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

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);
}

Related

How can I wait for all data to be written before the serial port connection is terminated

I need to send data from my QT application via serial port. I am trying to send data in this way.
void productDetail::on_detailSaveBtn_clicked()
{
if (!serial.isOpen())
{
if (serial.begin(QString("COM3"), 9600, 8, 0, 1, 0, false))
{
serial.send(ui->productDesp->text().toLatin1());
serial.end();
}
}
}
As I understand it, serial connection closes without writing all data. I think closing the serial port after waiting for all the data to be written can solve my problem. How can I verify that all data is written before the serial port close?
QT 5.15.2
Windows
Try to wait a few time so a portion of data can be written. Check if any left with while loop and repeat the process.
serial.send(ui->productDesp->text().toLatin1());
while(serial.bytesToWrite()){
serial.waitForBytesWritten(20);
}
serial.end();

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"));
}
}

C++ Serial Communication Issue

I am trying to make a Console C++ program that will be able to communicate through the serial port with my Arduino microcontroller, however I am having a problem with the ReadFile() function:
This is the ReadFile() function code from my C++ Console Program:
if(ReadFile(myPortHandle, &szBuf, 1, &dwIncommingReadSize, NULL) != 0)
{
cout<<"FOUND IT!"<<endl;
Sleep(100);
}
else
{
cout<<".";
Sleep(100);
}
The ReadFile function is consistently returning the "False" value, meaning it is not finding anything in the serial port. On the other side of the serial port, I have my Arduino Hooked up with the following code:
int switchPin = 4; // Switch connected to pin 4
void setup() {
pinMode(switchPin, INPUT); // Set pin 0 as an input
Serial.begin(9600); // Start serial communication at 9600 bps
}
void loop() {
if (digitalRead(switchPin) == HIGH) { // If switch is ON,
Serial.write(1); // send 1 to Processing
} else { // If the switch is not ON,
Serial.write(0); // send 0 to Processing
}
delay(100); // Wait 100 milliseconds
}
And every time I press a push button, I would send a "1" value to the serial port, and a "0" every time I don't press a push button. Basically, I got the Arduino code from a tutorial I watched on how to do serial communication with the program Processing (which worked perfectly), though I am unable to do the same with a simple Console Application I made with C++ because for some reason the ReadFile() function isn't finding any information in the serial port.
Anyone happen to know why?
P.S.: The complete code in the C++ Console Program can be found here:
https://stackoverflow.com/questions/27844956/c-console-program-serial-communication-arduino
The ReadFile function is consistently returning the "False" value, meaning it is not finding anything
No, that is not what it means. A FALSE return value indicates that it failed. That is never normal, you must implement error reporting code so you can diagnose the reason. And end the program since there is little reason to continue running. Unless you setup the serial port to intentionally fail by setting a read timeout.
Use GetLastError() to obtain the underlying Windows error code.
You look to use MS Windows so try to catch the arduino output using portmon first, then you can debug your C++ code.

xbee arduino communication programming

