i am new to python, i am using 2.7 with spyder
i have an anduino style board running this:
void setup() {
Serial1.begin(115200);
}
void loop() {
Serial1.write(0x80);
}
on my laptop i am not able to read the incoming data neither i am able to assing it to a variable:
# -*- coding: utf-8 -*-
import serial
print (serial.__version__)
#3.4
ser = serial.Serial(
port='/dev/ttyUSB1',
baudrate=115200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout = None
#timeout = 1
)
while 1:
print ser.read()
a = ser.read()
print a
i really don't understand what i am doing wrong, when i try to assign ser.read() to "a" spyder crash
i just would like to read the incoming hex value
solved it with this:
print hex(int(a.encode('hex'), 16))
i hope it could be usefull
now i am trying to understand why pyserial crashes so often
edit: upgrading to python 3.x solved all the crashed with pyserial
and also the sintax became more clear
in_bin = ser.read()
in_hex = hex(int.from_bytes(in_bin,byteorder='little'))
This way also works:
in_hex = ser.read().hex()
Related
I’m trying to send ASCII characters from an NVIDIA Jetson nano to a Roboteq motor controller. (MAX3232 to convert the logic level)
Using Pyserial for serial comm.
Sending 3 variable values for motor control, eg: ‘!VAR 1 250’ (‘!’ Is the start of the command)
Following is a snippet of the code,
import time
import serial
ser = serial.Serial(
port = '/dev/ttyTHS1',
baudrate = 115200,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
bytesize = serial.EIGHTBITS,
timeout = 1
)
command = ‘!VAR 1 250’ + ’ \r’
ser.write(command.encode())
data =
ser.readline().decode().strip()
print(data)
Coming to the issue,
‘!VAR 1 250’ does not pass the same value when sent every time.
Data string gets corrupted.
Is this because I am sending the ASCII command the wrong way? Is it being transferred in bytes?
I feel I am missing something here. How do we send an ASCII string via pyserial?
i am writing the data in eeprom of nodemcu esp8266 12e but their is error in writing data. after restarting the board the value is lost again not store for long . help to solve this issue.
when i am writing the data in eeprom on board the data is write in eeprom but after restarting the board the value will lost.
memcpy (msg,message.payload,message.payloadlen);
Serial.print(msg);
int compare = 1;
if (0==(compare=(strncmp("ON",msg,4)))) {
val = 1 ;
digitalWrite(LED,HIGH);
EEPROM.write(addr,val);
compare = 1;
}
else if (0==(compare=(strncmp("OFF",msg,4)))) {
val = 0 ;
digitalWrite(LED,LOW);
EEPROM.write(addr,val);
compare = 1;
}
So, the ESP8266 does not actually have an EEPROM. The authors of the Arduino SDK instead map out a small section of flash (You can find the actual size in the linker scripts) to be used for the virtual EEPROM.
When you call EEPROM.write(addr, x), it stores the data in a shadow copy of the virtual-EEPROM, but, does not store it in flash until EEPROM.commit(); is called.
Recently, I've been writing an Arduino(Yún) sketch to get RGB values(0-255) from the bridge. I have Bridge.begin() in the setup and the following in the loop:
Bridge.get("r", r, 4);
Bridge.get("g", g, 4);
Bridge.get("b", b, 4);
Which should get the value from the bridge(1st argument) and set the local variable to it(2nd argument). The local variables r, g and b are defined with char r[4];(obviously each with the appropriate name). I understand all of this, however there is a problem:
The first Bridge.get() call always returns \u0001(Start of heading). I have solved this by adding a dummy bridge get to the beginning of the loop, however this seems weird to me because the first call returns the "Start of heading" in every loop.
Why is this and is there a better way to fix it?
EDIT:
The code is put to the bridge by a python script running on the Linux side of the Yún. The following is shortened because the code that works out the RGB values is fairly long, messy and shouldn't be part of the problem(famous last words :D).
#!/usr/bin/python
from sys import path
path.insert(0, '/usr/lib/python2.7/bridge')
from bridgeclient import BridgeClient
link = BridgeClient()
link.put("r", str(int(r)))
link.put("g", str(int(g)))
link.put("b", str(int(b)))
The arduino code(once again abridged) is as follows:
#include <Process.h>
char r[4];
char g[4];
char b[4];
void setup() {
Bridge.begin();
}
void loop() {
Process colo;
colo.runShellCommand("/mnt/sda1/colours.py");
while (colo.running());
Bridge.get("r", r, 4); //this command(whatever key it’s getting) always returns \u0001
Bridge.get("r", r, 4);
Bridge.get("g", g, 4);
Bridge.get("b", b, 4);
}
So I'm trying to make a lighting system for my computer, I wanted to write the GUI and whatnot within Python and handle all the controlling of lights and stuff with the Arduino. After some research PySerial seemed like the easiest to use and understand being a beginner myself. I honestly have no idea what I'm doing here and I'm getting errors that I can't diagnose, and Google is not helping whatsoever.
Here is the code I have running in python now:
import serial
ser = serial.Serial('COM8', 9600) # Establish the connection on a specific port
while True:
numIn = str(input("Enter a Color value: "))
ser.write(numIn)
print (ser.readline())
On the Arduino side I have:
void setup ()
{
Serial.begin (9600);
Serial.println ("Ready\n\n");
}
void loop ()
{
int intensity = 0;
while (Serial.available() == 0)
while (Serial.available() > 0)
{
char byteIn = Serial.read();
intensity += int(byteIn) - '0';
Serial.print(byteIn);
}
}
Through Python I'd be sending a value between 0 - 255, That number should be being saved as a string and then be sent to the Arduino which would then create an integer character by character. For debugging reasons I wanted to echo back the string to Python but I haven't gotten my code to run that far yet. There is something up with the way I'm trying to send the data from Python to the Arduino, this is the Trace back I am getting:
Enter a Color value: 25
Traceback (most recent call last):
File "C:\Users\Squirrelzar\Documents\Python Proj\Arduino Serial Testing.py", line 10, in <module>
ser.write(numIn)
File "C:\Python34\lib\site-packages\serial\serialwin32.py", line 283, in write
data = to_bytes(data)
File "C:\Python34\lib\site-packages\serial\serialutil.py", line 76, in to_bytes
b.append(item) # this one handles int and str for our emulation and ints for Python 3.x
TypeError: an integer is required
Im using Python 3.4 with PySerial 2.7
Any help would be greatly appreciated..I am so lost..
You can send from python the integer value as a string, and read it directly in Arduino as integer using Serial.parseInt(). The next code works for me (linux, python 2.7):
Python:
import serial
ser = serial.Serial('/dev/ttyACM1', 9600)
print (ser.readline())
while True:
numIn = raw_input("Enter a Color value: ") # Returns the value as string
ser.write(numIn)
msg = ser.readline()
print (msg)
Arduino:
void setup ()
{
Serial.begin (9600);
Serial.print ("Ready\n");
}
void loop ()
{
while(Serial.available())
{
int inNumber = Serial.parseInt(); # retunrs the first valid long integer buffered
Serial.print(inNumber);
Serial.print('\n');
}
}
A comment, if you send Serial.println ("Ready\n\n"); you have to read all the new-line characters before reading other data
I have just downloaded the latest Arduino Library code from Github, and it's broken my MQTT client program. I'm using PubSubClient 1.91 on Arduino, and Mosquitto 1.1.2 (Build 2013-03-07) on Mac OSX. (I also tested against Mosquitto on Windows 7, same problem.)
The supplied Mosquitto clients work fine, (Mac over to Windows, Windows over to Mac) so it's some problem with what's coming from the Arduino end. A wireshark trace shows the Arduino client sending the following data packet:
10:15:ff:ff:4d:51:49:73:64:70:03:02:00:0f:00:07:41:72:64:75:69:6e:6f
And the Mosquitto broker shows:
New connection from 10.0.0.115
Socket read error on client (null), disconnecting.
Before I start to crawl through the MQTT spec, can anyone see anything wrong with the data packet being sent? It's got to be something to do with new Arduino library code...
* Update
Upon further investigation, it appears to be a code generation problem with avr-g++, although life experience tells me it will turn out not to be so. Here is a snippet of code from PubSubClient.cpp
boolean PubSubClient::connect(char *id, char *user, char *pass, char* willTopic, uint8_t willQos, uint8_t willRetain, char* willMessage) {
if (!connected()) {
int result = 0;
if (domain != NULL) {
result = _client->connect(this->domain, this->port);
} else {
result = _client->connect(this->ip, this->port);
}
if (result) {
nextMsgId = 1;
uint8_t d[9] = { 0x00, 0x06, 'M','Q','I','s','d','p',MQTTPROTOCOLVERSION};
// d[0] = 0;
// d[1] = 6;
Serial.print("d[0]="); Serial.println(d[0],HEX);
Now, the result of the Serial.print just above turns out to be 0xFF !!! So, the uint8_t array is not being initialised correctly. #knoleary Your pointer to the bad FF bytes lead me to this.
If I now uncomment the two lines above, and manually initialise the first 2 bytes to 0 and 6, all works fine, and my program communicates happily with Mosquitto.
I've looked at the generated code, but I'm not an Atmel expert.
Does anyone have any clue why this might be?
I'm compiling using the AVR-G++ toolset from Arduino 1.05, in Eclipse.
I'm going for a beer!
OK, I found it. It's a relatively subtle bug. Essentially, when the following line of source code is compiled;
uint8_t d[9] = { 0x00, 0x06, 'M','Q','I','s','d','p',MQTTPROTOCOLVERSION};
the 9 bytes get stored as a constant in the data section of the image. At runtime, a small loop copies the 9 bytes into the array (d[]) By looking at a combined Assembler / source listing, I could see where in the data section the 9 bytes were stored, and then print them out at regular intervals, until I found what was over-writing them. (A bit primitive, I know!)
It turns out the there's a bug in WiFi.cpp , the Arduino WiFi code. Here's the code:
uint8_t WiFiClient::connected() {
if (_sock == 255) {
return 0;
} else {
uint8_t s = status();
return !(s == LISTEN || s == CLOSED || s == FIN_WAIT_1 ||
s == FIN_WAIT_2 || s == TIME_WAIT ||
s == SYN_SENT || s== SYN_RCVD ||
(s == CLOSE_WAIT));
}
}
It turns out the the _sock variable is actually initialised like this:
WiFiClient::WiFiClient() : _sock(MAX_SOCK_NUM) {
}
and MAX_SOCK_NUM is 4, not 255. So, WiFiClient::status returned true, instead of false for an unused Socket.
This method was called by the MQTT Client like this:
boolean PubSubClient::connected() {
boolean rc;
if (_client == NULL ) {
rc = false;
} else {
rc = (int)_client->connected();
if (!rc) _client->stop();
}
return rc;
}
And, since the _client->connected() method erroneously returned true, the _client_stop() method was called. This resulted in a write to a non-existent socket array element, and so overwrote my string data.
#knolleary, I was wondering, is there any specific reason that your PubSubClient::connected() method does a disconnect? I use the ::connected method in a loop, to check that I'm still connected, and, of course it results in my getting a disconnect / reconnect each time round the loop. Any chance we could just make connected return true / false , and handle the disconnect in PuBSubClient::connect?
Nearly one and a half year later I ran into the same problem. Removing the
boolean PubSubClient::connected() {
int rc = (int)_client->connected();
if (!rc) _client->stop();
return rc;
}
the _client->stop() from the connected method of PubSubClient forehand fixed this problem for me. However, I'm not sure whether this is actually a solution or just a very dirty quick hack to localize the problem.
What have you done to fix this problem - your explanation of the problem above is fine however, I was not able to extract the solution easily ;-)