i want to communicate with 'TestEquity1000' temperature chamber by using 'pyserial' - python-3.x

i want to set and get temperature of serial device (testequity1000) by using pyserial but not able to communicate.
cable used RS232
python 3.7
import serial
port = 'COM20'
` serial_comunication = serial.Serial(port, baudrate=9600, timeout=1)
answer = serial_comunication.read(400)
print(answer)
NEW_TEMPERATURE=45
set_temp=serial_comunication.write(b'NEW_TEMPERATURE')
print(set_temp)
abc=serial_comunication.close()
print(abc)
results:
b''
15
None
can't understand these result

Your device seems to be able to communicate on the RS232 bus but you have to use Modbus instead of the raw serial.
Quoting from the manual:
The F4 Temperature Controller has an RS-232C interface. A DB-9
connector is located on the rear panel. It is wired to accommodate a
null-modem cable. To communicate with the controller from a PC, you
need to run software that uses the Modbus RTU protocol. Each
controller function has a “register” number which can be read or
written to (when applicable). These registers are listed Chapter Seven
of the “Series F4 User’s Manual”. RS-232C Modbus programming resources
and LabVIEW drivers can be downloaded from
http://chamber.testequity.com/rs232.html
Common Modbus Registers
-Actual chamber temperature reading is register 100 (Input 1 Value).
-Actual chamber humidity reading is register 104 (Input 2 Value).
-Static temperature set point is register 300 (Set Point 1).
-Static humidity set point is register 319 (Set Point 2). •
-Temperature set point during a profile is register 4122 (Set Point 1, Current Profile Status).
-Humidity set point during a profile is register 4123 (Set Point 2, Current Profile Status).
-Decimal points are implied. For example, 1005 is actually 100.5 and -230 is -23.0.
Based on these details you can use pymodbus instead. A good starting point is this example.
You can install the package with: pip install pymodbus
So, if you want to read the Actual Chamber Temperature you need to write something similar to this:
#!/usr/bin/env python
# Pymodbus Synchronous Client Examples
# --------------------------------------------------------------------------- #
# import the various server implementations
# --------------------------------------------------------------------------- #
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
# --------------------------------------------------------------------------- #
# configure the client logging
# --------------------------------------------------------------------------- #
import logging
FORMAT = ('%(asctime)-15s %(threadName)-15s '
'%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)
UNIT = 0x1
# ------------------------------------------------------------------------#
# choose the client you want
# ------------------------------------------------------------------------#
client = ModbusClient(method='rtu', port='COM20', timeout=1, baudrate=19200)
client.connect()
# ----------------------------------------------------------------------- #
# example requests
# ----------------------------------------------------------------------- #
rr = client.read_holding_registers(100, 1, unit=UNIT) #Actual chamber temperature reading
print(rr.registers[0])
# ----------------------------------------------------------------------- #
# close the client
# ----------------------------------------------------------------------- #
client.close()
You might need to change the default baudrate (according to the manual 19200) and/or the Modbus UNIT ID (UNIT 1 is the default value).

Hello I actually just finished using a little something in python. TestEquity chamber for the RS-232 you need to use modbus RTU protocol.
I'm using minimalmodbus. The other thing is that you need to make sure that you are using a null modem Tx and Rx need to be swapped in the DB9 connector.
Check the baudrate and slave address in setup, communications.
My code is here:
import minimalmodbus
TE1007C = minimalmodbus.Instrument("COM5", 1)
# Set baudrate
TE1007C.serial.baudrate = 9600
temp = TE1007C.read_register(100, 1, signed=True)
print(temp)
To set a temperature use write_register(). There are other registers that can be use.

Related

Serial Communication with ASCII Commands in Python

Hello guys I am attempting to write ASCII commands & in return read the serial buffer & get serial data. I am having an issue parsing the serial data out to only read the serial data I want to see and use.
The Code:
import serial
# Serial Connection
ser = serial.Serial(
port="COM2", baudrate = 38400,
parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS, timeout=1)
# Write ASCII Commands To TSI 4043 Flow Sensor
ser.write(b'?\r\n') # Ask Sensor if it is getting a signal (Returns "OK")
ser.write(b'SUS\r\n') # Set Flow type to SLPM (Returns "OK")
ser.write(b'SG0\r\n') # Set Flow Gas to Air (Returns "OK")
ser.write(b'SSR0010\r\n') # Set Sample Rate to 10ms (Returns "OK")
ser.write(b'DAFxx0010\r\n') # Read 10 sensor Flow Reading
# Read ASCII From Serial Buffer
output = ser.read(100) # Read 100 bytes from serial buffer
print(output)
OUTPUT:
b'OK\r\nOK\r\nOK\r\nOK\r\nOK\r\n80.63,80.42,80.52,80.32,80.33,80.66,79.88,80.39,80.26,80.28\r\n'
What I want to happen:
OK
OK
OK
OK
80.63,80.42,80.52,80.32,80.33,80.66,79.88,80.39,80.26,80.28
The OKs are just for debugging purposes. What I really need is to put all of the flow readings into an array so I can average it so I can watch the change in real time and control a motor.
You should change Your approach a bit.
Read from serial port after every ser.write and parse / process it's output.
Check if You actually receive b'OK\r\n' response from the device and make sure You comply with Device communication protocol (what are possible outputs for every command You send). You never know when Device throw an error while processing the command.
Like this You will already have communication in a way WRITE command => READ output for every command You send.
Then it comes to the part of flow readout. You should have just b'80.63,80.42,80.52,80.32,80.33,80.66,79.88,80.39,80.26,80.28\r\n' in Your output.
You can process it and get average with:
# Output value from DAFxx0010 command
output = b'80.63,80.42,80.52,80.32,80.33,80.66,79.88,80.39,80.26,80.28\r\n'
# Decode bytes to string, remove `\r\n`, split by ',' and convert values to float and save them into list
output_values = [float(val) for val in output.decode().strip().split(",")]
# Average all values
output_avg = sum(output_values) / len(output_values)
Now You have clean communication with Device and Your script can handle possible communication errors.

Trouble sending data from Matlab to Python via serial port

to better understand serial port communication, I am trying to write some sample code, where Matlab has a loop running, which continously sends data to a serial port, while a Python script running on the same windows machine listens to this port, then receives and prints any received data.
In Matlab, I have written a simple loop, which sends 99 test signals to Port COM1,
% Setup a serial port and open it
tep=serial("COM1", "Baudrate", 9600);
fopen(tep);
% this loop is supposed to send a number to a serial port repeatedly
n = 1; % counter variable
while n < 100
fprintf(tep,"50"); % Send data to serial port
n = n + 1; % Counter variable
pause(0.5) % Sleep to make this loop run for a total of 50s0
fprintf('run'); % Test output within matlab to check, whether it runs
end
% finally close the serial port
fclose(tep);
as far as I can tell, this Matlab part works, as it prints "run" every hald second.
The Python listener:
import serial
import time
# set up the serial line same as in Matlab
ser = serial.Serial('COM1', 9600)
time.sleep(2)
# Read and record the data
data =[] # empty list to store the data
for i in range(50):
b = ser.readline() # read a byte string
string_n = b.decode() # decode byte string into Unicode
string = string_n.rstrip() # remove \n and \r
flt = float(string) # convert string to float
print(flt)
data.append(flt) # add to the end of data list
time.sleep(0.1) # wait (sleep) 0.1 seconds
ser.close()
# show the data
for line in data:
print(line)
Running the script in Python results in the following error:
serial.serialutil.SerialException: could not open port 'COM1': PermissionError(13, 'Zugriff verweigert', None, 5)
Obviously the port is already in use by Matlab, as it sends information to it, but I don't understand, why that is a problem. Shouldn't it be fine, for one program to send data to it and for another to receive data from it?
Kind regards.
I'm afraid you cannot connect to the same serial port from two different processes.
That means if you open the serial port from Matlab for writing you cannot open it from Python to read.
The serial port is intended to send data from a computer to another computer or device not to share data between different applications (to do that there are better ways like writing to a file or to a chunk of shared memory).
Having said that, if what you are trying to do is for debugging purposes or just learning you might want to investigate com0com which allows you to create a pair of virtual (software) serial ports. This would be the same as having a couple of hardware (real) serial ports wired to each other. Since now you have two ports you can send data from Matlab on one and read from Python on the other.
This is one of the most recurring questions about serial ports, so you should be able to find a lot of good resources. You might want to start here.

Relay control with Raspberry Pi and Python3

below is a section of code I am using to control a relay to open electric gates via a relay which is controlled via pin 7 on a raspberry pi GPIO. The gates only need a momentary voltage (via the relay contacts) to open.
My question is, what do I need to add to this code to make the relay only switch on for 0.5 Seconds when pin 7 goes high. This would enable relay to return to the off state and then wait for the next time GPIO pin 7 goes high, the gates do not need any commands from the GPIO to close after a certain time, they close under the control of the separate gate control system.
if name=="gate":
GPIO.setmode(GPIO.BOARD) ## Use board pin numbering
GPIO.setup(int(7), GPIO.OUT) ## Setup GPIO Pin to OUTPUT
GPIO.output(int(7), state) ## State is true/false
Many thanks
Peter
In this example I will use gpiozero library instead of RPi.GPIO because I like the way, how this library handle events.
from gpiozero import Button, OutputDevice
from time import sleep
from signal import pause
buttonPin = 4
relayPin = 7
button = Button(buttonPin)
button.when_pressed = ButtonPressedCallback
relay = OutputDevice(relayPin)
def ButtonPressedCallback():
relay.on()
sleep(0.5)
relay.off()
pause()
I hope, I understood your question good.

RPi.GPIO pins - check state

I'm using the RPi.GPIO module in Python to turn on and off GPIO pins on the Raspberry Pi 3.
Is there a way to identify whether an output pin is ON or OFF and put that value into a variable that I can use to decide whether the pin is ON and needs to turn OFF, or is OFF and needs to turn ON.
from the docs
The code below should provide the functionality you are looking for.
import RPi.GPIO as GPIO
channel = 11
GPIO.setmode(GPIO.BCM)
# Setup your channel
GPIO.setup(channel, GPIO.OUT)
GPIO.output(channel, GPIO.LOW)
# To test the value of a pin use the .input method
channel_is_on = GPIO.input(channel) # Returns 0 if OFF or 1 if ON
if channel_is_on:
# Do something here

GPIO interrupt triggered by different pin

tl;dr:
Listening to a RISING event on GPIO PIN14 (with 10K pulldown resistor); Ghost RISING events when sending/receiving data on different GPIO pin;
I have the following issue:
In my technical room I have a Raspberry Pi 1B, and Raspberry Pi 3; I tested this on both units and I get the same results;
My mains meter has a flashing LED, 1000/kWh; I want to measure this using a photo resistor; The photo resistor is connected to GPIO PIN14; This setup works just fine, as long as I don't use any of the other GPIO pins.
Using the same unit I want to send some data over 433Mhz (GPIO PIN7, but as soon as I transmit data, I get RISING events on PIN14...
Across the internet I found different solutions, none of which seem to be working:
Use a different Raspberry Pi (B1 is a tad bit old)
Use a 10K pull down resistor on PIN14
Use a different power supply
Use separate power supplies for the raspberry pi, photo resistor, and 433Mhz transmitter
Using the code below, I can see expected behavior of the photo resistor and PIN14; But as soon as I startup the transmissions, the events of sending a message and RISING events on PIN14 synchronize. When I stop sending messages the listener on PIN14 stops working.
Does anyone have any idea how to fix this?
PIN14 Listener code:
import datetime
import time
try:
import RPi.GPIO as GPIO
except RuntimeError:
print(
'Error importing RPi.GPIO! This is probably because you need superuser privileges.')
delta = datetime.timedelta(microseconds=100000)
global last_electric_ping
last_electric_ping = datetime.datetime.now()
GPIO.setmode(GPIO.BCM)
GPIO.setup(14, GPIO.IN)
def electric_ping(channel):
if GPIO.input(14):
global last_electric_ping
now = datetime.datetime.now()
if delta + last_electric_ping <= now:
print(delta + last_electric_ping, end=" ")
print('ELECTRIC')
last_electric_ping = now
GPIO.add_event_detect(14, GPIO.RISING, callback=electric_ping)
while True:
continue
GPIO.cleanup()
Transmission code:
import time
from pi_switch import RCSwitchSender
sender = RCSwitchSender()
sender.enableTransmit(15) # use WiringPi pin 0
num = 1
while True:
time.sleep(1)
print("Woei!")
sender.sendDecimal(num, 24)
num += 1
Roll the drums:
Apparently I ran into a numbering issue; The BCM pin numbering says physical pin 8 is GPIO14, which is nice;
Now three guesses which number wiringPi gives to physical pin number 8... yes, number 15! Which is the one I'm trying send data to in the second script;
Now excuse while I go slap myself with a brick in the corner over there...

Resources