Hi all
I'm using BBB debian 7.11 (kernel 3.8) version image.
I'm trying to use RS485 cape on BBB or BBG. The product is like below link.
485 CAN CAPE
http://www.waveshare.com/wiki/RS485_CAN_CAPE
485 CLICK BOARD
http://www.mikroe.com/click/rs485-3.3v/
As I know, these board don't have capability to auto change
transmit/receive mode.
I try to use linux serial rs485 system call to control transmit/receive
mode.
And I surfer from one problem is if I read data after writing, I will
receive a 0x00 byte in the beginning of the buffer.
This is not a real data. I use another rs485 device to monitor cable, and
doesn't receive this redundant data.
The attached file is my sample code. This is modbus command. Due to this
redundant data, modbus command will be failed.
So I use raw command to read write data. And the result is as below.
send: 01 04 00 00 00 01 31 CA
receive: 00 01 04 02 01 3E 39 70
send: 01 04 00 01 00 01 60 0A
receive: 00 01 04 02 00 E2 39 79
send: 02 04 00 00 00 01 31 F9
receive: 00 02 04 02 00 BA 7C 83
send: 02 04 00 01 00 01 60 39
receive: 00 02 04 02 00 FA 7D 73
send: 03 04 00 00 00 01 30 28
receive: 00 03 04 02 03 11 00 0C
send: 03 04 00 01 00 01 61 E8
receive: 00 03 04 02 00 DE 40 A8
If I only use receive mode, there will not be any redundant data(0x00) in
the buffer.
Another problem is rs485 mode will not work in kernel 4.4 as I tried.
Could anyone give me some advice that I'm not familiar in kernel.
Many thanks,
Harvey
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/beagleboard/9d07b367-ab24-4c89-8a8f-9d5d426764c3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
# -*- coding: utf-8 -*-
import minimalmodbus
import serial, fcntl, struct, time
from datetime import datetime
ROOM1 = '1'
TANK1 = '1'
ser = serial.Serial(
port='/dev/ttyO2',
baudrate=9600,
timeout=1,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
)
# Standard Linux RS485 ioctl:
TIOCSRS485 = 0x542F
# define serial_rs485 struct per Michael Musset's patch that adds gpio RE/DE
# control:
# (https://github.com/RobertCNelson/bb-kernel/blob/am33x-v3.8/patches/fixes/0007-omap-RS485-support-by-Michael-Musset.patch#L30)
SER_RS485_ENABLED = (1 << 0)
SER_RS485_RTS_ON_SEND = (1 << 1)
SER_RS485_RTS_AFTER_SEND = (1 << 2)
SER_RS485_RTS_BEFORE_SEND = (1 << 3)
SER_RS485_USE_GPIO = (1 << 5)
# Enable RS485 mode using a GPIO pin to control RE/DE:
RS485_FLAGS = SER_RS485_ENABLED | SER_RS485_USE_GPIO
# With this configuration the GPIO pin will be high when transmitting and low
# when not
# If SER_RS485_RTS_ON_SEND and SER_RS485_RTS_AFTER_SEND flags are included the
# RE/DE signal will be inverted, i.e. low while transmitting
# The GPIO pin to use, using the Kernel numbering:
RS485_RTS_GPIO_PIN = 50 # GPIO1_18 -> GPIO(1)_(18) = (1)*32+(18) = 50
# Pack the config into 8 consecutive unsigned 32-bit values:
# (per struct serial_rs485 in patched serial.h)
serial_rs485 = struct.pack('IIIIIIII',
RS485_FLAGS, # config flags
0, # delay in us before send
0, # delay in us after send
RS485_RTS_GPIO_PIN, # the pin number used for DE/RE
0, 0, 0, 0 # padding - space for more values
)
# Apply the ioctl to the open ttyO2 file descriptor:
fd=ser.fileno()
fcntl.ioctl(fd, TIOCSRS485, serial_rs485)
# Send some bytes:
# GPIO1_16 should be low here
time.sleep(0.2)
print ('connect to port %s' %ser.port)
now = datetime.now().strftime('%Y-%m-%d %H:%M:%S') #this will remove decimal point value
date = str(datetime.now().date().today())
print('date: %s' %now)
print('test in Room %s tank %s\n' %(ROOM1, TANK1))
cmd1 = b'\x01\x04\x00\x00\x00\x01\x31\xCA'
ser.write(cmd1)
out = bytearray(ser.read(8))
#print('%02X %02X %02X %02X %02X %02X %02X %02X' %(out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7]))
salinity = (out[4] * (16**2) + out[5]) / 100.0
print('Salinity value: %.2f%%' %salinity)
cmd2 = b'\x01\x04\x00\x01\x00\x01\x60\x0A'
ser.write(cmd2)
out = bytearray(ser.read(8))
#print('%02X %02X %02X %02X %02X %02X %02X %02X' %(out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7]))
temp = (out[4] * (16**2) + out[5]) / 10.0
a = u'\u2103'
print('temperature value: %.1f %s' %(temp, a.encode('utf8')))
line = ROOM1 + ' ' + TANK1 + ' ' + \
now + ' ' + str(salinity) + ' ' + str(temp)
print('data format: %s' %line)
time.sleep(0.1)
print('')
cmd1 = b'\x02\x04\x00\x00\x00\x01\x31\xF9'
ser.write(cmd1)
out = bytearray(ser.read(8))
#print('%02X %02X %02X %02X %02X %02X %02X %02X' %(out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7]))
orp = out[4] * (16**2) + out[5]
print('ORP value: %dmv' %orp)
cmd2 = b'\x02\x04\x00\x01\x00\x01\x60\x39'
ser.write(cmd2)
out = bytearray(ser.read(8))
#print('%02X %02X %02X %02X %02X %02X %02X %02X' %(out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7]))
temp = (out[4] * (16**2) + out[5]) / 10.0
a = u'\u2103'
print('temperature value: %.1f %s' %(temp, a.encode('utf8')))
line = ROOM1 + ' ' + TANK1 + ' ' + \
now + ' ' + str(orp) + ' ' + str(temp)
print('data format: %s' %line)
time.sleep(0.1)
print('')
cmd1 = b'\x03\x04\x00\x00\x00\x01\x30\x28'
ser.write(cmd1)
out = bytearray(ser.read(8))
#print('%02X %02X %02X %02X %02X %02X %02X %02X' %(out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7]))
ph = (out[4] * (16**2) + out[5]) / 100.0
print('PH value: %.2f' %ph)
cmd2 = b'\x03\x04\x00\x01\x00\x01\x61\xE8'
ser.write(cmd2)
out = bytearray(ser.read(8))
#print('%02X %02X %02X %02X %02X %02X %02X %02X' %(out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7]))
temp = (out[4] * (16**2) + out[5]) / 10.0
a = u'\u2103'
print('temperature value: %.1f %s' %(temp, a.encode('utf8')))
line = ROOM1 + ' ' + TANK1 + ' ' + \
now + ' ' + str(ph) + ' ' + str(temp)
print('data format: %s' %line)
print('\nCommand process done!')