simulavr-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Simulavr-devel] How to capture PWM output?


From: Jeff Lane
Subject: [Simulavr-devel] How to capture PWM output?
Date: Fri, 16 Sep 2016 15:12:10 +0200

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)) 

 

 

 

 

 

 

 

 

 

 

 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]