I am trying to capture my temperature sensor reading from Arduino Uno, turn on AC if temperature is high or off and then send temperature to Raspberry Pi and write to a log file.
My Python code in Raspberry Pi to capture event and log to a file.
import time
import datetime
import serial
now = datetime.datetime.now()
month=time.strftime("%Y_%m")
#f= open(month+".txt","w+")
f=open("temperature.log","w+")
ser = serial.Serial('/dev/ttyACM0', 9600) # enable the serial port
print 'before while'
while 1: # execute the loop forever
val=ser.readline()
# read the serial data sent by the UNO
f.write(now.strftime("%Y-%m-%d %H:%M"))
# print the serial data sent by UNO
f.write(' -> ')
f.write(val)
f.close()
I can get the temperature value (sometimes it's a mess 16707), but most importantly it does not write to the log file.
Where am I missing? Do I have to include another library in the Python code?
You are closing the log file at the end of each loop. It should run once, but after the file is closed, it won't write again until you open it. Just put f.close() after the while loop. Or as a better practice:
ser = serial.Serial('/dev/ttyACM0', 9600)
with open("temperature.log", "w+") as f:
print 'before while'
while 1:
val = ser.readline()
f.write(now.strftime("%Y-%m-%d %H:%M"))
f.write(' -> ')
f.write(val)
This will close the file automatically once the code inside the with statement is finished.
Related
I am trying to make a program which constantly reads data being sent from device using serial port to computer. In addition to this whenever I enter something it is sent to device.(My main aim is to make a serial terminal emulator).
I wrote following program but it waits for any input and does not constantly read data and display on screen sent by device as thought:
ser1 = serial.Serial(com_name_to_use, auto_baud, timeout=0, write_timeout=0)
while True:
try:
# Writing Section
inp_str1 = input() # + "\n"
str1 = inp_str1.encode(encoding="ascii")
ser1.write(str1)
time.sleep(0.03)
# Reading Section
bf = ser1.readline()
print(str(bf, encoding="utf-8"), end="")
except Exception as err1:
pass
Kindly, tell how to fix it.
I have a very small and simple python script on my raspberry, it works well for as long as there is an active Wi-Fi connection. The raspberry is connected to a mobile hotspot and it's possible it will lose it's connection as it could get out of range. As soon as this happens it throws an exception and ends the request "while" loop.
I was hoping to get more information to how i can make this script pause or "ignore" the exception so it goes back into the loop as soon as the connection is restored.
import urllib
import serial
from time import sleep
link = "http://myurl/"
while True:
f = urllib.urlopen(link)
myfile = f.read()
print myfile
ser = serial.Serial('/dev/ttyUSB0', 9600)
ser.write(myfile)
sleep(3)
You can try something called, (obviously) a try statement!
Within your while loop, you can use a try: except block to make sure that even if your code does't execute (your pi loses connection or something else weird happens) you won't end the program!
This type of code would look like this:
import urllib
import serial
from time import sleep
link = "http://myurl/"
while True:
try:
f = urllib.urlopen(link)
myfile = f.read()
print myfile
ser = serial.Serial('/dev/ttyUSB0', 9600)
ser.write(myfile)
sleep(3)
except:
sleep(3) #If the code executed in the try part fails, then your program will simply sleep off 3 seconds before trying again!
My raspberry pi is connected to microcontroller over serial pin. I am trying to read the data from the serial port. The script reads the data for few seconds. However, it terminates throwing following exception
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected?)
I have used following python code
#!/usr/bin/python
import serial
import time
serialport = serial.Serial("/dev/ttyAMA0", 115200, timeout=.5)
while 1:
response = serialport.readlines(None)
print response
time.sleep(.05)
serialport.close()
Here is the code you should be using if you are seriously trying to just transfer and print a file:
for line in serialport.readlines().split('\n'):
print line
------------------------------------------------------------
I believe you are having problems because you are using readlines(None) instead of readline() Readline() reads it a line at a time, and will wait for each one. If reading a whole file it will be slower than readlines. But readlines() expects a whole file all at once. It is obviously not waiting for your serial transfer speed.
--------------------------------------------------
My data-logging loop receives a line every two minutes and writes it to a file. It could easily just print each line like you show in the OP.
readine() waits for each line. I have tested it to wait up to 30 minutes between lines with no problems by altering the program on the Nano.
import datetime
import serial
ser = serial.Serial("/dev/ttyUSB0",9600) --/dev/ACM0 is fine
while True :
linein = ser.readline()
date = str(datetime.datetime.now().date())
date = date[:10]
time = str(datetime.datetime.now().time())
time = time[:8]
outline = date + tab + time + tab + linein
f = open("/home/pi/python/today.dat","a")
f.write(outline)
f.close()
Maybe changing to this approach would be better for you.
I am trying to communicate an Arduino using python. I was able to connect it using the serial module. This is the code:
import serial
while True:
print "Opening port"
arduinoData = serial.Serial("com7", 9600)
print "The port is open"
while (arduinoData.inWaiting()==0): #I wait for data
print "There is no data"
print "Reading data"
arduinoString = arduinoData.readline()
print arduinoString
It seems that is hanging when I want to read the data, in the line that says arduinoString = arduino.readline().
What could be the problem?
instead using the while loop inside of the main while loop you can use an if else statement. Also, to read the data you can use the read function with arduinoData.inWaiting() as the paramater like this : arduinoData.read(arduinoData.inWaiting()). I hope this code will help you:
arduinoData = serial.Serial("com7", 9600)
while True:
if arduinoData.inWaiting() > 0: # check if there is data available
print "Reading data"
arduinoString = arduinoData.read(arduinoData.inWaiting()) '''read and decode data'''
print arduinoString
else:
print "There is no data"
The structure of your code is strange. I had a similar issue by creating the Serial object in a function without making it global. Maybe you should put this line outside the loop :
arduinoData = serial.Serial("com7", 9600)
Also, your initialization seems a bit light. I usually use more parameters but it depends of your hardware.
ser = serial.Serial(
port = 'com4', \
baudrate = 19200, \
parity=serial.PARITY_NONE, \
stopbits=serial.STOPBITS_ONE, \
bytesize = serial.EIGHTBITS, \
timeout = 0.25)
A workaround for your readline() issue coud be using the read() function instead and checking if it contains data.
Hope it will help !
Alright, you are getting the AttributeError: 'Serial' object has no attribute 'ser' error because in reality ser does not exist in the arduinoData object. It's my fault because I was thinking of the class that I created in my program containing ser which is just the another serial object. To fix this just replace arduinoData.ser with arduinoData
To add on, you should probably declare arduinoData outside of the while loop. you should do this because every time the you create a serial object it takes time to connect to the Arduino. For this, your program might not be able to read the data.
I hope this answer will help you.
I have the following program of python which displays serial data in the command prompt.
#!python
import time
import cgi
from serial import Serial
import subprocess
ser = Serial('COM4', 115200, timeout=1)
print("connected to: " + ser.portstr)
while True:
# Read a line and convert it from b'xxx\r\n' to xxx
line = ser.readline().decode('utf-8')[:-2]
if line: # If it isn't a blank line
print(line)
if line == '520':
subprocess.call(["xte", "key Up"])
elif line == '620':
subprocess.call(["xte", "key Down"])
elif line == '110':
break
ser.close()
This program is running perfect. The data is being constantly displayed in the console. Basically it is displaying the distance from a ping sensor I want to display the data in the web page http://localhost/distance.html. How will I do it? Displaying only the last data will be fine. Thanks for all the suggestions
Write the data to a file. Serve that file with a webserver like for example Apache.