Hi all
I'm useing debian 7.11(kernel 3.8) version image.
I'm trying to use rs485 cape on BBB or BBG. Below are the cape I use.
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 boards don't have capability to auto handle read/write mode
switching.
I try to use linux rs485 mode to auto handle switching problem.
The attached file is my sample code.
My problem is if I read data after writing, the receiving data will add a
redundant data(0x00) at the beginning of the buffer.
Below is the result.
This is modbus command, that due to the redundant data, the modbus command
will be failed.
So I use raw command to get data.
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
This redundant data is not read data from modbus device. I use another
rs485 cable to monitor the data will not have this redundant data.
Like this:
send: 01 04 00 00 00 01 31 CA
receive: 01 04 02 01 3E 39 70
If I only use receive mode, there will not be any redundant data in the
buffer.
As I tried, kernel 4.4 cannot work 485 system call.
I'm not familiar in kernel, does anyone could give me some advice?
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/c220e9fe-f495-4e4b-b94b-52379e0b94a2%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!')