jerryk
Posts: 43
Joined: Wed Nov 02, 2016 3:26 pm

Read SPI data from unknown device

Sun May 02, 2021 6:50 pm

I have tapped into a device that selects and plays specific ring tones when individual motion detectors are triggered. The communication appears to be SPI between a ring tone IC chip and a microcontoller.

Attached is a couple of screen shots of the data from the microcontroller sent to the unknown ringtone IC which is potted to prevent its identification. Each ring tone request command is a numeric value in binary representation. So the two attached photos represent ring tone #1 and #19.
pin2_tune1.jpg
Tune # 1
pin2_tune1.jpg (80.17 KiB) Viewed 1151 times
pin2_tune19.jpg
Tune # 19
pin2_tune19.jpg (81.57 KiB) Viewed 1151 times
With the raspberry pi 3b and python code I want to retrieve the ring tone numbers and was hoping spidev would be the route to go. However the clock speed is 806Hz which falls below the minimum speed that the pi will interpret. Also confusing to me is that I am eavesdropping the communication between the master/slave of another device and do not want to interrupt that communication. I just am try to get the decimal representation of the ring tone that is being sent so I can do some further processing.

Can this be done with spidev? If not are there any other python based solutions I should pursue?

Thank for any help - Jerry

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

Re: Read SPI data from unknown device

Sun May 02, 2021 7:00 pm

Do you have access to the clock line?

http://abyz.me.uk/rpi/pigpio/examples.h ... SPI_mon_py

jerryk
Posts: 43
Joined: Wed Nov 02, 2016 3:26 pm

Re: Read SPI data from unknown device

Sun May 02, 2021 7:05 pm

Yes I do. The blue trace is the clock and the yellow trace is the data lines.

The link you sent seems the match the description of what I am try the do as in passively sniff the communication line.

Jerry

jerryk
Posts: 43
Joined: Wed Nov 02, 2016 3:26 pm

Re: Read SPI data from unknown device

Sun May 02, 2021 10:25 pm

Installed pigpio and have the SPI Monitor program running. It works great using the MCP3008 and a temperature sensor. But when I hook up the the motion sensor receiver it distorts the clock signal from the motion sensor receiver and I have no output from SPI_mon.py or the tune generator. Looking at the miso and clk lines on the oscilloscope it looks like it tries to pull the clock pulses low. The only wires I have hooked to the raspberry pi are miso, clk and ground.

Any ideas?

Jerry

SurferTim
Posts: 2054
Joined: Sat Sep 14, 2013 9:27 am
Location: Miramar Beach, Florida

Re: Read SPI data from unknown device

Sun May 02, 2021 10:46 pm

You probably need to connect the CS pins for both devices to pins on the RPi also. Only one device at a time should have the CS pin LOW, otherwise you will end up with a not-very-pretty bus contention and possible damage.
My advice applies to RaspiOS only. Please mention if you use another OS.

jerryk
Posts: 43
Joined: Wed Nov 02, 2016 3:26 pm

Re: Read SPI data from unknown device

Mon May 03, 2021 12:43 am

Here are 3 screen shots from the motion sensor base station. Keep in mind that I am trying to monitor or sniff the spi lines on this base station that is not connected or controlled by the raspberry pi.

There are four lines (1 clock and 3 data)that appear to have spi data between the microcontroller of the base station and the tune generator chip board on the base station.

Each photo shows a data line in yellow and the clock line above in blue.
clock_data_1.jpg
Clock and MISO
clock_data_1.jpg (78.13 KiB) Viewed 1046 times
clock_data_2.jpg
Clock and MOSI
clock_data_2.jpg (79.95 KiB) Viewed 1046 times
clock_data_3.jpg
Clock and CE0
clock_data_3.jpg (79.26 KiB) Viewed 1046 times
I have added comment lines below each picture as the what I think the function of each line is.

The first picture is definitely the data I am trying to capture. It's a binary 1 (in this photo) and this is tune 1 from the tune chip. There are 30 tunes on the chip (numbered 1-30) and this data line will vary accordingly with each tune selected.

The second two photographs are of the clock and my guess as to whether they are MOSI or CE0.

Looking at the clock line in blue I wonder if I should change the -m flag to 2? Also if the third picture is CE0, it's pulled high during the clock pulse so how should I handle that line when connecting this to the pi.

Wish I was a little bit more on top of the subject but appreciate the help.

