Hello stack overflow folks.
The Context
General Context: I am working on project where the SBC (in my case, Raspberry Pi 4) has its pins protected from possible short-circuits due to the sloppy wiring; those pins are protected with microcontroller (in my case, it is an analog of Arduino Mega 1280 from DFRobot). The idea is that RPi tells microcontroller what sorts of actions on the I/O should be done, and in case of the short-circuit, microcontroller gets damaged instead of RPi, thus protecting RPi and its pins.
RPi and microcontroller communication Context: The communication is done through SPI. RPi and microcontroller are connected through CIPO, COPI, CS and SCLK (for old-fashion folks, the first three are MISO, MOSI and SS). Software wise on RPi I am using python with SpiDev and time libraries, and on microcontroller I am using Arduino IDE with SPI.h library. The communication utilises encoded byte signals, where first 5 bits determine the pin, 6th bit tells whether the pin send High or Low signal, 7th bit determines whether the pin is Input or Outputand 8th bit always stays 1 to insure that the command is taken into action.
How does the code work? The following code consists of list, array and two functions.
The list, that goes from pin 0 - 27, is there to tell the 5 bits used to find the pin used. tx_pin array is there to connect the function SendSignal with the earlier mentioned list (is this an extra step? possibly).
Function SendSignal just as the name suggests send the signal from RPi to microcontroller; the function demands to specify what pin (PIN) to use, to Input or Output it (IO), to keep High or Low (HL) and whether the to take the command into action (AI, earlier mention 8th bit; keep it as 1). Later the arguments are connected together into one byte as the tx_data variable. At the end the tx_data is sent as the signal through the rx_data = spi.xfer2(tx_data). Later on the function, the pin state is printed on the separate text document. Before all of the text document shenanigans, there rx_data awaits for the microcontroller to send back a specific byte signal (1 aka 0b00000001) in order to confirm that the two devices are still communicating with each other.
DebutTeste is the function that checks whether there is communication between two devices or not. It uses the SendSignal fucntion to repeatadly send signal until it receives an answer from the microcontroller.
How is it working so far? Fortunately, all of the code done is functioning. It has been tested beforehand.
The code for sending byte signal:
import spidev
import time
#Parametre de SPI
spi = spidev.SpiDev()
spi.open(0, 0)
spi.mode = 0b00
spi.bits_per_word = 8
spi.max_speed_hz = 1000000
#Etat de la communication
ComState = 0
AntiSpamComState = 0
#Liste des pins et bytes
pin0 = '00000'
pin1 = '00001'
pin2 = '00010'
pin3 = '00011'
pin4 = '00100'
pin5 = '00101'
pin6 = '00110'
pin7 = '00111'
pin8 = '01000'
pin9 = '01001'
pin10 = '01010'
pin11 = '01011'
pin12 = '01100'
pin13 = '01101'
pin14 = '01110'
pin15 = '01111'
pin16 = '10000'
pin17 = '10001'
pin18 = '10010'
pin19 = '10011'
pin20 = '10100'
pin21 = '10101'
pin22 = '10110'
pin23 = '10111'
pin24 = '11000'
pin25 = '11001'
pin26 = '11010'
pin27 = '11011'
#Pin array pour traduction
tx_pin = [pin0,pin1,pin2,pin3,pin4,pin5,pin6,pin7,pin8,pin9,pin10,pin11,pin12,pin13,pin14,pin15,pin16,pin17,pin18,pin19,pin20,pin21,pin22,pin23,pin24,pin25,pin26,pin27 ]
#Fonction signal
def SendSignal(PIN,IO,HL,AI):
#Envoyer et recevoir
tx_data = [int('0b' + str(AI) + str(IO) + str(HL) + str(tx_pin[PIN]),2)]
rx_data = spi.xfer2(tx_data)
print (rx_data)
global ComState
#Si ne marche pas
if rx_data != [1]:
#Etat de la communication
ComState = 0
print("COMMUNICATION ERROR! RETURN SIGNAL LOST OR CORRUPTED!")
#Si marche
else:
#Etat de la communication
#PreComState = 0
ComState = 1
print("Signal Stable")
#Traduction pour un message joli
if IO == 1:
TIO = 'Input'
if IO == 0:
TIO = 'Output'
if HL == 1:
THL = 'HIGH'
if HL == 0:
THL = 'LOW'
#Preparer message
new_line = f'PIN INFO: Pin = {PIN}, {TIO}, {THL}'
#Envoyer a doc
with open('/home/RPiUser/Documents/Prog/SPI/SPI_StatusDoc','r', encoding='utf-8') as file:
lines = file.readlines()
lines[PIN] = new_line + "\n"
with open('/home/RPiUser/Documents/Prog/SPI/SPI_StatusDoc', 'w',encoding='utf-8') as file:
file.writelines(lines)
def DebutTeste ():
global AntiSpamComState
#Envoyer et attendre pour recevoir signal quand pas de la communication
while ComState == 0:
time.sleep(0.5)
SendSignal(0,0,0,1)
#Preparer un messagae quand pas de la communication
OFFcommunication_line = 'Communication State OFF'
#Envoyer a doc quand pas de la communication
if AntiSpamComState == 0:
with open('/home/RPiUser/Documents/Prog/SPI/SPI_StatusDoc','r', encoding='utf-8') as file:
lines = file.readlines()
lines[28] = OFFcommunication_line + "\n"
with open('/home/RPiUser/Documents/Prog/SPI/SPI_StatusDoc', 'w',encoding='utf-8') as file:
file.writelines(lines)
AntiSpamComState = 1
#Preparer un messagae quand il y a de la communication
ONcommunication_line = 'Communication State ON'
#Envoyer a doc quand il y a de la communication
with open('/home/RPiUser/Documents/Prog/SPI/SPI_StatusDoc','r', encoding='utf-8') as file:
lines = file.readlines()
lines[28] = ONcommunication_line + "\n"
with open('/home/RPiUser/Documents/Prog/SPI/SPI_StatusDoc', 'w',encoding='utf-8') as file:
file.writelines(lines)
AntiSpamComState = 0
spi.close()
The Issue:
Creating and using a python module for sending byte signal I imported the first mentioned code to the new script and tried to use its SendSignal command; as the result, I receive Errno9 on the rx_data = spi.xfer2(tx_data) section.
In the new script I imported the first code - import FirstCode as FC and then used the SendSignal command as FC.SendSignal (0,1,0,1). It didn't work, I got the earlier mentioned issue.
After, I added the libraries that I used in the first code, so I imported spidev and time libraries. That brought no effect.
After, I added the variables, list, array and spi parameters (such as spi.open(0,0) before using the function, unfortunately - nothing.
In all cases, I get the exactly same error. I receive Errno9 on the rx_data = spi.xfer2(tx_data) section. **Reminder, the first code by itself works! **Please, help.