User avatar
joan
Posts: 14372
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: New pigpio Python module

Fri Mar 16, 2018 12:05 am

@Massi

Just an update.

I may have found the problem.

I use a lock to protect the pigpio command calls (each call needs to be atomic: send request then get reply). For some unfathomable reason a lock acquire is failing. I do not know why. All the code uses a try block to safely acquire/release the lock.

I have tried many fixes and thought I had one. Unfortunately the fix appears to work fine in Python2 but breaks some commands in Python3.

I'll keep trying.

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: New pigpio Python module

Fri Mar 16, 2018 1:48 pm

if you need any testing, i'm here :)

User avatar
joan
Posts: 14372
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: New pigpio Python module

Fri Mar 16, 2018 2:10 pm

Massi wrote:
Fri Mar 16, 2018 1:48 pm
if you need any testing, i'm here :)
I'll bear that in mind, but I am not ready yet.

If you want to play the current best try is at http://abyz.me.uk/pigpio.py (I'll probably delete this file in a few days).

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: New pigpio Python module

Fri Mar 16, 2018 2:24 pm

so is the problem strictly related to the python module?
i'll give it a look in the weekend :)

Mohmir
Posts: 1
Joined: Wed May 02, 2018 12:33 pm

Re: New pigpio Python module

Wed May 02, 2018 1:23 pm

joan wrote:
Thu Feb 18, 2016 11:27 pm
Here is the code altered for V46.

Code: Select all

#!/usr/bin/env python

# PPM.py
# 2016-02-18
# Public Domain

import time
import pigpio

class X:

   GAP=100
   WAVES=3

   def __init__(self, pi, gpio, channels=8, frame_ms=27):
      self.pi = pi
      self.gpio = gpio

      if frame_ms < 5:
         frame_ms = 5
         channels = 2
      elif frame_ms > 100:
         frame_ms = 100

      self.frame_ms = frame_ms

      self._frame_us = int(frame_ms * 1000)
      self._frame_secs = frame_ms / 1000.0

      if channels < 1:
         channels = 1
      elif channels > (frame_ms // 2):
         channels = int(frame_ms // 2)

      self.channels = channels

      self._widths = [1000] * channels # set each channel to minimum pulse width

      self._wid = [None]*self.WAVES
      self._next_wid = 0

      pi.write(gpio, pigpio.LOW)

      self._update_time = time.time()

   def _update(self):
      wf =[]
      micros = 0
      for i in self._widths:
         wf.append(pigpio.pulse(0, 1<<self.gpio, self.GAP))
         wf.append(pigpio.pulse(1<<self.gpio, 0, i))
         micros += (i+self.GAP)
      # off for the remaining frame period
      wf.append(pigpio.pulse(0, 1<<self.gpio, self._frame_us-micros))

      self.pi.wave_add_generic(wf)
      wid = self.pi.wave_create()
      self.pi.wave_send_using_mode(wid, pigpio.WAVE_MODE_REPEAT_SYNC)
      self._wid[self._next_wid] = wid

      self._next_wid += 1
      if self._next_wid >= self.WAVES:
         self._next_wid = 0

      
      remaining = self._update_time + self._frame_secs - time.time()
      if remaining > 0:
         time.sleep(remaining)
      self._update_time = time.time()

      wid = self._wid[self._next_wid]
      if wid is not None:
         self.pi.wave_delete(wid)
         self._wid[self._next_wid] = None

   def update_channel(self, channel, width):
      self._widths[channel] = width
      self._update()

   def update_channels(self, widths):
      self._widths[0:len(widths)] = widths[0:self.channels]
      self._update()

   def cancel(self):
      self.pi.wave_tx_stop()
      for i in self._wid:
         if i is not None:
            self.pi.wave_delete(i)

if __name__ == "__main__":

   import time
   import PPM
   import pigpio

   pi = pigpio.pi()

   if not pi.connected:
      exit(0)

   pi.wave_tx_stop() # Start with a clean slate.

   ppm = PPM.X(pi, 6, frame_ms=20)

   updates = 0
   start = time.time()
   for chan in range(8):
      for pw in range(1000, 2000, 5):
         ppm.update_channel(chan, pw)
         updates += 1
   end = time.time()
   secs = end - start
   print("{} updates in {:.1f} seconds ({}/s)".format(updates, secs, int(updates/secs)))

   ppm.update_channels([1000, 2000, 1000, 2000, 1000, 2000, 1000, 2000])

   time.sleep(2)

   ppm.cancel()

   pi.stop()
There is one new function - wave_send_using_mode.

I have moved the update delay into the class and based it on the frame time. This means you can't update more often than the frame time (pointless) or delete a waveform before it has been used (bad).
Hello Joan!
I'm trying to controll a Quad with my computer. my raspberrypi 3b is connected to pixhawk 2.1, and i need to make ppm signals inside rpi.
i tried this code, but i get an error about the line " import PPM''. where do i get this file/library?
i will send values from my computer to the raspberry with wifi, and then wire the rapsberry to the pixhawk. And im trying to stay away from mission planner. Any input you have will be greatly appreciated.

Return to “Python”