我的网络由多个连接到Max485的Arduino组成。这些Arduino可以完美地交谈
我目前正在尝试将一个树莓Pi连接到网络中。我一直在关注this tutorial
我已经启用了UART引脚,并禁用了通过串行传输的shell
对于测试,我有wiredTX(GPIO 14/引脚8)到MAX485上的DI,RX(GPIO 15/引脚10)到RO,GPIO 4(引脚7)到DE&;重新。它还为两个MAX485芯片供电,两个芯片都接地。 在arduino方面,我目前正在使用Mega。它有TX3到DI,RX3到RO,引脚2到DE/RE。这两个设备是此网络上唯一的设备
Raspi Python:
import time
import serial
import RPi.GPIO as GPIO
from time import sleep
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
#sets pin 7 on the GPIO as DE/RE
GPIO.setup(7, GPIO.OUT, initial=GPIO.LOW)
rs = serial.Serial(port='/dev/serial0', timeout=5, baudrate=9600)
data = bytearray()
msgIn = bytearray()
addr = 1
# Splits each byte into two, then unfold each half-byte to make a full byte.
# The slave will take this data, and fold it back to readable form
# This is to ensure anything being read by the slave is actual data, not noise.
def foldOpen(where, what):
hb = what >> 4
where.append((hb << 4) | (hb ^ 0x0F))
lb = what & 0x0F
where.append((lb << 4) | (lb ^ 0x0F))
# Unfolds the folded data
def unFold():
sByte, cByte = False, 0
timeout = time.perf_counter()
while((time.perf_counter() - timeout) < 1):
inByte = rs.read()
if((inByte >> 4) != ((inByte & 0x0F) ^ 0x0F)):
return 0
inByte >>= 4
if(sByte):
cByte <<= 4
cByte |= inByte
return cByte
else:
cByte = inByte
sByte = True
timeout = time.perf_counter()
return 0
# add's each piece of data into the crc
def AddCrc(crc, n):
for i in range(0, 8):
mix = (n ^ crc) & 0x01
crc >>= 1
if(mix):
crc ^= 0x8C
n >>= 1
return crc & 0xFF
#Receives a start bit, then address, then data length, then data, and finally crc.
#If everything is formatted correctly, the right amound of data is passed and crc correct
#it will return true
def recvMsg(msg):
msgState = crc = msgL = 0
timeout = time.perf_counter()
while(msgState <= 4):
if(rs.in_waiting > 0):
if(msgState < 1):
inByte = rs.read()
sleep(1)
else:
inByte = unFold()
if(msgState == 4):
for x in msg:
crc = AddCrc(crc, x)
if(crc == inByte):
return 1
elif(msgState == 3):
msg.append = inByte
if(len(msg) == msgL):
msgState = 4
elif(msgState == 2):
msgL = inByte
msgState = 3
elif(msgState == 1):
if(inByte == addr):
msgState = 2
else:
msgState = 5
elif(msgState == 0):
print('Start bit is ')
print(inByte)
if(inByte == 2):
print('accepted')
msgState = 1
if((time.perf_counter() - timeout) >= 5):
msgState = 5
#Sends a message, starting with start bit (2), addr, msg length, data, and crc
def sendMsg(where, size, what):
GPIO.output(7, GPIO.HIGH)
msg = bytearray()
crc = 0
msg.append(2)
foldOpen(msg, where)
foldOpen(msg, size)
for x in what:
foldOpen(msg, x)
for x in what:
crc = AddCrc(crc, x)
foldOpen(msg, crc)
rs.write(msg)
rs.flush()
GPIO.output(7, GPIO.LOW)
#creating random data to send to slave for testing
data = bytearray()
info = ord('A')
info2 = 45
data.append(info)
data.append(info2)
sendMsg(2, len(data), data)
#reads 1 byte, just so I know I made a connection
timer = time.perf_counter()
while((time.perf_counter() - timer) < 10):
if(rs.in_waiting):
inByte = rs.read(1)
print(inByte)
Arduino代码:
#include <RS485_Comm.h>
byte enablePin = 2;
byte check = 0;
size_t rsWrite (const byte what) {
Serial3.write (what);
Serial3.flush();
}
bool rsAvailable () {
return Serial3.available ();
}
int rsRead () {
return Serial3.read ();
}
RS485 myChannel (rsWrite, rsAvailable, rsRead, 20, 2, 2, 1);
//name(Write CB, AvailableCB, ReadCB, buffer, Epin, Addr, Debug)
void setup() {
Serial.begin(9600);
Serial3.begin(9600);
myChannel.begin();
Serial.print("A-OK");
}
void loop() {
if (myChannel.recvMsg()) {
if (myChannel.getMsg()[0] == 'A') {
Serial.print("A-OK");
byte msgOut[] = "A";
myChannel.sendMsg(msgOut, sizeof(msgOut), 1);
}
}
}
再一次,我可以把Raspi的信息发送到Arduino家。相同的Arduino,以相同的配置连接,可以与网络上的其他Arduino进行来回对话
我只是无法从Arduino和raspberry pi那里得到任何信息。rs.read(1)不返回任何内容,或返回一些随机噪声。我哪里做错了
在阅读您的问题时,您似乎正在为RPi上的GPIO引脚提供5V逻辑
对于快速测试来说,这可能没问题,但从长远来看,某些东西可能会损坏。如果转换器支持,最好使用3.3V作为MAX485的电源电压(有些电路板只能使用5V,而其他电路板似乎是双电压)
似乎是RPi上的UART RX出了问题,也许您应该验证它是否仍然正常。您可以按照以下步骤操作:
1)拆下RPi 40针接头上的所有导线
2)RPi UART上的RX对TX短路(针脚8与针脚10短路)
3)运行minicom:
sudo minicom -D /dev/serial0
4)在屏幕上键入任何内容。如果你能看到你正在键入的内容,这意味着你的UART正在工作
5)按CTRL键+A键,然后按E键激活回声。在屏幕上键入其他内容,现在您应该可以看到每个按键出现两次
6)按CTRL键+A键,然后按X键退出minicom
如果您需要进一步排除UART故障,有许多教程提供了更多详细信息。例如,见here
如果这些UART测试成功,您可以继续将RPi连接到Arduino并再次运行minicom,这次您可以使用以下选项选择波特率:
然后打开你的Arduino,看看你是否收到了
如果您这样做了,但是Python代码仍然没有报告任何内容,那么您可以确定问题出在那里(对于这样一个简单的任务,如果代码有点过于复杂,那么您的代码看起来很好)
相关问题 更多 >
编程相关推荐