python arduino usb communication - python-2.7

I'm trying to move data from Python to Arduino nano, but I can't see anything on the console on the Arduino side, but when
I tried to move data from Arduino to python, it worked very well.
Follow my codes below:
arduino code
void setup() {
Serial.begin(9600);
}
void loop() {
if(Serial.available() > 0) {
char data = Serial.read();
char str[2];
str[0] = data;
str[1] = '\0'
Serial.print(str);
}
}
python code
import serial, time
arduino = serial.Serial('COM3', 9600, timeout=.1)
time.sleep(1) # give the connection a second to settle
arduino.write("Hello from Python!")
while True:
data = arduino.readline()
if data:
print data.rstrip('\n') # strip out the new lines

The Arduino is using print, the Python is using readLINE.. Readline reads until it finds a '\n' the arduino is never sending a '\n'.'
Replace \0 in the sketch with \n and it should work.
It's always useful to test using the serial monitor and seeing what happens, if this doesn't work then please try sending some data using the serial monitor and let us know the results.

The problem may be that you have set too little time after connecting to the COM port.
try this
time.sleep(5) # give the connection 5 seconds to establish

Related

Serial read, collate, write AT commands

This is most probably a software question, not sure where to post this (Arduino sub? electronics sub?).
I have an Arduino Mega, that is connected to :
an RFID card read via SPI,
a wifi chip (esp8266-12f) via Serial1.
The wifi chip currently acts as a web Server as I intend to send commands to it via the internet. I also want that wifi chip to act as a Client, that is to say : when the RFID reads a card, I want the Arduino Mega to forward the RFID's card id to the wifi chip via Serial1 so that the wifi chip can send an http request to a dedicated server that would save it into sql database.
This is how I coded it on the wifi chip so far :
// esp as a Server
// [...]
// esp as a Client
timeout = millis() + (10 * 1000UL); // 10s
String input;
while (Serial.available() >= 0 && millis() < timeout) {
input += Serial.readStringUntil('\r');
int pos = input.indexOf("AT+TEST");
if (pos >= 0) {
Serial.println(F("AT+TEST"));
// collate, aka confirm to Arduino Mega we understood the command and we are processing it
// todo: process the command, aka parse the command, send an http request, etc
Serial.println(F("\r\nOK"));
} else {
Serial.println(F("\r\nNOPE"));
}
}
As you might have guessed, the chip is printing "AT+TEST" over and over again (until it times out, then loops infinite NOPE), as it is trying to process the command over and over, but I just want it to say "ok Arduino Mega, I understood you want me to execute AT+TEST"
What would be an elegant way to make it so that the wifi chip "ignores" the stuff it itself prints to it's own serial? It should only execute commands coming from the Arduino Mega.
This is something the factory default firmware does very well : when I send "AT", it echoes back "AT\r\n\r\nOK" only once.
I found this but I cannot understand how they implemented the idea (irrelevant code everywhere) : https://github.com/JiriBilek/ESP_ATMod/blob/d6ad63f71ef3189518ef4740f16a9d697c3e843a/ESP_ATMod/ESP_ATMod.ino#L581
Looking for guidance on a solid way to achieve this as there are lots of datas coming in and out to that serial of the wifi chip.
It looped because of the Line Feed. Not only that, it also needed a 1ms delay somehow.
Sorry for the poor explanation of my issue.
The following works as I expected :
// esp as a client
String input;
timeout = millis() + (5 * 1000UL); // 5s
while (Serial.available() && millis() < timeout) {
input = Serial.readStringUntil('\r'); // up to CR
delay(1); Serial.read(); // discard LF
// collate
Serial.println(input);
// AT+TEST
if (input.indexOf("AT+TEST") >= 0) {
Serial.println(F("\r\nOK"));
// todo : verbose for debug
}
// AT+GET=https://arduino.example.tld/api/arduino.php?token=123&key1=val1
else if (input.indexOf("AT+GET") >= 0) {
Serial.println(F("\r\nOK"));
// todo : regex + http get req
} else {
Serial.println(F("\r\nERROR"));
}
}

Arduino not taking multiple commands