Jerry

SurferTim
Posts: 2054
Joined: Sat Sep 14, 2013 9:27 am
Location: Miramar Beach, Florida

Re: Read SPI data from unknown device

Mon May 03, 2021 1:06 am

It appears the CEO enables the IC when HIGH rather than LOW. Compensate accordingly.
The data on the MOSI line is the instruction to a slave from the master.
The data on the MISO line is the return value to the master from the slave.

Edit: You may have the MOSI and MISO lines backwards. This device makes a sound depending on the value sent by the master, correct?
It appears the first image is the MOSI line sending a '1'.

If you plan on monitoring this, watch the CEO line. When it goes HIGH, then watch the clock for falling edge.
My advice applies to RaspiOS only. Please mention if you use another OS.

jerryk
Posts: 43
Joined: Wed Nov 02, 2016 3:26 pm

Re: Read SPI data from unknown device

Mon May 03, 2021 2:03 am

I did have that backwards between MOSI and MISO. The Micro of the base station sends a binary 1 to the tune chip and it plays tune number 1.

I was trying to use SPI_mon.py which was suggested in the first reply to accomplish the task. It sounds like you are suggesting using something like Rpi.GPIO add_event_detect for the tasK? Any time I have tried that to capture a binary representation it was not fast enough for the task. Maybe I was doing things wrong or there is a better approach to the problem.

I'm not sure what's meant by "compensate accordingly" in the first sentence. It makes sense but I'm not sure what to do with the CE0 line. I do not have any other spi devices on the pi that I'm using if that makes a difference. Another observation was the clock pulse seems active low instead of active high and that why I asked about changing the mode flag for SPI_mon.py to -m 2.

Sure appreciate the help.

Jerry

SurferTim
Posts: 2054
Joined: Sat Sep 14, 2013 9:27 am
Location: Miramar Beach, Florida

Re: Read SPI data from unknown device

Mon May 03, 2021 2:13 am

The scope output shows 2ms/div, which makes the signal about 9600 baud. That should be within the RPi's capability. I haven't tried it.

Edit: I don't think it is SPI. It appears it is bit-banging. The CEO line goes HIGH, then the clock goes LOW 8 times, then the CEO line goes LOW.
.
My advice applies to RaspiOS only. Please mention if you use another OS.

jerryk
Posts: 43
Joined: Wed Nov 02, 2016 3:26 pm

Re: Read SPI data from unknown device

Mon May 03, 2021 2:35 am

It is slow. The frequency I measured was around 806 Hz. I will try to count the high and low pulses and see if it yields consistent result.

Thanks - Jerry

SurferTim
Posts: 2054
Joined: Sat Sep 14, 2013 9:27 am
Location: Miramar Beach, Florida

Re: Read SPI data from unknown device

Mon May 03, 2021 2:39 am

I missed the frequency by a decimal point. Even slower.
I'd use the GPIO.add_event_detect function on the CEO and clock pins.
My advice applies to RaspiOS only. Please mention if you use another OS.

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

Re: Read SPI data from unknown device

Mon May 03, 2021 8:00 am

The script I linked is using callbacks.

Why not just use piscope?

http://abyz.me.uk/rpi/pigpio/piscope.html

It can capture the data and you can save it to a file.

If you want you can replay the captured data into another script to process it again.

http://abyz.me.uk/rpi/pigpio/examples.h ... layback_py

SurferTim
Posts: 2054
Joined: Sat Sep 14, 2013 9:27 am
Location: Miramar Beach, Florida

Re: Read SPI data from unknown device

Mon May 03, 2021 3:49 pm

I had to test it. This code works with the info you provided.
I programmed a STM32 Blue Pill to output data like your master.
Ensure you have GND connected to the other device.

Code: Select all

#!/usr/bin/env python3

import RPi.GPIO as GPIO
from time import sleep

CS = 16 # GPIO23
clkpin = 18 # GPIO24
datapin = 22 # GPIO25

thisbyte = 0
shiftbuffer = 0

# uses the board pin numbers, not the GPIO numbers
GPIO.setmode(GPIO.BOARD)

GPIO.setup(CS,GPIO.IN)
GPIO.setup(clkpin,GPIO.IN)
GPIO.setup(datapin,GPIO.IN)

def CS_callback(channel):
  global thisbyte,shiftbuffer

  thisbyte = shiftbuffer
  shiftbuffer = 0
  print("New byte ", thisbyte)

