I am new to python and I am trying to write a code to send hex serial data to a radio and receive hex data in response. radio_init_buf variable store the hex data to be sent. The last two bytes with store checksum. radio_init_buf[3] tells the size.
import sys
import glob
import numpy as np
import serial
class serial_communication():
PORT = 'COM2'
# RETURN_VALUE = None
def list_serial_ports(self):
""" Lists serial port names
:raises EnvironmentError:
On unsupported or unknown platforms
:returns:
A list of the serial ports available on the system
"""
if sys.platform.startswith('win'):
ports = ['COM%s' % (i + 1) for i in range(0,10)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
# this excludes your current terminal "/dev/tty"
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
except (OSError, serial.SerialException):
pass
return result
def serial_open(self):
self.ser = serial.Serial()
self.ser.baudrate = 9600
self.ser.port = sc.PORT
self.ser.parity = serial.PARITY_NONE
self.ser.stopbits = serial.STOPBITS_ONE
self.ser.bytesize = serial.EIGHTBITS
self.ser.writeTimeout = 1000
self.ser.timeout = 1000
try:
self.ser.open()
print("Port OPENED")
self.initialize(self.ser)
except Exception as e:
print("error opening serial port: " + str(e))
exit()
return self.ser
def checksum(self, crc_packet, crc_packet_length):
crc_table= np.array([0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040],dtype=np.uint16)
saved_crc_byte1 = crc_packet[crc_packet_length - 1]
saved_crc_byte2 = crc_packet[crc_packet_length - 2]
crc_packet[crc_packet_length - 1] = 0
crc_packet[crc_packet_length - 2] = 0
crc = 0
for crc_loop in range(0,crc_packet_length):
crc = (crc >> 8) ^ crc_table[(crc ^ crc_packet[crc_loop]) & 0xFF]
def initialize(self,serial_port):
ser = serial_port
if ser.isOpen():
print("Initialising...")
try:
ser.flushInput() # flush input buffer, discarding all its contents
ser.flushOutput() # flush output buffer, aborting current output
# and discard all that is in buffer
# write data
#f = open('F:/output.txt', 'wb')
radio_init_buf = np.array([0xAA, 0x00, 0x00, 0x08, 0x09, 0x32, 0x0, 0x0],dtype=np.uint8)
#radio_init_buf="\xAA\x00\x00\x08\x09\x32\x00\x00"
print(radio_init_buf)
self.checksum(radio_init_buf,radio_init_buf[3])
print(radio_init_buf)
ser.write(radio_init_buf)
serial.time.sleep(0.5) # give the serial port sometime to receive the data
#return_value = ser.read(7)
print(return_value)
print("Initialisation Complete")
#comm Link Check
print("Communication Link Checking..")
comm_check_buf = np.array([0xAA, 0x06, 00, 6, 0x0B, 0x70],dtype=np.uint8)
ser.write(comm_check_buf)
print("Link Check Complete")
#clear non-volatile memory
clear_nvm_buf = np.array([0xAA, 0x82, 00, 7, 1, 0, 0],dtype=np.uint8)
self.checksum(clear_nvm_buf, clear_nvm_buf[3])
ser.write(clear_nvm_buf)
#ser.close()
except Exception as e1:
print ("error communicating...: " + str(e1))
ser.close()
else:
print("cannot open serial port ")
sc = serial_communication()
print(sc.list_serial_ports())
sc.serial_open()
When i run the code i get:
['COM1', 'COM2', 'COM3']
Port OPENED
Initialising...
[170 0 0 8 9 50 0 0]
[170 0 0 8 9 50 0 0]
b'\xaa\x90\x00\x12\x01\x0c\x00'
Initialisation Complete
Communication Link Checking..
Link Check Complete
Instead of [170 0 0 8 9 50 0 0], i want the hex data.
Also, it is not returning radio_init_buf with checksum. The result after calling checksum is same.
Displaying in hex:
for n in radio_init_buf:
print("{:#x}".format(n), end='')
print()
{:#x} - a format string, #: adds the 0x prefix, x: presentation will be in hex,
In one line:
print(("{:#x} "*len(radio_init_buf)).format(*radio_init_buf))
It creates a string of length len(radio_init_buf).
In *radio_init_buf , '*' unpacks the list.
Related
I have tried my luck with these codes to read the data from the DDSU666-H and it seems that I am able to read data, but I don't know what to do with it. In theory it is a list of data, but I am not able to understand what I am receiving or how to translate it into something I can use
import serial # import the module
def banner_bottom():
print(' +-------------------------------------------+')
print(' | SPACE |')
print(' +-------------------------------------------+')
COM_Port = serial.Serial('COM3')
COM_Port.baudrate = 9600 # set Baud rate
COM_Port.bytesize = 8 # Number of data bits = 8
COM_Port.parity = 'N' # No parity
COM_Port.stopbits = 1 # Number of Stop bits = 1
COM_Port.setRTS(1) #RTS=1,~RTS=0 so ~RE=0,Receive mode enabled for MAX485
COM_Port.setDTR(1) #DTR=1,~DTR=0 so DE=0,(In FT232 RTS and DTR pins are inverted)
#~RE and DE LED's on USB2SERIAL board will be off
RxedData = COM_Port.readline()
print(' ',RxedData, '\n')
COM_Port.close() # Close the Serial port
banner_bottom()# Display the bottom banner
Output:
b'\x7f~\xbb\xff\xfb\xe3=\x7f~_cuI_\x0e\x7f~\xbb\xff\xfb\xe3=\x7f~_]\xd3V\'\t\x7f~\xbb\xff\xfb\xe3=\x7f~__\x07\xf5tU\x7f~\xbb\xff\xfb\xe3=\x7f~_[y\x8d\xba\x00\x7f~\xbb\xff\xfb\xe3=\x7f~_YsGe\x18\x7f~\xbb\xff\xfb\xe3=\x7f~_Y\xe3\x06n\x16\x7f~\xbb\xff\xfb\xe3=\x7f~__O]I\x1d\x7f~\xbb\xff\xfb\xe3=\x7f~_ao\xff\xf0\x05\x7f~\xbb\xff\xfb\xe3=\x7f~_co-O\x10\x7f~\xbb\xff\xfb\xe3=\x7f~__\x15\x117\x03\x7f~\xbb\xff\xfb\xe3=\x7f~__!-\xc9/\x7f~\xbb\xff\xfb\xe3=\x7f~__}\xed|\x00\x7f~\xbb\xff\xfb\xe3=\x7f~_c\xb7+\xda\x00\x7f~\xbb\xff\xfb\xe3=\x7f~_e\x8f"U\x01\x7f~\xfd\xff\xfb]\x1a\x7f~_W\xaf\x08\x975\x00\x7f~\xfd\xff\xfb]\x1a\x7f~_W\xaf\x08\x975\x00\x7f~\xfd\xff\xfb]\x1a\x7f~_W\xaf\x08\x975\x00\x7f~\xbb\xff\xfb\xe3=\x7f~_]\xd3V\'\t\x7f~\xbb\xff\xfb\xe3=\x7f~__\xd9\xadb\x08\x7f~\xbb\xff\xfb\xe3=\x7f~__\xc5[P\x05\x7f~\xbb\xff\xfb\xe3=\x7f~__\x91\xfef\x00\x7f~\xbb\xff\xfb\xe3=\x7f~_c3\xb3T\x0f\x7f~\xbb\xff\xfb\xe3=\x7f~_e\xbd\x01\xb0\x03\x7f~\xbb\xff\xfb\xe3=\x7f~_e?y\x84\x19\x7f~\xbb\xff\xfb\xe3=\x7f~_\xe349\xac\n'
Code 2:
#!/usr/bin/env python3
import serial
port = 'COM3'
ComPort = serial.Serial(port)
ComPort.baudrate = 9600
ComPort.bitesize = 8
ComPort.parity = 'N'
ComPort.stopbits = 1
dataIn=ComPort.read(6)
print(dataIn)
ComPort.close()
Ouput:
b'\x7f~\xbb\xff\xfb\xe3'
I've tried to translate the output into something I can understand, but I haven't been able to see anything either.
binary_data = b'\x7f~\xbb\xff\xfb\xe3'
aa = binary_data.hex()
print(aa)
#OUT: 7f7ebbfffbe3
bb = ''.join(['%02x' % b for b in binary_data])
print(bb)
#OUT: 7f7ebbfffbe3
s = binary_data.decode('cp855')
print(s)
#OUT:~╗ чÑ
What can I try to resolve this?
I want to send packet over Modbus TCP. I want to use:
But I can not send this way how can I send this packet? (I don't know something will be)
req = struct.pack(
'Something', transaction, identifier, length, unitid, func_code, reg_addr
)
These are my variables:
transaction=0x01
identifier=0x00
length=[0x00,0x06]
unitid=0x01
func_code=0x03
reg_addr=[0x13,0x14,0x15]
At first you can use pymodbus library with very features.
Also struct.pack() not support a list as argument.
0001 0000 0006 11 03 006B 0003 is a standard example of Modbus-TCP packet which contained:
0001: Transaction Identifier
0000: Protocol Identifier
0006: Message Length (6 bytes to follow)
11: The Unit Identifier (17 = 11 hex)
03: The Function Code (read Analog Output Holding Registers)
006B: The Data Address of the first register requested. (40108-40001 = 107 =6B hex)
0003: The total number of registers requested. (read 3 registers 40108 to 40110)
Reference
Thus, you can create a Modbus-TCP packet with the above example:
import struct
transaction = 0x0001
identifier = 0x0000
length = 0x0006
unitid = 0x11
fcode = 0x03 # Holding register fcode.
reg_addr = 0x006B # Register address.
count = 0x0003 # Read three register.
total_pack_string = '0x{:04x}{:04x}{:04x}{:02x}{:02x}{:04x}{:04x}'.format(
transaction, identifier, length, unitid, fcode, reg_addr, count
)
total_pack_hex = hex(int(total_pack_string, 16))
'''Or with using pack method.'''
pack_ = struct.pack(
'>HHHBBHH', transaction, identifier, length, unitid, fcode, reg_addr, count
)
# Then send the pack_ or total_pack_hex using a TCP-Socket.
[NOTE]:
transaction is 2Byte == Short == H
identifier is 2Byte == Short == H
length is 2Byte == Short == H
unitid is 1Byte == B
fcode is 1Byte == B
reg_addr is 2Byte == Short == H
count is 2Byte == Short == H
B is unsigned byte
H is unsigned short
Thus, the format will be like this >HHHBBHH
Using pymodbus equivalent:
from pymodbus.client.sync import ModbusTcpClient
unitid = 0x11
fcode = 0x03 # Holding register fcode.
reg_addr = 0x006B # Register address.
count = 0x0003 # Read three register.
cli = ModbusTcpClient('127.0.0.1', port=502)
if cli.connect():
res = cli.read_holding_registers(reg_addr, count=count, unit=unitid)
if not res.isError():
print(res.registers)
else:
print('There is an error.')
cli.close()
else:
print('Error in connection.')
I have a matrix keypad and a hd44780 lcd connected into raspberry pi.
The below code are in python. It will take 4 digit password from the user, but when the user enter the digit through the keypad, nothing was display on the lcd. I would like when the user enter a digit a * display on the lcd. I can only manage to get the * print in the same place,but not in 4 separate place.
Code
import RPi.GPIO as GPIO
import time
import lcd
import os
import subprocess
from subprocess import call
mylcd = lcd.lcd()
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
MATRIX = [['1', '2', '3', 'A'],
['4', '5', '6', 'B'],
['7', '8', '9', 'C'],
['*', '0', '#', 'D']]
ROW = [5,6,13,19]
COL = [26,16,20,21]
for j in range(4):
GPIO.setup(COL[j], GPIO.OUT)
GPIO.output(COL[j], 1)
for i in range(4):
GPIO.setup(ROW[i], GPIO.IN, pull_up_down=GPIO.PUD_UP)
password = "1234"
attempt = ""
try:
while (True):
mylcd.lcd_display_string("Enter pw",1)
for j in range(4):
GPIO.output(COL[j], 0)
for i in range(4):
if GPIO.input(ROW[i]) == 0:
mylcd.lcd_display_string("*",2,0)
time.sleep(0.01)
while (GPIO.input(ROW[i]) == 0):
pass
attempt += MATRIX[i][j]
if len(attempt) == len(password):
if attempt == password:
mylcd.lcd_clear()
print "Password OK"
mylcd.lcd_display_string("Password",1 ,4 )
mylcd.lcd_display_string("Ok!",2 ,6 )
time.sleep(2)
mylcd.lcd_clear()
os.chdir('/home/pi/nfc/py532lib')
call('./nfc.sh')
mylcd.lcd_clear()
else:
print(attempt)
print "Password incorrect"
mylcd.lcd_display_string("Password",1,4)
mylcd.lcd_display_string("Incorrect!",2,3)
time.sleep(2)
mylcd.lcd_clear()
attempt = ""
time.sleep(0.01)
GPIO.output(COL[j], 1)
except KeyboardInterrupt:
GPIO.cleanup()
LCD Library
# -*- coding: utf-8 -*-
# Original code found at:
# https://gist.github.com/DenisFromHR/cc863375a6e19dce359d
"""
Compiled, mashed and generally mutilated 2014-2015 by Denis Pleic
Made available under GNU GENERAL PUBLIC LICENSE
# Modified Python I2C library for Raspberry Pi
# as found on http://www.recantha.co.uk/blog/?p=4849
# Joined existing 'i2c_lib.py' and 'lcddriver.py' into a single library
# added bits and pieces from various sources
# By DenisFromHR (Denis Pleic)
# 2015-02-10, ver 0.1
"""
# i2c bus (0 -- original Pi, 1 -- Rev 2 Pi)
I2CBUS = 0
# LCD Address
ADDRESS = 0x27
import smbus
from time import sleep
class i2c_device:
def __init__(self, addr, port=I2CBUS):
self.addr = addr
self.bus = smbus.SMBus(port)
# Write a single command
def write_cmd(self, cmd):
self.bus.write_byte(self.addr, cmd)
sleep(0.0001)
# Write a command and argument
def write_cmd_arg(self, cmd, data):
self.bus.write_byte_data(self.addr, cmd, data)
sleep(0.0001)
# Write a block of data
def write_block_data(self, cmd, data):
self.bus.write_block_data(self.addr, cmd, data)
sleep(0.0001)
# Read a single byte
def read(self):
return self.bus.read_byte(self.addr)
# Read
def read_data(self, cmd):
return self.bus.read_byte_data(self.addr, cmd)
# Read a block of data
def read_block_data(self, cmd):
return self.bus.read_block_data(self.addr, cmd)
# commands
LCD_CLEARDISPLAY = 0x01
LCD_RETURNHOME = 0x02
LCD_ENTRYMODESET = 0x04
LCD_DISPLAYCONTROL = 0x08
LCD_CURSORSHIFT = 0x10
LCD_FUNCTIONSET = 0x20
LCD_SETCGRAMADDR = 0x40
LCD_SETDDRAMADDR = 0x80
# flags for display entry mode
LCD_ENTRYRIGHT = 0x00
LCD_ENTRYLEFT = 0x02
LCD_ENTRYSHIFTINCREMENT = 0x01
LCD_ENTRYSHIFTDECREMENT = 0x00
# flags for display on/off control
LCD_DISPLAYON = 0x04
LCD_DISPLAYOFF = 0x00
LCD_CURSORON = 0x02
LCD_CURSOROFF = 0x00
LCD_BLINKON = 0x01
LCD_BLINKOFF = 0x00
# flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00
LCD_MOVERIGHT = 0x04
LCD_MOVELEFT = 0x00
# flags for function set
LCD_8BITMODE = 0x10
LCD_4BITMODE = 0x00
LCD_2LINE = 0x08
LCD_1LINE = 0x00
LCD_5x10DOTS = 0x04
LCD_5x8DOTS = 0x00
# flags for backlight control
LCD_BACKLIGHT = 0x08
LCD_NOBACKLIGHT = 0x00
En = 0b00000100 # Enable bit
Rw = 0b00000010 # Read/Write bit
Rs = 0b00000001 # Register select bit
class lcd:
#initializes objects and lcd
def __init__(self):
self.lcd_device = i2c_device(ADDRESS)
self.lcd_write(0x03)
self.lcd_write(0x03)
self.lcd_write(0x03)
self.lcd_write(0x02)
self.lcd_write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE)
self.lcd_write(LCD_DISPLAYCONTROL | LCD_DISPLAYON)
self.lcd_write(LCD_CLEARDISPLAY)
self.lcd_write(LCD_ENTRYMODESET | LCD_ENTRYLEFT)
sleep(0.2)
# clocks EN to latch command
def lcd_strobe(self, data):
self.lcd_device.write_cmd(data | En | LCD_BACKLIGHT)
sleep(.0005)
self.lcd_device.write_cmd(((data & ~En) | LCD_BACKLIGHT))
sleep(.0001)
def lcd_write_four_bits(self, data):
self.lcd_device.write_cmd(data | LCD_BACKLIGHT)
self.lcd_strobe(data)
# write a command to lcd
def lcd_write(self, cmd, mode=0):
self.lcd_write_four_bits(mode | (cmd & 0xF0))
self.lcd_write_four_bits(mode | ((cmd << 4) & 0xF0))
# write a character to lcd (or character rom) 0x09: backlight | RS=DR<
# works!
def lcd_write_char(self, charvalue, mode=1):
self.lcd_write_four_bits(mode | (charvalue & 0xF0))
self.lcd_write_four_bits(mode | ((charvalue << 4) & 0xF0))
# put string function with optional char positioning
def lcd_display_string(self, string, line=1, pos=0):
if line == 1:
pos_new = pos
elif line == 2:
pos_new = 0x40 + pos
elif line == 3:
pos_new = 0x14 + pos
elif line == 4:
pos_new = 0x54 + pos
self.lcd_write(0x80 + pos_new)
for char in string:
self.lcd_write(ord(char), Rs)
# clear lcd and set to home
def lcd_clear(self):
self.lcd_write(LCD_CLEARDISPLAY)
self.lcd_write(LCD_RETURNHOME)
# define backlight on/off (lcd.backlight(1); off= lcd.backlight(0)
def backlight(self, state): # for state, 1 = on, 0 = off
if state == 1:
self.lcd_device.write_cmd(LCD_BACKLIGHT)
elif state == 0:
self.lcd_device.write_cmd(LCD_NOBACKLIGHT)
# add custom characters (0 - 7)
def lcd_load_custom_chars(self, fontdata):
self.lcd_write(0x40);
for char in fontdata:
for line in char:
self.lcd_write_char(line)
Your code may be not correct. For each output you test all inputs:
for i in range(4):
if GPIO.input(ROW[i]) == 0:
Check if for sure exactly one proper input is active. If not, you have to rewrite it.
Moreover, the number of * should depend on external counter j, not i (my mistake in the comment, sorry):
mylcd.lcd_display_string((j+1) * "*", 2, 0)
I'm using Python3.5.1 serial module. When I open a port it fails with OS Error 22 (Windows Error 87) which signals failure to configure port, one of the arguments in OPEN system call were incorrect, or malformed.
My code uses loops over serial settings - that sends bad packets to the device until the device responds with a (readable) error message (so I know that my serial port is configured correctly). Yes, I should just know the device's settings but this isn't a prefect world.
import serial
import time
baud_rate = [50,75,110,134,150,200,300600,1200,1800,2400,4800,9600,19200,38400,57600,115200]
parity = [serial.PARITY_ODD,serial.PARITY_EVEN,serial.PARITY_NONE]
stop_bits = [serial.STOPBITS_TWO, serial.STOPBITS_ONE]
bytesize = [serial.SEVENBITS,serial.EIGHTBITS]
timeout = 5000
for b in baud_rate:
for p in parity:
for s in stop_bits:
for bs in bytesize:
ser = serial.Serial(port='COM3',baudrate=b,parity=p,stopbits=s,bytesize=bs)
try:
if ser.isOpen():
ser.write(b'TEST')
ser.reset_output_buffer()
time.sleep(1)
out = ser.read(3)
if out[0] == 64 and out[1] == 67 and out[2] == 32:
print("dumping settings")
print(ser.get_settings())
else:
ser.close()
except SerialException:
print("Serial Exception occured.")
pass
The problem happens under windows 7 x64 service pack 1. The python version is 3.5. The cmd.exe instance is ran as administrator.
I'm very sure COM3 exists when I run the script
import serial.tools.list_ports
ports = list(serial.tools.list_ports.comports())
for p in ports:
print(p)
I receive the output:
>python list_serial.py
COM3 - Prolific USB-to-Serial Comm Port (COM3)
So I believe the port URL/URI (idfk) is correct.
Full Error Text:
Traceback (most recent call last):
File "serial_reader.py", line 13, in <module>
ser = serial.Serial(port='COM3',baudrate=b,parity=p,stopbits=s,bytesize=bs)
File "C:\Users\FA1\AppData\Local\Programs\Python\Python35-32\lib\site-packages\serial\serialwin32.py", line 31, in __init__
SerialBase.__init__(self, *args, **kwargs)
File "C:\Users\FA1\AppData\Local\Programs\Python\Python35-32\lib\site-packages\serial\serialutil.py", line 180, in __init__
self.open()
File "C:\Users\FA1\AppData\Local\Programs\Python\Python35-32\lib\site-packages\serial\serialwin32.py", line 78, in open
self._reconfigure_port()
File "C:\Users\FA1\AppData\Local\Programs\Python\Python35-32\lib\site-packages\serial\serialwin32.py", line 220, in _reconfigure_port
raise SerialException("Cannot configure port, something went wrong. Original message: %r" % ctypes.WinError())
serial.serialutil.SerialException: Cannot configure port, something went wrong. Original message: OSError(22, 'The parameter is incorrect.', None, 87)
I've ensured the driver is properly installed, but I receive this error with 2 different serial converters. So I believe the issue isn't hardware or driver related.
You say that you "should just know the device's settings but this isn't a prefect world". But Windows does allow querying communications device properties via GetCommProperties. pySerial doesn't appear to support this, but you can use ctypes to call this function directly.
The following defines a get_comm_properties function to query the settable properties of a comm port. It accepts either an existing device handle (e.g. the _handle attribute of a pySerial port) or a DOS device name such as COM1 or WinAPI device name such as \\.\COM1.
import collections
import ctypes
from ctypes import wintypes
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
OPEN_EXISTING = 3
INVALID_HANDLE_VALUE = wintypes.HANDLE(-1).value
ERROR_FILE_NOT_FOUND = 0x0002
class COMMPROP(ctypes.Structure):
_fields_= (('wPacketLength', wintypes.WORD),
('wPacketVersion', wintypes.WORD),
('dwServiceMask', wintypes.DWORD),
('dwReserved1', wintypes.DWORD),
('dwMaxTxQueue', wintypes.DWORD),
('dwMaxRxQueue', wintypes.DWORD),
('dwMaxBaud', wintypes.DWORD),
('dwProvSubType', wintypes.DWORD),
('dwProvCapabilities', wintypes.DWORD),
('dwSettableParams', wintypes.DWORD),
('dwSettableBaud', wintypes.DWORD),
('wSettableData', wintypes.WORD),
('wSettableStopParity', wintypes.WORD),
('dwCurrentTxQueue', wintypes.DWORD),
('dwCurrentRxQueue', wintypes.DWORD),
('dwProvSpec1', wintypes.DWORD),
('dwProvSpec2', wintypes.DWORD),
('wcProvChar', wintypes.WCHAR * 1))
class _CONST:
COMMPROP_INITIALIZED = 0xE73CF52E
SP_SERIALCOMM = 0x00000001
BAUD_USER = 0x10000000 # programmable baud rate
DATABITS_16X = 0x0020 # hardware wide data path
PROV_SUBTYPE = collections.OrderedDict([
('UNSPECIFIED', 0x00000000),
('RS232', 0x00000001),
('PARALLELPORT', 0x00000002),
('RS422', 0x00000003),
('RS423', 0x00000004),
('RS449', 0x00000005),
('MODEM', 0x00000006),
('FAX', 0x00000021),
('SCANNER', 0x00000022),
('NETWORK_BRIDGE', 0x00000100),
('LAT', 0x00000101),
('TCPIP_TELNET', 0x00000102),
('X25', 0x00000103),
])
PROV_CAPABILITIES = collections.OrderedDict([
('DTRDSR', 0x0001), # data-terminal-ready / data-set-ready
('RTSCTS', 0x0002), # request-to-send / clear-to-send
('RLSD', 0x0004), # receive-line-signal-detect
('PARITY_CHECK', 0x0008),
('XONXOFF', 0x0010), # XON/XOFF flow control
('SETXCHAR', 0x0020), # settable XON/XOFF
('TOTALTIMEOUTS', 0x0040), # total (elapsed) time-outs
('INTTIMEOUTS', 0x0080), # interval time-outs
('SPECIALCHARS', 0x0100),
('16BITMODE', 0x0200),
])
SETTABLE_PARAMS = collections.OrderedDict([
('PARITY', 0x0001),
('BAUD', 0x0002),
('DATABITS', 0x0004),
('STOPBITS', 0x0008),
('HANDSHAKING', 0x0010), # flow control
('PARITY_CHECK', 0x0020),
('RLSD', 0x0040), # receive-line-signal-detect
])
SETTABLE_BAUD = collections.OrderedDict([
(75, 0x00000001),
(110, 0x00000002),
(134.5, 0x00000004),
(150, 0x00000008),
(300, 0x00000010),
(600, 0x00000020),
(1200, 0x00000040),
(1800, 0x00000080),
(2400, 0x00000100),
(4800, 0x00000200),
(7200, 0x00000400),
(9600, 0x00000800),
(14400, 0x00001000),
(19200, 0x00002000),
(38400, 0x00004000),
(56000, 0x00008000),
(57600, 0x00040000),
(115200, 0x00020000),
(128000, 0x00010000),
])
SETTABLE_DATA = collections.OrderedDict([
(5, 0x0001), # 5 data bits
(6, 0x0002), # 6 data bits
(7, 0x0004), # 7 data bits
(8, 0x0008), # 8 data bits
(16, 0x0010), # 16 data bits
])
SETTABLE_STOP = collections.OrderedDict([
(1, 0x0001), # 1 stop bit
(1.5, 0x0002), # 1.5 stop bits
(2, 0x0004), # 2 stop bits
])
SETTABLE_PARITY = collections.OrderedDict([
('NONE', 0x0100), # no parity
('ODD', 0x0200), # odd parity
('EVEN', 0x0400), # even parity
('MARK', 0x0800), # mark parity
('SPACE', 0x1000), # space parity
])
#property
def max_baud(self):
s = self.dwMaxBaud
m = self._CONST.SETTABLE_BAUD
if s == self._CONST.BAUD_USER:
return 0
else:
return m[s]
#property
def prov_subtype(self):
s = self.dwProvSubType
m = self._CONST.PROV_SUBTYPE
return [x for x, c in m.items() if c & s]
#property
def prov_capabilities(self):
s = self.dwProvCapabilities
m = self._CONST.PROV_CAPABILITIES
return [x for x, c in m.items() if c & s]
#property
def settable_params(self):
s = self.dwSettableParams
m = self._CONST.SETTABLE_PARAMS
return [x for x, c in m.items() if c & s]
#property
def settable_baud(self):
s = self.dwSettableBaud
m = self._CONST.SETTABLE_BAUD
return [x for x, c in m.items() if c & s]
#property
def user_settable_baud(self):
return bool(self.dwSettableBaud & self._CONST.BAUD_USER)
#property
def settable_data(self):
s = self.wSettableData
m = self._CONST.SETTABLE_DATA
return [x for x, c in m.items() if c & s]
#property
def wide_settable_data(self):
return bool(self.wSettableData & self._CONST.DATABITS_16X)
#property
def settable_stop(self):
s = self.wSettableStopParity
m = self._CONST.SETTABLE_STOP
return [x for x, c in m.items() if c & s]
#property
def settable_parity(self):
s = self.wSettableStopParity
m = self._CONST.SETTABLE_PARITY
return [x for x, c in m.items() if c & s]
LPCOMMPROP = ctypes.POINTER(COMMPROP)
class SECURITY_ATTRIBUTES(ctypes.Structure):
_fields_ = (('nLength', wintypes.DWORD),
('lpSecurityDescriptor', wintypes.LPVOID),
('bInheritHandle', wintypes.BOOL))
LPSECURITY_ATTRIBUTES = ctypes.POINTER(SECURITY_ATTRIBUTES)
kernel32.CreateFileW.restype = wintypes.HANDLE
kernel32.CreateFileW.argtypes = (
wintypes.LPCWSTR, # _In_ lpFileName
wintypes.DWORD, # _In_ dwDesiredAccess
wintypes.DWORD, # _In_ dwShareMode
LPSECURITY_ATTRIBUTES, # _In_opt_ lpSecurityAttributes
wintypes.DWORD, # _In_ dwCreationDisposition
wintypes.DWORD, # _In_ dwFlagsAndAttributes
wintypes.HANDLE) # _In_opt_ hTemplateFile
kernel32.CloseHandle.argtypes = (wintypes.HANDLE,)
kernel32.GetCommProperties.argtypes = (
wintypes.HANDLE, # _In_ hFile
LPCOMMPROP) # _Out_ lpCommProp
def get_comm_properties(handle_or_port):
if isinstance(handle_or_port, str):
handle = kernel32.CreateFileW(
handle_or_port,
GENERIC_READ | GENERIC_WRITE,
0, # exclusive access
None, # default security
OPEN_EXISTING,
0,
None)
if handle == INVALID_HANDLE_VALUE:
raise ctypes.WinError(ctypes.get_last_error())
close_handle = True
else:
handle = handle_or_port
close_handle = False
try:
prop = COMMPROP()
if not kernel32.GetCommProperties(handle, ctypes.byref(prop)):
raise ctypes.WinError(ctypes.get_last_error())
finally:
if close_handle:
kernel32.CloseHandle(handle)
return prop
Example:
if __name__ == '__main__':
for i in range(1, 10):
port = r'\\.\COM%d' % i
try:
prop = get_comm_properties(port)
except WindowsError as e:
if e.winerror == ERROR_FILE_NOT_FOUND:
continue
print('%s properties' % port)
x = prop.dwMaxTxQueue if prop.dwMaxTxQueue else 'no limit'
print('\tMax output buffer size: %s' % x)
x = prop.dwMaxRxQueue if prop.dwMaxRxQueue else 'no limit'
print('\tMax input buffer size: %s' % x)
x = prop.dwCurrentTxQueue if prop.dwCurrentTxQueue else 'unavailable'
print('\tCurrent output buffer size: %s' % x)
x = prop.dwCurrentRxQueue if prop.dwCurrentRxQueue else 'unavailable'
print('\tCurrent input buffer size: %s' % x)
x = prop.max_baud if prop.max_baud else 'user programmable'
print('\tMax baud rate: %s' % x)
print('\tProvider subtypes:\n\t\t%s' %
'\n\t\t'.join(prop.prov_subtype))
print('\tProvider capabilities:\n\t\t%s' %
'\n\t\t'.join(prop.prov_capabilities))
print('\tSettable parameters:\n\t\t%s' %
'\n\t\t'.join(prop.settable_params))
print('\tSettable baud rates:\n\t\t%s' %
'\n\t\t'.join([str(x) for x in prop.settable_baud]))
print('\tSettable user baud rates: %s' %
prop.user_settable_baud)
print('\tSettable data bits:\n\t\t%s' %
'\n\t\t'.join([str(x) for x in prop.settable_data]))
print('\tSettable wide data bits: %s' %
prop.wide_settable_data)
print('\tSettable stop bits:\n\t\t%s' %
'\n\t\t'.join([str(x) for x in prop.settable_stop]))
print('\tSettable parity:\n\t\t%s' %
'\n\t\t'.join(prop.settable_parity))
Output:
\\.\COM1 properties
Max output buffer size: no limit
Max input buffer size: no limit
Current output buffer size: unavailable
Current input buffer size: 4096
Max baud rate: user programmable
Provider subtypes:
RS232
RS422
RS449
FAX
LAT
X25
Provider capabilities:
DTRDSR
RTSCTS
RLSD
PARITY_CHECK
XONXOFF
SETXCHAR
TOTALTIMEOUTS
INTTIMEOUTS
Settable parameters:
PARITY
BAUD
DATABITS
STOPBITS
HANDSHAKING
PARITY_CHECK
RLSD
Settable baud rates:
75
110
134.5
150
300
600
1200
1800
2400
4800
7200
9600
14400
19200
38400
56000
57600
115200
Settable user baud rates: True
Settable data bits:
5
6
7
8
Settable wide data bits: False
Settable stop bits:
1
1.5
2
Settable parity:
NONE
ODD
EVEN
MARK
SPACE
Baud rates <100 are treated as configuration errors in Windows 7. So starting the loop on 50,75 baud will both yield errors. 110 baud does not return an error.
I have 3 files lcdtest.py, lcd.py and alarmfunctionr.py.
I am trying to control the attached lcd display on my raspberry pi with the lcdtest.py script.
!/usr/bin/env python
import paho.mqtt.client as paho
import globals
import time
from alarmfunctionsr import SendToLCD
from lcd import noDisplay
from lcd import message
globals.init()
SendToLCD(12, "test lcd" ,1) #Test
time.sleep(5)
lcd.message("test with message")
time.sleep(5)
noDisplay
The import from alarmfunctionsr seem to work ok but i get an cannot import name error when i try the same for the lcd script.
lcd.py:
#!/usr/bin/python
#
# based on code from lrvick and LiquidCrystal
# lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py
# LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp
#
from time import sleep
class CharLCD(object):
# commands
LCD_CLEARDISPLAY = 0x01
LCD_RETURNHOME = 0x02
LCD_ENTRYMODESET = 0x04
LCD_DISPLAYCONTROL = 0x08
LCD_CURSORSHIFT = 0x10
LCD_FUNCTIONSET = 0x20
LCD_SETCGRAMADDR = 0x40
LCD_SETDDRAMADDR = 0x80
# flags for display entry mode
LCD_ENTRYRIGHT = 0x00
LCD_ENTRYLEFT = 0x02
LCD_ENTRYSHIFTINCREMENT = 0x01
LCD_ENTRYSHIFTDECREMENT = 0x00
# flags for display on/off control
LCD_DISPLAYON = 0x04
LCD_DISPLAYOFF = 0x00
LCD_CURSORON = 0x02
LCD_CURSOROFF = 0x00
LCD_BLINKON = 0x01
LCD_BLINKOFF = 0x00
# flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00
# flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00
LCD_MOVERIGHT = 0x04
LCD_MOVELEFT = 0x00
# flags for function set
LCD_8BITMODE = 0x10
LCD_4BITMODE = 0x00
LCD_2LINE = 0x08
LCD_1LINE = 0x00
LCD_5x10DOTS = 0x04
LCD_5x8DOTS = 0x00
def __init__(self, pin_rs=25, pin_e=24, pins_db=[23, 17, 27, 22], GPIO=None):
# Emulate the old behavior of using RPi.GPIO if we haven't been given
# an explicit GPIO interface to use
if not GPIO:
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
self.GPIO = GPIO
self.pin_rs = pin_rs
self.pin_e = pin_e
self.pins_db = pins_db
self.GPIO.setmode(GPIO.BCM)
self.GPIO.setup(self.pin_e, GPIO.OUT)
self.GPIO.setup(self.pin_rs, GPIO.OUT)
for pin in self.pins_db:
self.GPIO.setup(pin, GPIO.OUT)
self.write4bits(0x33) # initialization
self.write4bits(0x32) # initialization
self.write4bits(0x28) # 2 line 5x7 matrix
self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor
self.write4bits(0x06) # shift cursor right
self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF
self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS
self.displayfunction |= self.LCD_2LINE
# Initialize to default text direction (for romance languages)
self.displaymode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) # set the entry mode
self.clear()
def begin(self, cols, lines):
if (lines > 1):
self.numlines = lines
self.displayfunction |= self.LCD_2LINE
def home(self):
self.write4bits(self.LCD_RETURNHOME) # set cursor position to zero
self.delayMicroseconds(3000) # this command takes a long time!
def clear(self):
self.write4bits(self.LCD_CLEARDISPLAY) # command to clear display
self.delayMicroseconds(3000) # 3000 microsecond sleep, clearing the display takes a long time
def setCursor(self, col, row):
self.row_offsets = [0x00, 0x40, 0x14, 0x54]
self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row]))
def noDisplay(self):
""" Turn the display off (quickly) """
self.displaycontrol &= ~self.LCD_DISPLAYON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
def display(self):
""" Turn the display on (quickly) """
self.displaycontrol |= self.LCD_DISPLAYON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
def noCursor(self):
""" Turns the underline cursor off """
self.displaycontrol &= ~self.LCD_CURSORON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
def cursor(self):
""" Turns the underline cursor on """
self.displaycontrol |= self.LCD_CURSORON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
def noBlink(self):
""" Turn the blinking cursor off """
self.displaycontrol &= ~self.LCD_BLINKON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
def blink(self):
""" Turn the blinking cursor on """
self.displaycontrol |= self.LCD_BLINKON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
def DisplayLeft(self):
""" These commands scroll the display without changing the RAM """
self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT)
def scrollDisplayRight(self):
""" These commands scroll the display without changing the RAM """
self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT)
def leftToRight(self):
""" This is for text that flows Left to Right """
self.displaymode |= self.LCD_ENTRYLEFT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
def rightToLeft(self):
""" This is for text that flows Right to Left """
self.displaymode &= ~self.LCD_ENTRYLEFT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
def autoscroll(self):
""" This will 'right justify' text from the cursor """
self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
def noAutoscroll(self):
""" This will 'left justify' text from the cursor """
self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
def write4bits(self, bits, char_mode=False):
""" Send command to LCD """
self.delayMicroseconds(1000) # 1000 microsecond sleep
bits = bin(bits)[2:].zfill(8)
self.GPIO.output(self.pin_rs, char_mode)
for pin in self.pins_db:
self.GPIO.output(pin, False)
for i in range(4):
if bits[i] == "1":
self.GPIO.output(self.pins_db[::-1][i], True)
self.pulseEnable()
for pin in self.pins_db:
self.GPIO.output(pin, False)
for i in range(4, 8):
if bits[i] == "1":
self.GPIO.output(self.pins_db[::-1][i-4], True)
self.pulseEnable()
def delayMicroseconds(self, microseconds):
seconds = microseconds / float(1000000) # divide microseconds by 1 million for seconds
sleep(seconds)
def pulseEnable(self):
self.GPIO.output(self.pin_e, False)
self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
self.GPIO.output(self.pin_e, True)
self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
self.GPIO.output(self.pin_e, False)
self.delayMicroseconds(1) # commands need > 37us to settle
def message(self, text):
""" Send string to LCD. Newline wraps to second line"""
for char in text:
if char == '\n':
self.write4bits(0xC0) # next line
else:
self.write4bits(ord(char), True)
def DisplayLCD(msg):
lcd = CharLCD()
lcd.clear()
x=msg.find("**")
if x>0:
line1=msg[0:x]
line2=msg[x+2:len(msg)]
else:
line1=msg
line2=""
lcd.message(line1+"\n"+line2)
alarmfunctionsr.py:
#!/usr/bin/env python
"""
import globals
import urllib2
import smtplib
import serial
import time
import sys
import thread
import RPi.GPIO as GPIO
import os, glob, time, operator
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from time import sleep
def find_all(a_str, sub):
start = 0
cnt=0
while True:
start = a_str.find(sub, start)
if start == -1:
return cnt
start += len(sub)
cnt=cnt+1
def isNumber(x):
# Test whether the contents of a string is a number
try:
val = int(x)
except ValueError:
return False
return True
def get_latest_photo(files):
lt = operator.lt
if not files:
return None
now = time.time()
latest = files[0], now - os.path.getctime(files[0])
for f in files[1:]:
age = now - os.path.getctime(f)
if lt(age, latest[1]):
latest = f, age
return latest[0]
def UpdateHostThread(function,opcode):
try:
thread.start_new_thread(UpdateHostThread, (function,opcode, ) )
except:
print "Error: unable to start thread"
def UpdateHost(function,opcode):
# Sends data to the server
script_path = "https://www.privateeyepi.com/alarmhostr.php?u="+globals.user+"&p="+globals.password+"&function="+str(function)
i=0
for x in opcode:
script_path=script_path+"&opcode"+str(i)+"="+str(opcode[i])
i=i+1
if globals.PrintToScreen: print "Host Update: "+script_path
try:
rt=urllib2.urlopen(script_path)
except urllib2.HTTPError:
if globals.PrintToScreen: print "HTTP Error"
return False
time.sleep(.2)
temp=rt.read()
if globals.PrintToScreen: print temp
l = find_all(temp,"/n");
RecordSet = temp.split(',')
c=[]
y=0
c.append([])
for x in RecordSet:
if x=="/n":
y=y+1
if y < l:
c.append([])
else:
if isNumber(x):
c[y].append(int(x))
else:
c[y].append(x)
rt=ProcessActions(c)
if rt==False:
return(False)
else:
return(c)
def ProcessActions(ActionList):
FalseInd=True
for x in ActionList:
if x[0]=="/EMAIL":
SendEmailAlertFromRule(x[1], x[2],0)
x.remove
if x[0]=="/SEMAIL":
SendEmailAlert(x[1])
x.remove
if x[0]=="/CHIME":
StartChimeThread()
x.remove
if x[0]=="/rn588":
exit()
if x[0]=="/FALSE":
FalseInd=False
if x[0]=="/SIREN":
StartSirenThread(x[2])
x.remove
if x[0]=="/PHOTO":
SendEmailAlertFromRule(x[1], x[2],1)
x.remove
if x[0]=="/RELAYON":
SwitchRelay(1)
x.remove
if x[0]=="/RELAYOFF":
SwitchRelay(0)
x.remove
if x[0]=="/WRELAYON":
SwitchRFRelay(1)
x.remove
if x[0]=="/WRELAYOFF":
SwitchRFRelay(0)
x.remove
return(FalseInd)
def StartSirenThread(Zone):
try:
thread.start_new_thread(Siren, (Zone, ) )
except:
print "Error: unable to start thread"
def SwitchRelay(onoff):
GPIO.setmode(GPIO.BOARD)
GPIO.setup(globals.RelayPin, GPIO.OUT)
GPIO.output(globals.RelayPin,onoff)
def SwitchRFRelay(onoff):
# declare to variables, holding the com port we wish to talk to and the speed
port = '/dev/ttyAMA0'
baud = 9600
# open a serial connection using the variables above
ser = serial.Serial(port=port, baudrate=baud)
# wait for a moment before doing anything else
sleep(0.2)
for i in range(0,3):
if (onoff==True):
ser.write('a{}RELAYAON-'.format(globals.WRelayPin))
else:
ser.write('a{}RELAYAOFF'.format(globals.WRelayPin))
time.sleep(2)
ser.close
def SendToLCD(GPIOnumber, Location, status):
import paho.mqtt.client as paho
if status==0:
ActionStr="_"
topic="alarm_activity"
else:
if status==1:
ActionStr="_"
topic="alarm_activity"
else:
topic="temperature"
if status==2:
ActionStr=str(GPIOnumber)+","+Location
else:
ActionStr="Undefined"
#client = mosquitto.Mosquitto('privateeyepi')
client = paho.Client()
client.connect(globals.lcd_ip)
if status <= 1:
if globals.PrintToScreen:
print str(Location)+"**"+str(ActionStr)
client.publish(topic, str(Location)+"**"+str(ActionStr))
else:
if globals.PrintToScreen:
print str(ActionStr)
client.publish(topic, ActionStr)
client.disconnect()
def Siren(Zone):
GPIO.setmode(GPIO.BOARD)
if globals.UseSiren == True:
GPIO.setup(globals.SirenGPIOPin, GPIO.OUT) #Siren pin setup
else:
return
if globals.SirenDelay>0:
globals.SirenStartTime = time.time()
while time.time() < globals.SirenStartTime + globals.SirenDelay:
if globals.BeepDuringDelay:
GPIO.output(globals.SirenGPIOPin,True)
time.sleep(1)
GPIO.output(globals.SirenGPIOPin,False)
time.sleep(4)
GPIO.output(globals.SirenGPIOPin,True)
globals.SirenStartTime = time.time()
if globals.PrintToScreen: print "Siren Activated"
while time.time() < globals.SirenStartTime + globals.SirenTimeout:
time.sleep(5)
if CheckForSirenDeactivation(Zone) == True:
break
GPIO.output(globals.SirenGPIOPin,False)
if globals.PrintToScreen: print "Siren Deactivated"
def CheckForSirenDeactivation(Zone):
# Routine to fetch the location and zone descriptions from the server
RecordSet = GetDataFromHost(16,[Zone])
if globals.PrintToScreen: print RecordSet
ZoneStatus=RecordSet[0][0]
if ZoneStatus=="FALSE":
return (True)
def StartChimeThread():
try:
thread.start_new_thread(SoundChime, ())
except:
print "Error: unable to start thread"
def SoundChime():
if globals.ChimeDuration>0:
GPIO.setmode(GPIO.BOARD)
GPIO.setup(globals.ChimeGPIOPin, GPIO.OUT) #Siren pin setup
GPIO.output(globals.ChimeGPIOPin,True)
time.sleep(globals.ChimeDuration)
GPIO.output(globals.ChimeGPIOPin,False)
def GetDataFromHost(function,opcode):
# Request data and receive reply (request/reply) from the server
script_path = "https://www.privateeyepi.com/alarmhostr.php?u="+globals.user+"&p="+globals.password+"&function="+str(function)
i=0
for x in opcode:
script_path=script_path+"&opcode"+str(i)+"="+str(opcode[i])
i=i+1
if globals.PrintToScreen: print script_path
try:
rt = urllib2.urlopen(script_path)
except urllib2.HTTPError:
return False
temp=rt.read()
if globals.PrintToScreen: print temp
l = find_all(temp,"/n");
RecordSet = temp.split(',')
c=[]
y=0
c.append([])
for x in RecordSet:
if x=="/n":
y=y+1
if y < l:
c.append([])
else:
if isNumber(x):
c[y].append(int(x))
else:
c[y].append(x)
rt=ProcessActions(c)
if rt==False:
return(False)
else:
return(c)
return(c)
def BuildMessage(SensorNumber):
# Routine to fetch the location and zone descriptions from the server
RecordSet = GetDataFromHost(6,[SensorNumber])
if globals.PrintToScreen: print RecordSet
if RecordSet==False:
return
zonedesc=RecordSet[0][0]
locationdesc = RecordSet[0][1]
messagestr="This is an automated email from your house alarm system. Alarm activated for Zone: "+zonedesc+" ("+locationdesc+")"
return messagestr
def BuildMessageFromRule(SensorNumber, smartruleid):
RecordSet = GetDataFromHost(7,[smartruleid, SensorNumber])
if RecordSet==False:
return
numrows = len(RecordSet)
messagestr="This is an automated email from PrivateEyePi. Rule triggered for Zone(s): "+RecordSet[0][3]+", Location: "+RecordSet[0][4]+" and for rule "
for i in range(0,numrows,1):
if RecordSet[i][0]==1:
messagestr=messagestr+"Alarm Activated"
if RecordSet[i][0]==2:
messagestr=messagestr+"Alarm Deactivated"
if RecordSet[i][0]==3:
messagestr=messagestr+"Circuit Open"
if RecordSet[i][0]==4:
messagestr=messagestr+"Circuit Closed"
if RecordSet[i][0]==5:
messagestr=messagestr+"Open for " + str(RecordSet[i][1]) + " Minutes"
if RecordSet[i][0]==6:
messagestr=messagestr+"Closed for " + str(RecordSet[i][1]) + " Minutes"
if RecordSet[i][0]==7:
messagestr=messagestr+"Where sensor value (" + str(RecordSet[i][5]) + ") is between " + str(RecordSet[i][1]) + " " + str(RecordSet[i][2])
if RecordSet[i][0]==8:
messagestr=messagestr+"Tamper"
if RecordSet[i][0]==9:
messagestr=messagestr+"Day Of Week is between " + str(RecordSet[i][1]) + " and " + str(RecordSet[i][2])
if RecordSet[i][0]==10:
messagestr=messagestr+"Hour Of Day is between " + str(RecordSet[i][1]) + " and " + str(RecordSet[i][2])
if RecordSet[i][0]==11:
messagestr=messagestr+"Where secondary sensor value (" + str(RecordSet[i][6]) + ") is between " + str(RecordSet[i][1]) + " " + str(RecordSet[i][2])
if i<numrows-1:
messagestr=messagestr + " AND "
return messagestr
def SendEmailAlertFromRule(ruleid, SensorNumber, photo):
try:
thread.start_new_thread(SendEmailAlertThread, (SensorNumber, ruleid, True, photo, ) )
except:
print "Error: unable to start thread"
def SendEmailAlert(SensorNumber):
try:
thread.start_new_thread(SendEmailAlertThread, (SensorNumber,0 , False, False) )
except:
print "Error: unable to start thread"
def SendEmailAlertThread(SensorNumber, smartruleid, ruleind, photo):
# Get the email addresses that you configured on the server
RecordSet = GetDataFromHost(5,[0])
if RecordSet==False:
return
numrows = len(RecordSet)
if globals.smtp_server=="":
return
if ruleind:
msgtext = BuildMessageFromRule(SensorNumber, smartruleid)
else:
msgtext = BuildMessage(SensorNumber)
for i in range(numrows):
# Define email addresses to use
addr_to = RecordSet[i][0]
addr_from = globals.smtp_user #Or change to another valid email recognized under your account by your ISP
# Construct email
if (photo==1):
files = 0
files = glob.glob(globals.photopath)
latestphoto = get_latest_photo(files)
msg = MIMEMultipart()
else:
msg = MIMEText(msgtext)
msg['To'] = addr_to
msg['From'] = addr_from
msg['Subject'] = 'Alarm Notification' #Configure to whatever subject line you want
#attach photo
if (photo==1):
msg.preamble = 'Multipart message.\n'
part = MIMEText(msgtext)
msg.attach(part)
part = MIMEApplication(open(latestphoto,"rb").read())
part.add_header('Content-Disposition', 'attachment', filename=latestphoto)
msg.attach(part)
# Send the message via an SMTP server
#Option 1 - No Encryption
if globals.email_type==1:
s = smtplib.SMTP(globals.smtp_server)
elif globals.email_type==2:
#Option 2 - SSL
s = smtplib.SMTP_SSL(globals.smtp_server, 465)
elif globals.email_type==3:
#Option 3 - TLS
s = smtplib.SMTP(globals.smtp_server,587)
s.ehlo()
s.starttls()
s.ehlo()
else:
s = smtplib.SMTP(globals.smtp_server)
s.login(globals.smtp_user,globals.smtp_pass)
s.sendmail(addr_from, addr_to, msg.as_string())
s.quit()
if globals.PrintToScreen: print msg;
def SendCustomEmail(msgText, msgSubject):
# Get the email addresses that you configured on the server
RecordSet = GetDataFromHost(5,[0])
if RecordSet==False:
return
numrows = len(RecordSet)
if globals.smtp_server=="":
return
for i in range(numrows):
# Define email addresses to use
addr_to = RecordSet[i][0]
addr_from = globals.smtp_user #Or change to another valid email recognized under your account by your ISP
# Construct email
msg = MIMEText(msgText)
msg['To'] = addr_to
msg['From'] = addr_from
msg['Subject'] = msgSubject #Configure to whatever subject line you want
# Send the message via an SMTP server
#Option 1 - No Encryption
if globals.email_type==1:
s = smtplib.SMTP(globals.smtp_server)
elif globals.email_type==2:
#Option 2 - SSL
s = smtplib.SMTP_SSL(globals.smtp_server, 465)
elif globals.email_type==3:
#Option 3 - TLS
s = smtplib.SMTP(globals.smtp_server,587)
s.ehlo()
s.starttls()
s.ehlo()
else:
s = smtplib.SMTP(globals.smtp_server)
s.login(globals.smtp_user,globals.smtp_pass)
s.sendmail(addr_from, addr_to, msg.as_string())
s.quit()
if globals.PrintToScreen: print msg;
Your lcd.py module doesn't define any functions (or other top-level objects) named noDisplay or message, only a class named CharLCD and a function named DisplayLCD. So, when you try to import something that doesn't exist, of course you get an ImportError.
It's true that the CharLCD class has methods named noDisplay and message, but that doesn't mean you can just import them as top-level functions. (And, even if you could, you can't call them that way; you need a CharLCD object to call its methods.)
I suspect you need to read a basic tutorial on classes, like the Classes chapter in the official tutorial.
Meanwhile, I think the code you want is:
from lcd import CharLCD
# ...
char_lcd = CharLCD()
char_lcd.message("test with message")
time.sleep(5)
char_lcd.noDisplay()
(Also note the () in the last line. You need those parentheses to call a function or method; without them, you're just referring to the function or method itself, as a value, which has no more effect than just writing 2 on a line by itself.)