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 > Simulavr-devel@nongnu.org > https://lists.nongnu.org/mailman/listinfo/simulavr-devel > _______________________________________________ Simulavr-devel mailing list Simulavr-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/simulavr-devel