I am experimenting with connecting Raspberry Pi to Arduino, and when I set a loop to receive info from Arduino Uno serial, it only receives:
'118537\r\n'
That is when I try to serial print 'Hi'
Here is my arduino code:
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.println('Hi');
delay(2000);
}
Here is my python 3.2 code:
import serial
ser = serial.Serial('/dev/ttyACM0')
while True:
print(ser.readline())
This prints: '118537\r\n' every 2 seconds.
How can I get the original 'Hi' every 2 seconds?
For those of you who want to know, it was the fact that I used ' instead of " in the string, changing:
Serial.println('Hi');
to
Serial.println("Hi");
eta: the reason why '118537\n\n' is printed out is because 'Hi' is a literal array of two bytes rather than a "string" and therefore the compiler uses the function for printing an int. In fact, the hex code of H is 48 and the hex code of i is 69, and the hexadecimal value of 0x4869 is exactly 118537 in decimal notation.
Related
I have a weird bug when I'm sending data from Arduino Mega via I2C to Raspberry Pi 4B.
Arduino Mega is working as slave and Raspberry Pi as master. Raspberry Pi request data from Arduino and it sends a string of letters and numbers that look like this(no newline on the end):
xxE5xNx
but Raspberry Pi receives:
xxE5xN#
For sure that's not a issue with wiring, because I tested sending and receiving of 1000 packets without any error.
This bug does not happen when I change 'E', '5' or 'N' to another character or delete first two characters. When changing any of 'x' to another character bug still exists. Why?
Minimal code for reproducing:
Arduino Mega(slave):
#include <Wire.h>
String s = "xxE5xNx";
void i2cRequest(){
Wire.print(s);
}
void setup() {
Wire.begin(0x01);
Wire.onRequest(i2cRequest);
}
void loop() {}
Raspberry Pi 4B(master):
from smbus2 import SMBus
bus = SMBus(1)
data = bus.read_i2c_block_data(0x01, 0, 32)
text = ""
for m in data:
if(m != 255): text += chr(m)
print(text)
I want to send multibyte integers,(eg. 1000,10000, etc) from raspberry pi to arduino. It can either be in the form of int or string(will convert it into integer on arduino's side) through i2c. Now, I am able to send data but only till 255, If I try to send 1000, the output on ARduino serial terminal will be 232 and not 1000. I tried to search over the internet for like 4-5 hours, but no luck. Can someone please guide me?
import smbus
import time
bus = smbus.SMBus(1)
address = 0x04
a=1000
#a=str(a)
def writeString(a,b,c,d):
bus.write_i2c_block_data(address, a, [b, c, d])
return -1
while True:
try:
writeString(1000,a,5,0)
time.sleep(1) #delay one second
except KeyboardInterrupt:
quit()
Arduino:
#include <Wire.h>
int data [4];
int x = 0;
void setup() {
Serial.begin(9600);
Wire.begin(0x04);
Wire.onReceive(receiveData); //callback for i2c. Jump to void recieveData() function when pi sends data
}
void loop () {
delay(100); //Delay 0.1 seconds. Something for the arduino to do when it is not inside the reciveData() function. This also might be to prevent data collisions.
}
void receiveData(int byteCount) {
while(Wire.available()) { //Wire.available() returns the number of bytes available for retrieval with Wire.read(). Or it returns TRUE for values >0.
data[x]=Wire.read();
x++;
}
Serial.println("----");
Serial.print(data[0]);
Serial.print("\t");
Serial.print(data[1]);
Serial.print("\t");
Serial.print(data[2]);
Serial.print("\t");
Serial.println(data[3]);
// Serial.print("----");
}
I2C sends and receives BYTES. 1000 in hex is 0x3E8. 232 in hex is 0xE8. Only the low byte is sent.
I send 3 set of data from 3 sensors from Arduino 1 (router) to another Arduino(coordinator) to with wireless technology (xbee):
On coordinator, I receive wireless data from this 3 sensors(from the router) perfectly. The data stream is something like this(each sensor data on its line):
22.5624728451
944
8523
I want to have these 3 values as 3 variables that get updated constantly and then pass these values on to the rest of the program to make something like print on LCD or something else:
temperature=22. 5624728451
gas=944
smoke=8523
Initially, I had only 2 sensors and I send the data of these 2 sensors something like this:
22.5624728451944(22.5624728451 – temperature, 944 - gas) and I received both of them on the same line and divided everything into two variables(with readString.substring() ) with the code below. But now I have 3 sensors and I receive data on a separate line because I don't know which is the length of each data string … And I can't use the same technique (sending only one string that contain all sensor data on the same line and then divide them)
My old code:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,10,9,8,7);
String temperature;
String gas;
String readString;
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
}
void loop() {
while (Serial.available() > 0)
{
char IncomingData = Serial.read();
readString += IncomingData ;
temperature = readString.substring(0, 13); //get the first 13 characters
gas = readString.substring(13, 16); //get the last 3 characters
Serial.print(IncomingData); //here I have my string: 20.1324325452924 wichs is updating properly when I have sensor values changes
// Process message when new line character is DatePrimite
if (IncomingData == '\n')
{
Serial.println(temperature);
lcd.setCursor(0,0);
lcd.write("T:");
lcd.print(temperature);
delay(500);
temperature = ""; // Clear DatePrimite buffer
Serial.println(gaz);
lcd.begin(16, 2);
lcd.setCursor(0,1);
lcd.write("G:");
lcd.print(gas);
delay(500);
gaz = ""; // Clear DatePrimite buffer
readString = "";
}
}
}
All I want to do now is to assign a variable for every sensor data (3 lines – 3 variables for each line) updated constantly and then pass these values on to the rest of the program. Does anyone have any idea how to modify the code tO work in this situation?
Thank you in advance!
I would recommend that you concatenate the values into the same line on the sending end and use a delimiter like a comma along with string.split() on the receiving end if you are committed to using string values. EDIT: It appears Arduino does not have the string.split() function. See this conversation for an example.
An alternative would be to set a standard byte length and send the numbers as binary instead of ASCII encoded strings representing numbers. See this post on the Arudino forum for a little background. I am recommending sending the number in raw byte notation rather than as ASCII characters. When you define a variable as in integer on the arduino it defaults to 16-bit signed integer value. A float is a 32-bit floating point number. If, for example, you send a float and two ints as binary values the float will always be the first 4 bytes, the first int, the next 2 and the last int the last 2. The order of the bytes (endianness, or most significant byte first (Big Endian, Motorolla style)/least significant bit first (Little Endian, Intel style)).
I'm using this sensor with an arduino board.
On page 2, it describes the serial output from pin 5.
http://www.maxbotix.com/documents/HRXL-MaxSonar-WR_Datasheet.pdf
The output is an ASCII capital "R", followed by four ASCII character
digits representing the range in millimeters,followed by a carriage
return (ASCII 13). The serial data format is 9600 baud, 8 data bits, no parity,
with one stop bit (9600-8-N-1).
This is my arduino code (which isn't correct). It only outputs the '82' which is the capital R.
void setup()
{
Serial.begin(9600);
}
void loop()
{
int data = Serial.read();
Serial.println(data);
delay (1000);
}
How do I get a distance reading to a string?
Many thanks
Do you tried the readBytesUntil method ?
You should use it like that :
byte DataToRead [6];
Serial.readBytesUntil(char(13), DataToRead, 6);
Your data is contained into DataToRead (your 'R' in DataToRead[0] etc.)
As I read it, the question was:
How do you convert a byte (ascii) representation of a character into a readable alpha-numeric character like "a" versus 97?
The actual quesion: Arduino convert ascii characters to string.
Why do ppl post responses that don't answer the question?
Not exact answer but casting with (char) will get you on the way there.
char inByte = 0;
inByte = (char)Serial.read(); // ascii 97 received
Serial.println((char)inByte); // => prints an 'a' without the quotes
to start off, this might not be a problem with arduino code or arduino, but I figured I would post here because I really just can not figure out what is wrong.
I am working on this project just for fun to send key strokes from the keyboard, through the computer, and out through the USB to my arduino mega. No additional hardware is here, just the computer, the arduino, and the USB cable.
I am using Microsoft Visual Studio Express 2012 to write code to receive key strokes and send them to the USB. This is the code I am using:
#include "stdafx.h"
#include "conio.h"
using namespace System;
using namespace System::IO::Ports;
int main(array<System::String ^> ^args)
{
String^ portName;
String^ key;
int baudRate=9600;
Console::WriteLine("type in a port name and hit ENTER");
portName=Console::ReadLine();
//arduino settings
SerialPort^ arduino;
arduino = gcnew SerialPort(portName, baudRate);
//open port
try
{
arduino->Open();
while(1)
{
int k = getch();
key = k.ToString();
Console::WriteLine(key);
arduino->Write(key);
if (k == 32)
return 0;
}
}
catch (IO::IOException^ e )
{
Console::WriteLine(e->GetType()->Name+": Port is not ready");
}
}
This code works fine, and sends commands to the arduino. I might as well ask this as well, but after 35 key strokes it just stops sending key strokes, I am unsure as to why, but that is not an arduino problem (I don't think).
So when the certain value for key gets sent to the arduino, it changes. For example, the values that are assigned to the variable key for pressing the number 1 and 2 are 49 and 50, respectively. However, when they get sent to the arduino, the values are different some how. 1 is now 57, and 2 is now 48. I am unsure as to why this is happening. I tried 4 and 5 and they both have their values shift down 2 like the key 2. This is the code I have on the arduino:
int ledPin = 13;
int key=0;
int c;
void setup()
{
pinMode(ledPin, OUTPUT); // pin will be used to for output
Serial.begin(9600); // same as in your c++ script
}
void loop()
{
if (Serial.available() > 0)
{
key = Serial.read(); // used to read incoming data
if (key == 57)
{
digitalWrite(ledPin, HIGH);
}
else if (key == 48)
{
digitalWrite(ledPin, LOW);
}
}
c = key;
Serial.println(c);
}
As of right now it is just to switch a light on and off. I am hoping to involve many more keys and having the values be consistent would be very convenient. Anyways, if anyone could help me with why the values are different that would be awesome. I am not completely new to programming but I am certainly no expert and have not gotten too far into advanced stuff.
Thank you for any help or advice.
This has to do with what you are sending through visual studio. You are converting a keypress to its ASCII value, then converting that ASCII value to string, then sending that string through serial. The arduino is expecting a number, not a string.
For example, if you press the 1 key, your visual studio code converts that to an ASCII number 49, which is then converted to string "49", which the Arduino receives - but since you are sending "49", which is a "4" and an "9", the Arduino is reading 9 which corresponds to 57, as you have seen.
Similarly, pressing 2 converts it to "50", and the Arduino reads "0" which corresponds to the value 48 which you were getting.
To fix this, send the number directly, don't convert it into a string.