Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    TimerWipy

    Scheduled Pinned Locked Moved WiPy 2&3
    wipy 2timer interruptimerirq
    17 Posts 2 Posters 2.2k Views 2 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • V Offline
      VFlorio94 @robert-hh
      last edited by

      @robert-hh Hello. I have to ask you a new thing correlate with this code that you wrote previously.
      I want to implement the code with another part in which I desire to activate PWM depending on the data sample and wrote by IMU. So, the question is:
      Is it correct if I introduced a control on the data that I wrote and the command to activate PWM in the fuction 'sample and write'?
      And have I also to complete class acquire like this?

      self.pwm = PWM(0.02, frequency=500 ) #This sets up the timer to 
              #oscillate at the specified frequency. timer is an integer from 0 to 3. 
              # frequency is an integer from 1 Hz to 78 KHz 
      

      I know that I have also to set PWM channel where I put set-up Hardware parameters.
      I'll be newly grateful if you can help me.

      robert-hhR 1 Reply Last reply Reply Quote 0
      • robert-hhR Offline
        robert-hh @VFlorio94
        last edited by

        @vflorio94 said in TimerWipy:

        self.pwm = PWM(0.02, frequency=500 )

        The first argument of the class instantiation is a timer ID, not a time or the like. The value range is 0 - 3. See: https://docs.pycom.io/firmwareapi/pycom/machine/pwm
        So it should be:
        self.pwm = PWM(0, frequency=500 )

        V 1 Reply Last reply Reply Quote 0
        • V Offline
          VFlorio94 @robert-hh
          last edited by

          @robert-hh yes, I checked and you are right. And about command to activate pwm responding to data acquire by sensor?

          robert-hhR 1 Reply Last reply Reply Quote 0
          • robert-hhR Offline
            robert-hh @VFlorio94
            last edited by

            @vflorio94 ???

            V 1 Reply Last reply Reply Quote 0
            • V Offline
              VFlorio94 @robert-hh
              last edited by

              @robert-hh sorry, I describe the problem in a bad way. I have another question.
              I have a data that I want to use inside the function 'sample_and_write', but I have some difficulties to pass it from main to the class '''Acquire''' and in the end to the function. Is it possible ? can you help me?

              robert-hhR 1 Reply Last reply Reply Quote 0
              • robert-hhR Offline
                robert-hh @VFlorio94
                last edited by

                @vflorio94 That's a question of scope and visibility in Python.
                So most simple but unelegant method is to have that data global. So it is created outside every function. Then at any part of your code you can declare is a global to access it. Example:

                # at the top level of your code:
                data_buffer = bytearray(100)
                data_ptr_in = 0
                data_ptr_out = 0
                
                #
                # 
                class MyClass:
                    def my_func(self):
                        # declare symbols as global
                        global data_buffer, data_ptr_in, data_ptr_out
                        data_buffer[data_ptr_in] = some_data
                        data_ptr_in = (data_ptr_in + 1) % len(data:buffer)
                

                You can also define functions (or better to say methods) to pass along data, and you can use property and setter and getter methods of classes, ...

                V 1 Reply Last reply Reply Quote 0
                • V Offline
                  VFlorio94 @robert-hh
                  last edited by

                  @robert-hh Thank you, I solved this problem. I put data as metod.
                  Now I have a new problem because I want to read data from sensor and after a comparisono with reference data I want to activate pwm. I did it in this way.
                  But the problem is that the period change a lot, sample time decrease to 0.04.
                  Is there another way to modify this code for activate pwm that can be better??
                  I need if it is possible that period remain more possible like 0.02.

                  thank you

                  import machine 
                  import pycom
                  from machine import Timer
                  from machine import idle
                  import time
                  import lib_imu
                  import lib_imu2
                  from machine import I2C
                  from math import sqrt
                  from math import fabs
                  from machine import PWM
                  from machine import SD
                  import gc
                  import os
                  sd = SD()
                  os.chdir('/sd')
                  from machine import idle
                  
                  #
                  # add the other imports here that you need
                  # fileIMU1 = open('/sd/dati_IMU1.txt', 'w')
                  #
                  # acquire  values. The paramters of the constructor are:
                  #
                  class Acquire:
                      def __init__(self, filename_imu1, data, period=0.02, runtime = 60):
                          self.fileIMU1 = open(filename_imu1, "w")
                          self.temp = Timer.Chrono()
                          self.busy = True
                          self.data = data
                          self.runtime = runtime
                          self.temp.start()
                          self.alarm = Timer.Alarm(self.sample_and_write, period , periodic=True)
                          # and add all other init tasks you need
                  
                      def stop(self):
                          self.alarm.cancel()
                          pwm_c2.duty_cycle(0)
                          pwm_c5.duty_cycle(0)
                          self.fileIMU1.close()
                          #self.fileIMU2.close()
                  
                      def sample_and_write(self, alarm):
                          passed = self.temp.read()
                          # check, if done, if the time for sampling is expired, then stop
                          if passed >= self.runtime:
                              self.stop()
                              self.busy = False
                              print('end')
                          else:
                              # get data and write
                              #print(passed, fabs(lib_imu2.get_euler()[2]))
                              self.fileIMU1.write(repr(passed) + repr(lib_imu2.get_euler()) + "\n")
                               # avanti
                              if fabs(lib_imu2.get_euler()[2]) > ( fabs(dati_rif[2]) + 0.2):
                                  if fabs(lib_imu2.get_euler()[2]) < (fabs(dati_rif[2]) + 0.4):
                                      pwm2 = PWM(0, frequency=1000 )
                                      pwm_c2.duty_cycle(0.5)
                                      pwm_c5.duty_cycle(0) 
                                  elif fabs(lib_imu2.get_euler()[2]) >= (fabs(dati_rif[2]) + 2): 
                                      pwm2 = PWM(0, frequency=2000 )
                                      pwm_c2.duty_cycle(0.6)
                                      pwm_c5.duty_cycle(0) 
                              # indietro  
                              elif fabs(lib_imu2.get_euler()[2]) <  fabs(dati_rif[2]) + 0.2:
                                  if fabs(lib_imu2.get_euler()[2]) > (fabs(dati_rif[2]) + 0.4):
                                      pwm5 = PWM(0, frequency=1000 )
                                      pwm_c2.duty_cycle(0)
                                      pwm_c5.duty_cycle(0.5) 
                                  elif fabs(lib_imu2.get_euler()[2])< (fabs(dati_rif[2]) + 2): 
                                      pwm5 = PWM(0, frequency=2000 )
                                      pwm_c2.duty_cycle(0)
                                      pwm_c5.duty_cycle(0.5)
                              # and what else you have to do.
                  
                  #
                  # now here the skeleton main_
                  #
                  sd = SD()
                  os.chdir('/sd')
                  
                  # set up the hardware
                  ''' SET UP IMU 0X29 '''
                  # Scala Berg: imu L5 - lib_imu - acc
                  lib_imu.set_acc()
                  time.sleep(0.01)
                  lib_imu.set_configmode()
                  time.sleep(0.01) 
                  lib_imu.set_units()
                  time.sleep(0.01)
                  lib_imu.set_mode('ndof')
                  time.sleep(0.01)
                  ''' SET UP IMU 0X28 '''
                  # imu t1 - lib_imu2 - eul
                  lib_imu2.set_configmode() 
                  time.sleep(0.01)
                  lib_imu2.set_units()
                  time.sleep(0.01)
                  lib_imu2.set_mode('ndof')
                  time.sleep(0.01)
                  ''' PWM '''
                  pwm2 = PWM(0, frequency=500 )
                  pwm5 = PWM(0, frequency=500 )
                  #This sets up the timer to 
                  #oscillate at the specified frequency. timer is an integer from 0 to 3. 
                  # frequency is an integer from 1 Hz to 78 KHz 
                  pwm_c5 = pwm2.channel(5, pin='P12') #dietro
                  pwm_c2 = pwm5.channel(2, pin='P5')   # avanti
                  pwm_c5.duty_cycle(0)
                  time.sleep(0.01)
                  pwm_c2.duty_cycle(0)
                  time.sleep(0.01)
                  
                  ''' START''' 
                  with open("/sd/Rif.txt", "r") as f:
                      line = f.read()
                      # now you have a list of one string per line
                      dati_rif = [float(el) for el in line.strip("()\n ").split(",")]  # reference data
                  print('start')
                  acquire = Acquire('Acquisition_Vibration.txt', dati_rif[2], 0.02, 30)
                  
                  #
                  # now get the data, until it's done
                  #
                  while acquire.busy:
                      idle()
                  #
                  # whatever you have to do for cleanup, do it here
                  #```
                  robert-hhR 1 Reply Last reply Reply Quote 0
                  • robert-hhR Offline
                    robert-hh @VFlorio94
                    last edited by

                    @vflorio94 For a consistent operation at a period of 0.02 or 50 ms it is required that the handler takes not longer than that, and that is executes the OWM changes at almost the same time within the handler. Looking at your code, I see at least two things that could affect timing:
                    a) You write to a file. File i/O is buffered. As long as the data is written into the buffer, it's fast. When the buffer will be written, it can be slow.
                    b) You call lib_imu2.get_euler() several times in the timer handler. I do not know the complexity of that call, but if it includes access to external hardware, then it may take some time. Better call it once, store the result and use that in consecutive statements.

                    V 2 Replies Last reply Reply Quote 0
                    • V Offline
                      VFlorio94 @robert-hh
                      last edited by

                      @robert-hh I solved the problem creating a new function to compare data acquire by sensor with reference data and then it power on pwm. And in this way the period remain 50 ms.
                      thank you

                      1 Reply Last reply Reply Quote 0
                      • V Offline
                        VFlorio94 @robert-hh
                        last edited by

                        @robert-hh Hi, sorry for my insistence on this topic.
                        I 'm not able to use thread but I read about it and I think that it's better for my code if I use them . So do you know if is it possibile to use thread to read from two I2C through the code that I posted before?
                        thank you.

                        1 Reply Last reply Reply Quote 0

                        Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                        Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                        With your input, this post could be even better 💗

                        Register Login
                        • 1 / 1
                        • First post
                          Last post

                        Pycom on Twitter

                        Pycom