joan2937 / pigpio

pigpio is a C library for the Raspberry which allows control of the General Purpose Input Outputs (GPIO).
The Unlicense
1.43k stars 403 forks source link

Understanding pigpiod command implementation #599

Closed davthomaspilot closed 3 months ago

davthomaspilot commented 5 months ago

I'm sick of the issues associated with running with sudo. You'd be amazed how much time I waste trying to work around limitations in my development environment when working with an application that must run under sudo. (:rant off)

Currently I use a hacked version of the pigpio C/IF library. I need the timestamps that are already available in the gpioSerialRead function

I just added "monkey see, monkey do" versions of gpioSerialReadOpen and gpioSerialRead functions. The modified open adds a line to create a buffer for the timestamps:

wfRx[gpio].ts.tickBuf = malloc(SRX_BUF_SIZE * sizeof(uint32_t));

And the modified read function adds a fragment to copy the timestamps to the an additional parameter that specifies where the callers buffer for that data sits:

      if (startTicksBuf) memcpy(startTicksBuf, w->ts.tickBuf+w->ts.readPos,bytes*sizeof(uint32_t));   
      w->ts.readPos += bytes;

I callled the modified functions gpioSerialReadTs and gpioSerialOpenTs.

I think I could have just added an optional parameter to the existing functions, but I felt it safest to leave them exactly as is.

You might be surprised how useful this has been! We can do things on an RPI that normally not be possible without using an RTOS.

Anyway, now I want to get the same functionality using by using the pipe interface. Before I go any farther, any chance of getting this in the "real" pigpio? Or, a sandbox version?

Assuming no, off I go... I might be getting over my head...

I figure I need to add an element in the cmdInfo array that's defined in command.c. I think the retv column is how many variables are returned and the script column indicates whether the command can be used in a script. But, what is vfyt?

Thanks for any help I can get!

davthomaspilot commented 5 months ago

Found the cmdParse and figured out how the vt member of the cmdInfo structure is used. Continuing...

davthomaspilot commented 5 months ago

Working my way through the code.

I think using my version of gpioSerialRead over the pipe/socket interface might tear up the code on the daemon side too much. There's a function myDoCommand that is called by the daemon to do all the the commands like the serialRead andserialReadOpen.

myDoCommand only has parameters for one buffer. The function I need requires two buffers, one for the characters received and another for the timestamp associated with each character.

It might make more sense to have a separate function that returns only the timestamps, but I need to figure out how to make sure a call to get the timestamps is synched with data read from serialRead. Will that be a nightmare?

It would be really nice not to have to hack anything. I'm going to start a new issue about a different way of going about.

guymcswain commented 5 months ago

What I have done in the past with success is to decode the raw signal edges using the callback level, tick tuples. You can do all this remotely leaving your rpi zero-w running just the pigpio daemon. I would set a glitch filter on pigpio to remove noise above the expected bit rate. In the bit-bang decode, done remotely, you can detect the preamble of your rf signal - which appears as a long break frame to the serial decoder. From there you have a timestamp for the serial data which follows.

You can start by converting pigpio's internal bit-bang decode logic to your needs. There may be python script/examples floating around or I can give you some code I used written in NodeJs. sigrok, I believe, have decoders that do similar and much more.

The clear advantage with this approach is you don't need to hack the library. A potential downside is the additional network traffic to handle the raw level,tick stream. As I recall, doing this for 9600 baud serial data did not present any significant demand on network bandwidth.

davthomaspilot commented 5 months ago

Guy, that might be the way to go.

Our bit rate is 20833, and the examples I've found for doing bb serial read are well below that.

"Remotely" will just be another process on the same rpi, so that should mitigate issues. I think communication over a local pipe shouldn't be an issue

I have it working with the pigpiod library hacks, but I think it's worth the time to have my own code to to the decoding so no hacks are needed.

I did a C++ wrapper class that uses pigpiod functions when not running under sudo, otherwise the pigpio version. Got all that working only to be reminded another library I use (ws2811) also needs to run as root. But, until Bookworm, I could change permissions on /dev/mem (or maybe it was /dev/gpio--something worked), but I can't find a way to make that work.

So, a separate process that uses the ws2811 library and does the serial decode on the raw time stamps seems the cleanest.

I may ask for some examples, but I have to put this on the back burner for a few days to get some other stuff working.

Thanks!

guymcswain commented 5 months ago

With a bit rate of ~21K I recommend you set pigpio's sample rate to 1usec. At that (highest) sample rate you can achieve 38.4K baud without significant error rates. For bit rates above 19.2K, some sort of error detection is highly recommended.

davthomaspilot commented 5 months ago

Will do. Thanks!

davthomaspilot commented 4 months ago

There may be python script/examples floating around or I can give you some code I used written in NodeJs. sigrok, I believe, have decoders that do similar and much more.

Ok, I'm back on this. Code examples would be great!

I could also reject spurious detection of the 22 bit time mark by looking at the data that follows. There are only a few characters that are valid as the first character after the 22 bit period. So, I figured I'd add an interface that defines those expected "first character after 22 bit preamble" characters.

guymcswain commented 4 months ago

sigrok-uart

davthomaspilot commented 4 months ago

Thank you!