I'm trying to get the basics done with my Arduino, and thus I'm starting off small.
That said, I want the Arduino to listen for simple, multiple commands being sent from my Raspberry Pi (I'm emulating this through the serial monitor now, however)
This is the code I'm working with:
#include "SoftwareSerial.h"
void setup()
{
Serial.begin(9600);
delay(100);
}
void loop() {
if (Serial.find("test1")) {
delay(100);
Serial.println("TEST1 command received");
}
if (Serial.find("test2")) {
delay(100);
Serial.println("TEST2 command received");
}
}
}
Sadly, only the test1 command triggers a serial print response, test2 no. Can anyone here help point me in the right direction?
Thank you!
From reading the documentation, I don't think you can use the find() function like that.
Consider what happens if test2 is input, when the find("test1") call is running. It will probably consume all characters up to and including the 2, and then return false, at which point those characters are lost.
I think you should design an actual protocol, with some delimiter between commands, and read/parse those.

Send a signed integer as a byte via serial in c++ and Arduino read it

I could send a String via serial, but Arduino reads String very slow. Therefore, I use reading byte in Arduino, but the problem is I don't know how to send a number (<256) as a byte via Serial Port in C++.
If you open up the Arduino IDE, under the menu, look at:
File > Examples > 08.Strings > CharacterAnalysis
Here I think you'll find something very close what you're looking for. To sum up, it opens a Serial connection (USB) and reads input from the computer. (You'll need to make sure you match the baud rate and use the "send" button.) It's up to you do program the Arduino as you'd like. In the example's case, it simply sends feedback back to the the Serial Monitor. Run it for yourself and see what happens :)
A [MCVE] snippet from the example:
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// send an intro:
Serial.println("send any byte and I'll tell you everything I can about it");
Serial.println();
}
void loop() {
// get any incoming bytes:
if (Serial.available() > 0) {
int thisChar = Serial.read();
// say what was sent:
Serial.print("You sent me: \'");
Serial.write(thisChar);
}

XBee PRO S1 always gets response with API MODEM_STATUS_RESPONSE instead of nothing

My wiring is this:
XBee is configured in API mode 1 and mbed (LPC1768) runs this code:
Serial terminal(USBTX, USBRX);
wait_ms(1000);
while(!terminal.readable()) {
wait_ms(10);
}
terminal.getc();
mbed_led1 = 1;
while(1) {
xbee.readPacketUntilAvailable();
terminal.puts("Packet available\r\n");
XBeeResponse response = xbee.getResponse();
if (response.isAvailable()) {
char tmp[20];
int c = response.getApiId();
sprintf(tmp, "%d", c);
terminal.puts("Response available at API: ");
terminal.puts(tmp);
terminal.puts("\r\n");
if (response.getApiId() == RX_16_RESPONSE) {
Rx16Response rx16 = Rx16Response();
response.getRx16Response(rx16);
uint8_t len = rx16.getDataLength();
char l[20];
sprintf(l, "%d", len);
terminal.puts("We have data: ");
terminal.puts(l);
terminal.puts("\r\n");
}
}
wait(1);
}
XBee library for mbed is essentially a port of a widely popular Arduino XBee library. Sources are here: http://mbed.org/users/okini3939/code/XBee/
And when aforementioned code runs, my output is this:
Terminal ready
Packet available
Response available at API: 138
Packet available
Response available at API: 138
...
138 is a decimal representation of a hex 0x8A, which in turn is mapped to MODEM_STATUS_RESPONSE.
This XBee module is the only one that is powered.
And my question is why would I have that weird behaviour? How come this XBee have successfully read packet at all?
The XBee module sends the Modem Status frame to the host, and it's not the result of the module receiving a packet. Try dumping the rest of the Modem Status frame to see what status the XBee module is trying to report. It might be reporting Hardware Reset (0x00), followed by Coordinator Started (0x06).
The XBee Series 1 documentation includes a list of all possible Modem Status values.
BTW, updating the sprintf(tmp, "%d", c); to use "0x%02X" as the format string will print the frame type in hex and make it easier to look up frame types in the documentation.

How to send serial data from Python script to Arduino on Windows - Nothing Works

I can't correctly send data over serial from a Python script to an Arduino Uno. I'm using 9600 baud, and the Arduino correctly resets, but it does not read the char I'm sending from the Python script. I call time.sleep() to ensure the reset on the Arduino does not interfere, and I'm using Windows 7. I should clarify by saying that my desktop is running the python script and connected via USB to the Serial of my Arduino Uno. I then have the RX & TX pins (pins 0 & 1) of my Uno connected to my Mega's Serial1 (pins 18 & 19). I then use the Serial Monitor in the Arduino IDE on my laptop (which uses the Mega's regular Serial) to peek at what the Uno is seeing. Here is the code for the Mega:
void setup() {
Serial1.begin(9600);
Serial.begin(9600);
Serial.println("Master Ready");
}
void loop() {
if(Serial1.available() > 0) {
char inByte = Serial1.read();
Serial.write(inByte);
Serial.write("\n");
}
}
Here is the code for the Uno:
void setup() {
Serial.begin(9600);
Serial.println("Slave Ready");
}
void loop() {
if(Serial.available() > 0) {
char inByte = Serial.read();
Serial.write(inByte);
}
}
And finally, here is the python script:
import sys
import serial
import time
ser = serial.Serial("COM23",9600)
n = int(sys.argv[1])
print n
time.sleep(10)
print ser
print n == 41
if (n == 70):
ser.write(chr(97))
print 'a'
elif n == 41:
ser.write('ggggggg')
print 'b'
elif n == 42:
ser.write('hello world')
print 'c'
elif n == 25:
ser.write(chr(100))
elif n == 26:
ser.write(chr(101))
elif n == 22:
ser.write(chr(102))
elif n == 10:
ser.write(chr(103))
elif n == 4:
ser.write(chr(104))
elif n == 14:
ser.write(chr(105))
elif n == 7:
ser.write(chr(106))
elif n == 11:
ser.write(chr(105))
elif n == 5:
ser.write(chr(106))
elif n == 17:
ser.write(chr(107))
# head - a - 70
# right bicep - b - 41
# right forearm - c - 42
# left bicep - d - 25
# left forearm - e - 26
# chest - f - 22
# right thigh - g - 10
# left thigh - h - 4
# right shin - i - 11 - 14
# left shin - j - 5 - 7
# waist - k - 17
In case it helps, I'm essentially trying to write the hit locations in Doom3 to an Arduino over serial so that the Arduino can turn a motor on in the proper location on your body. The game code is in C++, and I first tried using a serial library for C++, but that didn't work either.
I just came across something similar. The key here is that it worked when communicating with the arduino from the IDE and failed when using some other serial program. You have been bit by the auto-reset feature.
Check out this link on the Arduino Playground for a detailed description of what is going on and what to do about it. The site gives several solutions depending on you skill and comfort level.
I expect your C++ code will work once you implement one of the work arounds from this site.
If I understand your physical setup correctly, there appears to be a conflict between the Arudino IDE and python. Only one program by default can open the serial port at a time (like opening a file for exclusive write). If you just use the python script, don't start the arduino IDE and change the ardiuno to turn on an LED when it gets a msg, that should work (if you serial port assignment is correct). The arduino's diagnostic LEDs should blink with normal serial traffic, but for a single msg you might be missing the short blink.
It looks like there is also a conflict between using the serial port between the IDE and between Arduinos. (I don't understand the reason for multiple Arduinos.) Each serial communication pair should be unique. Use the Arduino's SoftwareSerial library to use another pair of digital pins to communicate between the arduinos, not the d0/d1 pins currently used by the FTDI chip to talk to the IDE.
Might also include some diagnostic msgs in the python script if it can't open/communicate with the serial port.
Problem:
Serial Communication is not always accurate. Sometimes you can notice that in the Serial Monitor, garbage data that you don't want appearing due to the overlapping of two or more pieces of data from Arduino. Similarly, try sending two values quickly and printing the value on the serial monitor, you will notice the same kind of overlapping. Arduino requires certain delays to work effectively and hence pyserial module is not the best way to use python with Arduino.
Solution:
1) In your python script use the ser.write() or ser.read() functions twice! If you find this irritating, use the next solution.
2 ) Use Arduino_Master_Delta module(python) to communicate with Arduino which is designed especially to ease the process and remove garbage values with advanced data science and visualization functions.
The link to the pip module is Arduino_Master_Delta
With this module installed you can use this statement instead:
import Arduino_Master_Delta as amd
writeSerial(23, msg=' Whatever you want to send to the serial monitor')
# Data will be encoded into bytes and hence use the Serial.readString() in Arduino code
# and then convert the string to your desired data type!
Read the documentation in the above link to learn more !!
BTW I'm the developer of this python module. Do share your view about it.
I had a problem too with serial communication, i managed to resolve it by closing the serial monitor in the Arduino. I don't know if you open it when you run your program, but if you do then that might be the problem.