I tried testing the system and I’m not sure if the problem is with the xbee’s, the transmitting code, or the recieveing code. Before I post my code I will explain what we are doing with the signals. We have three analog signals that will be sent serially through one xbee using an arduino and xbee shield. We want to send these signals to the receiving xbee where the arduino will output these signals to be connected to a third arduino through wires to be used in a Simulink program. We are using an arduino mega for the transmitting side and an arduino uno for the receiving side. I was told I need to do serial streaming but I’m not sure how that’s done. I understand the xbee and arduinos both digitize signals but we are hoping to get a signal very similar to the analog signals we are transmitting. Any amount of help is greatly appreciated!!
This is how I have my xbees configured (series 1) both in AT mode:
Transmitting Xbee:
Channel:10
Pan id: 1234
MY: 10
DL: 11
Receiving Xbee:
Channel:10
Pan ID: 1234
MY: 11
DL: 10
transmitting Arduino code:
void setup() {
Serial.begin(9600);
}
void loop() {
// read the input on analog pins
int sensorValue1 = analogRead(A0);
int sensorValue2 = analogRead(A1);
int sensorValue3 = analogRead(A2);
// print out the value you read:
Serial.println(sensorValue1);
Serial.println(sensorValue2);
Serial.println(sensorValue3);
delay(1);
}
Receiving Arduino code:
int received1=8;
int received2=9;
int received3=10;
void setup(){
pinMode(received1, OUTPUT);
pinMode(received2, OUTPUT);
pinMode(received3, OUTPUT);
Serial.begin(9600);
}
void loop(){
if(Serial.available() )
{
byte output1 = Serial.read();
byte output2 = Serial.read();
byte output3 = Serial.read();
digitalWrite(received1, HIGH);
digitalWrite(received2, HIGH);
digitalWrite(received3, HIGH);
}
}
It sounds like you're using the XBee modules in "AT mode" or "transparent serial" mode where anything received on the serial port of module A is sent out of the serial port of module B, and vice versa.
If that's the case, it may help to do your initial development with the serial ports of your two devices connected directly to each other. Work out your serial protocol there, and then try to run it with the XBee modules in place as a serial cable replacement.
Consider the format of the data that you're sending, and how you will process it on the other end. How will you separate the readings and identify which analog input they belong to? With your current code, you print the readings on separate lines, but it won't be clear which is A0. Maybe you want to send them on a single line with a comma in between each reading?
On the receiving end, you need to convert the text back to an integer using a C function like atoi() or strtoul().
If you're trying to create an analog output on the Arduino, it might be possible with a digital output that's using PWM (pulse width modulation). This Instructable does a decent job of describing that concept.

How do I read the output of an AT command in Arduino?

How do I capture the output from an AT command on an Arduino?
I'm using the Arduino Uno R3 with a GSM shield. I have all the AT commands (they can be seen here ) and I can enter them just fine if I use the terminal and get output. However how can I capture the resulting output via code? The code below shows what I've tried but it does not work. In particular where I attempt to get the analog input and then print out the result.
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 8);
void setup()
{
char sensorValue[32] ="";
Serial.begin(9600);
mySerial.begin(9600);
Serial.println("\r");
//Wait for a second while the modem sends an "OK"
delay(1000);
//Because we want to send the SMS in text mode
Serial.println("AT+CMGF=1\r");
delay(1000);
mySerial.println("AT+CADC?"); //Query the analog input for data
Serial.println(Serial.available());
Serial.println(Serial.read()); //Print out result???
//Start accepting the text for the message
//to be sent to the number specified.
//Replace this number with the target mobile number.
Serial.println("AT+CMGS=\"+MSISDN\"\r");
delay(1000);
Serial.println("!"); //The text for the message
delay(1000);
Serial.write(26); //Equivalent to sending Ctrl+Z
}
void loop()
{
/*
if (mySerial.available())
Serial.write(mySerial.read());
if (Serial.available())
mySerial.write(Serial.read());
*/
}
I get the outputs:
AT+CMGF=1
AT+CADC? 21 13
or
AT+CMGF=1
AT+CADC? 18 65
Regardless of changes in my analog source
Take a look at the documentation of the SoftwareSerial read function here.
When you read from the GSM device serial interface, you cannot take for granted that there are bytes to be read on the buffer.
It's very likely that mySerial.read() returns -1 (no bytes available), as Arduino runs that code before the GSM device can provide something on the serial port.
You should use the available function (documentation here) to test the serial interface for incoming bytes. You could use it with a timeout to avoid infinite waiting.
The best thing you could try is to write a separate class to handle serial operations (read, write, timeouts, delays, etc).
Also, I wrote a GPRS driver for Arduino once.
I had a problem with the power supply that required me to install an extra capacitor on the GPRS device and use a power supply with more than 2A of output current.