def clk_callback(channel):
  global datapin,shiftbuffer

  shiftbuffer = shiftbuffer << 1
  if GPIO.input(datapin):
    shiftbuffer = shiftbuffer | 1

GPIO.add_event_detect(CS,GPIO.FALLING,callback=CS_callback)
GPIO.add_event_detect(clkpin,GPIO.FALLING,callback=clk_callback)

try:
    while True:
        sleep(0.1)
except KeyboardInterrupt:
    pass
finally:
    GPIO.cleanup()
My advice applies to RaspiOS only. Please mention if you use another OS.

jerryk
Posts: 43
Joined: Wed Nov 02, 2016 3:26 pm

Re: Read SPI data from unknown device

Mon May 03, 2021 8:15 pm

SurferTim wrote:
Mon May 03, 2021 3:49 pm
I had to test it. This code works with the info you provided.
I programmed a STM32 Blue Pill to output data like your master.
Ensure you have GND connected to the other device.
That's perfect!! I attached the output of testing sensors pair to tunes 1 and 19 (4 times each). Then I scroll through the selectable tunes starting at tune 8.
output_sensor_test.jpg
output_sensor_test.jpg (94.18 KiB) Viewed 883 times
Notice the extra if statement I added to prevent some repetitive outputs of New byte 0 after the triggering of each sensor. That is a patch for now as I'm trying to see what's causing the false triggering in the callback function.

Otherwise it's seeming to work fantastic.

Many thanks - Jerry

jerryk
Posts: 43
Joined: Wed Nov 02, 2016 3:26 pm

Re: Read SPI data from unknown device

Mon May 03, 2021 9:17 pm

joan wrote:
Mon May 03, 2021 8:00 am
The script I linked is using callbacks.

Why not just use piscope?

http://abyz.me.uk/rpi/pigpio/piscope.html

It can capture the data and you can save it to a file.

If you want you can replay the captured data into another script to process it again.

http://abyz.me.uk/rpi/pigpio/examples.h ... layback_py
Thanks for your input. I did look through the code in the linked script and was trying to see why I cannot just use any other pin set as an input. I think the problem of distorting the clock pulse has to to with the clock pin set to alt0 but that is a guess on my part.

Also I have installed piscope as I am very interested in it but am hung on "(piscope:13518): Gtk-WARNING **: cannot open display: 192.168.1.105:0.0". I'm using ssh -Y (mypy login) form my imac to the pi.

Appreciate the help - Jerry

jerryk
Posts: 43
Joined: Wed Nov 02, 2016 3:26 pm

Re: Read SPI data from unknown device

Sat May 08, 2021 10:43 pm

The help above solved all problems with reading the Guardline sensor data.

I am trying to add one other motion detection system (Optex) to this project but it communicates at 8 kHz rather than the 800 Hz of the Guardline.

I appears that Rpi.GPIO is too slow for 8 kHz. Another issue is there is no chip select pin from the Optex micro controller. I have attached a photo of the piscope output that I want to read.
picope_reading.jpg
picope_reading.jpg (96.46 KiB) Viewed 802 times
Here is a shot of the output that matches the pulse in the above photo.
jupyter_output.jpg
jupyter_output.jpg (99.92 KiB) Viewed 802 times
And the code I'm using vi pigpio library as an initial test each value of the six clock pulses (pin 27) against the data pulse values (pin 13).

Code: Select all

#!/usr/bin/python

import pigpio, time

def callback(g, l, t):
    print(str(g) + " " + str(l) + " " + str(t))
    print("Level of datapin:", pi.read(datapin))

pi = pigpio.pi()
if not pi.connected:
    exit()

pin = 27
datapin = 13

pi.set_mode(pin, pigpio.INPUT)
pi.set_pull_up_down(pin, pigpio.PUD_DOWN)
pi.set_mode(datapin, pigpio.INPUT)
pi.set_pull_up_down(datapin, pigpio.PUD_DOWN)

cb1 = pi.callback(pin, pigpio.RISING_EDGE, callback)

while True:
  #print("Direct " + str(pi.read(pin)) + " " + str(pi.get_current_tick()))
  time.sleep(1)
The printed datapin value levels should be 000110. Instead I get 111111.

The pigpio library is reading the clock pulse fine but I cannot understand my error in reading the datapin level.

Jerry

