[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Simulavr-devel] How to capture PWM output?
From: |
Stan Behrens |
Subject: |
Re: [Simulavr-devel] How to capture PWM output? |
Date: |
Sat, 17 Sep 2016 11:09:25 +0200 |
User-agent: |
Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 |
Hey Jeff,
I wrote a Soft-PWM for up to 8 outputs (one full pin register) that's
using a single Timer-Interrupt to run asynchroniously.
To test my code under hard realtime conditions, I generated some random
PWM-values and recorded the PIN-changes with simulavr's option '-c
vcd:ti:to'.
That option generated a file named 'to' which had timestamp + value of
the pins. Therefor I could calculate all outputted PWM-values with the
PWM-values I wanted, which gave me a full simulated closed loop test setup.
I hope I could help.
Bye, Stan.
On 16/09/2016 15:12, Jeff Lane wrote:
> Hello All,
>
>
>
> Thank you all for your long and continuing work with simulavr! I am
> successfully using this very useful tool, in both Linux (Debian) and
> Windows(MinGW) environments, and using Python and PyQt for test and GUI
> construction. Setting up Pins and Nets for Digital, Analog, and Serial
> "Pins" are all OK.
>
>
>
> I've been less successful with PWM output, and am currently using a
> workaround where I am simply setting volatile variables and reading them in
> the Pin::SetInState method. Of course this is missing pretty much the entire
> PWM code and simulation. Below an example of the Evil that I have done. If
> possible, any help on how to actually use the PWM feature in a normal
> Net/Pin setup would be most welcome.
>
>
>
> P.S: Not related, and I know the TWI interface is not implemented yet, but I
> do watch this kind of thing go by many thousands(?) of times a day! :) :
>
> "WARNING: file rwmem.cpp: line 243: TWI register TWCR not simulated (write
> 0x80 to register)"
>
> "WARNING: file rwmem.cpp: line 243: TWI register TWDR not simulated (write
> 0xff to register)"
>
>
>
> Thank You,
>
> Jeff
>
>
>
> /********** current ugly workaround **********/
>
> /********** something like this in the source **********/
>
>
>
> #ifdef SIMULAVR
>
> volatile int OCR1A_value;
>
> volatile int OCR1B_value;
>
> volatile int PWM_top_value;
>
> #endif
>
>
>
> Etc.
>
>
>
> /********** something like this in device MCU **********/
>
> # Gas PropValve Control (PWM)
>
> ## Pin to receive digital data from pin PD5
>
> self.pinGasControlValve = OutputPinPWM("pinGasControlValve", self.dev,
> "OCR1B_value", 'PWM_top_value')
>
> ## MCU Pin PD5
>
> self.pinD5 = self.dev.GetPin("D5")
>
> ## Net for MCU Pin PD5
>
> self.netPD5 = pysimulavr.Net()
>
> self.netPD5.Add(self.pinD5)
>
> self.netPD5.Add(self.pinGasControlValve)
>
>
>
>
>
>
>
> /********** something like this in Pin **********/
>
> ## Class to represent a PWM output (from MCU) Pin.
>
> #
>
> #
>
> class OutputPinPWM(pysimulavr.Pin):
>
>
>
> ## OutputPinPWM constructor #
>
> def __init__(self, pin_name, parent_device, pwm_value_varname,
> pwm_range_varname):
>
> pysimulavr.Pin.__init__(self)
>
> ## string name of Pin
>
> self.myname = pin_name
>
>
>
> ## reference to parent MCU
>
> self.parent_device = parent_device
>
>
>
> ## reference to pwm_value_varname from MCU source code
>
> self.pwm_value_varname = pwm_value_varname
>
>
>
> ## current PWM range value (for % calculation)
>
> self.pwm_range_varname = pwm_range_varname
>
>
>
> ## calculated PWM value (for application)
>
> self.calculated_pwm_value = 0
>
>
>
> ## current PWM value (for comparison)
>
> self.current_pwm_value = 0
>
>
>
> ## previous PWM value (for comparison)
>
> self.old_pwm_value = 0
>
>
>
> ## return name of the Pin
>
> #
>
> def __str__(self):
>
> return self.myname
>
>
>
> ## return current PWM value
>
> #
>
> def getCurrentPvmValue(self):
>
> return self.calculated_pwm_value
>
>
>
> ## Update pin value
>
> #
>
> def SetInState(self, pin):
>
> pysimulavr.Pin.SetInState(self, pin)
>
> try:
>
> # following code reference from simulavr python examples (
> simulavr/examples/python/ex_utils.py )
>
> # read current PWM variable direct from MCU :(
>
> addr =
> self.parent_device.data.GetAddressAtSymbol(self.pwm_value_varname)
>
> self.current_pwm_value = self.parent_device.getRWMem(addr)
>
> addr += 1
>
> self.current_pwm_value = (self.parent_device.getRWMem(addr) <<
> 8) + self.current_pwm_value
>
>
>
> # read current PWM range variable direct from MCU :(
>
> addr =
> self.parent_device.data.GetAddressAtSymbol(self.pwm_range_varname)
>
> pwm_max_value = self.parent_device.getRWMem(addr)
>
> addr += 1
>
> pwm_max_value = (self.parent_device.getRWMem(addr) << 8) +
> pwm_max_value
>
>
>
> if self.current_pwm_value != self.old_pwm_value:
>
>
>
> self.old_pwm_value = self.current_pwm_value
>
>
>
> # calculate pwm percentage
>
> if (pwm_max_value != 0):
>
> self.calculated_pwm_value =
> (float(self.current_pwm_value) / pwm_max_value ) * 100
>
> else:
>
> self.calculated_pwm_value = 0
>
>
>
> print ("OutputPinPWM SetInState : calculated_pwm_value = " +
> str(self.calculated_pwm_value))
>
>
>
> # send blinker signal with updated PWM value
>
> pin_message = signal(self.pwm_value_varname)
>
> pin_message.send(self, message=self.calculated_pwm_value,
> signal_name=self.myname)
>
> print "pin_message.send (" + self.myname + " : " +
> self.pwm_value_varname + "): " + str(self.calculated_pwm_value)
>
>
>
>
>
> except Exception as err:
>
> print ("OutputPinPWM Error:SetInState : " + str(err))
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> _______________________________________________
> Simulavr-devel mailing list
> address@hidden
> https://lists.nongnu.org/mailman/listinfo/simulavr-devel
>