SurferTim
Posts: 2054
Joined: Sat Sep 14, 2013 9:27 am
Location: Miramar Beach, Florida

Re: Read SPI data from unknown device

Sun May 09, 2021 11:16 am

My advice applies to RaspiOS only. Please mention if you use another OS.

jerryk
Posts: 43
Joined: Wed Nov 02, 2016 3:26 pm

Re: Read SPI data from unknown device

Sun May 09, 2021 4:44 pm

SurferTim wrote:
Sun May 09, 2021 11:16 am
That looks more like I2C than SPI.
https://www.engineersgarage.com/microco ... -protocol/
https://pypi.org/project/smbus2/
I looked at the info on pi-i2c and it talks about i2c standard speeds 100 kHz and above. The pulse I'm currently working with is 8 kHz. The device is just like the Guardline in general terms. It has a receiver , microcontroller, and a tone generating chip that is again "potted" so I have no data on this device. I wouldn't have any idea of how the reference the device address using smbus2.

So far what I'm seeing is:

RPi.GPIO library cannot handle an 8 kHz signal. It only counts two of the six clock pulses when a motion event is triggered.

pigpio library can handle the 8 kHz signal and counts all six clock pulses just fine. But for some odd reason pi.read("some other pin") does not function correctly in the call back function. Either I'm doing something wrong or reading an 8 kHz signal is beyond the capability of either library.

The solution you helped me with at the beginning of this thread works perfect and all the sensors (8 of them) now report back with voice alerts rather than the annoying ring tones available. But that was a much slower signal at 800 Hz. I'll keep researching and looking for ideas.

Thanks - Jerry

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

Re: Read SPI data from unknown device

Sun May 09, 2021 5:05 pm

The documentation says not to use read in a callback. It even gives the reason.

http://abyz.me.uk/rpi/pigpio/python.html#callback

ghp
Posts: 1969
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Read SPI data from unknown device

Sun May 09, 2021 5:36 pm

If you use pigpiod with fast signals, then you should use callbacks for all related GPIO.
When using callbacks for clock only, then the callback will be triggered in the python code when data line has changed state already.
When using callback for clock and data, then the callback calls are arriving in correct sequence.

Code: Select all

class DecodeUnknownSource:
    def __init__(self, PIN_SCK = 21, PIN_DATA = 20 ):
        pi.set_mode( PIN_SCK, pigpio.INPUT )
        pi.set_mode( PIN_DATA, pigpio.INPUT)
        self.data = pi.read( PIN_DATA)
        self.clk = pi.read( PIN_SCK)
        cb1 = pi.callback(PIN_SCK, pigpio.EITHER_EDGE,  self.cbf_clk)
        cb2 = pi.callback(PIN_DATA, pigpio.EITHER_EDGE , self.cbf_data)
        
    def cbf_clk(self, gpio, level, tick):
        self.clk = level
        # process data
        
    def cbf_data(self, gpio, level, tick):
        self.data = level
        # process data


jerryk
Posts: 43
Joined: Wed Nov 02, 2016 3:26 pm

Re: Read SPI data from unknown device

Sun May 09, 2021 7:22 pm

joan wrote:
Sun May 09, 2021 5:05 pm
The documentation says not to use read in a callback. It even gives the reason.

http://abyz.me.uk/rpi/pigpio/python.html#callback
Yes it does say that very clearly!! Sorry I missed it. Thanks to the post above I think things on this project are going into the solved bin.

Thanks - Jerry

jerryk
Posts: 43
Joined: Wed Nov 02, 2016 3:26 pm

Re: Read SPI data from unknown device

Sun May 09, 2021 7:33 pm

ghp wrote:
Sun May 09, 2021 5:36 pm
If you use pigpiod with fast signals, then you should use callbacks for all related GPIO.
When using callbacks for clock only, then the callback will be triggered in the python code when data line has changed state already.
When using callback for clock and data, then the callback calls are arriving in correct sequence.
That solved the fast signal problem. Sure appreciate the help from you and the other kind folks that helped me along.

End result is I have motion a detector system that has 14 sensors (two different manufacturers) spread over twenty acres of property that used to report back with annoying ring tones. I had to try to remember which tone went to which sensor. Now output signals go through the pi 3b and each sensor talks in a nice female voice and reports back it's location with a precise timestamp attached to the event.

Thanks - Jerry

Return to “Python”