How to receive strings from Arduino in C++? - c++

Hey I have problems with receiving strings from Arduino. I am running on linux and I want to use C++ fotr that. I an easily send strings from C++ code to arduino. For that I use C++ code like this.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
fstream arduino("/dev/ttyACM0");
arduino << "Led on\n";
arduino.close();
return 0;
}
So how can I receive strings from Arduino?

I'm not an Arduino expert, but from your code I concluded:
You are using a serial interface to send data
You should connect the serial interface to your computer (with a traditional serial cable, or USB)
Write a C++ app, that opens and received data from serial port. See this!
Find out from Arduino specs, what serial communication parameters are used by Arduino (stop bit, parity bits, baudrate etc) and use these parameters to configure the serial port in your C++ application!
Hope that helps!

Use boost.asio to communicate with a serial device and C++. It works like a charm and is pretty easy to use. See: http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/overview/serial_ports.html and this: Reading from serial port with Boost Asio

The folowing code waits for a response from an arduino. If the response contains "Done" it returns 1. If it didn't find it within the given timeout, it returns -1.
It should not prove that hard to change this code to fit your needs.
int Serial::waitForResponse()
{
const int buffSize = 1024;
char bufferChar[buffSize] = {'\0'};
int counter = 0;
std::string wholeAnswer = "";
int noDataTime = 0;
while(wholeAnswer.find("Done") == std::string::npos) //Done string was found.
{
if(noDataTime > 10000)
{
std::cout << "timeout" << std::endl;
return -1;
}
counter = read(this->hSerial, bufferChar, buffSize - 1);
if(counter > 0)
{
noDataTime = 0;
bufferChar[counter] = '\0';
wholeAnswer += std::string(bufferChar);
} else
{
noDataTime++;
usleep(1000);
}
}
if(!wholeAnswer.empty())
{
return 1;
} else
{
return -1;
}

Related

No Matching Function Begin Multicast - Arduino/cpp

I was given a project to convert from ESP8266 to ESP32, and I'm definitely not a coder, but it needs to get done. So I was hoping I could get some guidance/help on how to solve this issue. I'm basically taking previous code from an old project using an ESP8266 WiFi module and converting it over to a more updated module using ESP32. Been compiling and troubleshooting code as I go the best I can, but this one has stumped me.
The error message I'm getting is "No matching function for call to 'WiFiUDP::beginMulticast(IPAddress, IPAddress&, const unsigned int&)'
There are several pages of code, but this is the .cpp file that is currently throwing up an error, and hoping it's able to be resolved with something on this page. Like I said, I'm not a coder, but I have the basics down. Any help on this would be greatly appreciated. Thanks!
#include "Switch.h"
#include <functional>
// Multicast declarations
IPAddress ipMulti(239, 255, 255, 250);
const unsigned int portMulti = 1900;
char packetBuffer[512];
#define MAX_SWITCHES 14
Switch switches[MAX_SWITCHES] = {};
int numOfSwitchs = 0;
//#define numOfSwitchs (sizeof(switches)/sizeof(Switch)) //array size
//<<constructor>>
UpnpBroadcastResponder::UpnpBroadcastResponder(){
}
//<<destructor>>
UpnpBroadcastResponder::~UpnpBroadcastResponder(){/*nothing to destruct*/}
bool UpnpBroadcastResponder::beginUdpMulticast(){
boolean state = false;
Serial.println("Begin multicast ..");
if(UDP.beginMulticast(WiFi.localIP(), ipMulti, portMulti)) {
Serial.print("Udp multicast server started at ");
Serial.print(ipMulti);
Serial.print(":");
Serial.println(portMulti);
state = true;
}
else{
Serial.println("Connection failed");
}
return state;
}
//Switch *ptrArray;
void UpnpBroadcastResponder::addDevice(Switch& device) {
Serial.print("Adding switch : ");
Serial.print(device.getAlexaInvokeName());
Serial.print(" index : ");
Serial.println(numOfSwitchs);
switches[numOfSwitchs] = device;
numOfSwitchs++;
}
void UpnpBroadcastResponder::serverLoop(){
int packetSize = UDP.parsePacket();
if (packetSize <= 0)
return;
IPAddress senderIP = UDP.remoteIP();
unsigned int senderPort = UDP.remotePort();
// read the packet into the buffer
UDP.read(packetBuffer, packetSize);
// check if this is a M-SEARCH for WeMo device
String request = String((char *)packetBuffer);
if(request.indexOf('M-SEARCH') > 0) {
if(request.indexOf("urn:Belkin:device:**") > 0) {
Serial.println("Got UDP Belkin Request..");
// int arrSize = sizeof(switchs) / sizeof(Switch);
for(int n = 0; n < numOfSwitchs; n++) {
Switch &sw = switches[n];
if (&sw != NULL) {
sw.respondToSearch(senderIP, senderPort);
}
}
}
}
}```
The Arduino UDP API as defined by the UDP base class in Arduino core has
uint8_t beginMulticast(IPAddress, uint16_t);
In esp8266 Arduino WiFi the UDP is modified and the first parameter of beginMulticast specifies the network interface to listen to. (Network interfaces are STA, SoftAP, Ethernet etc)
In esp32 Arduino WiFi library beginMulticast has only the standard parameters and listens on all network interfaces.
Your solution is to remove the first parameter in the beginMulticast call.

How to pass the(serverClients[i].read() to byte array on ESP8266

In a sketch of Arduino there is an example WiFi Telnet To Serial with ESP8266. There is a piece of code that is used to receive data from a client:
//check clients for data
for(i = 0; i < MAX_SRV_CLIENTS; i++){
if (serverClients[i] && serverClients[i].connected()){
if(serverClients[i].available()){
//get data from the telnet client and push it to the UART
while(serverClients[i].available())
Serial.write(serverClients[i].read());
}
}
}
This data is sent to the console or the serial port, but I need to capture that data and store it in a byte array:
byte bufferMSGfromCliente[1024]
How to do it?
Its not c++ but you might be able to use a processing sketch. The syntax is very close to arduino so it should be familiar.
import processing.serial.*;
Serial myPort; // The serial port
void setup() {
// List all the available serial ports
printArray(Serial.list());
// Open the port you are using at the rate you want:
myPort = new Serial(this, Serial.list()[0], 9600);
}
void draw() {
int i = 0;
byte[] bufferMSGfromCliente = new byte[1024];
while (myPort.available() > 0) {
int inByte = myPort.read();
if(i > 1024)
{
i = 0;
}
bufferMSGfromCliente[i] = inByte;
i++;
}
}
Did you try to write it to another Serial port? Here you write it on the same Serial port as your Serial Monitor.
Best would be to store serverClients[i].read() into a Byte and then Serial.println(Byte) to see what the information is.
After that, ask yourself:
1. What Serial port will this information be sent to, what is the destination?
2. How can I confirm that information is sent succesfully and has the ability to be debugged.
Also, use Serial.flush() to make sure the Serial.write function completes. Eventhough it says ''flush'', the function in Arduino IDE waits for the Serial write function to be completed.

Why is the Serial communication via BLE failing on the first run of the code but working fine for consecutive runs?

I'm trying to communicate with the STM32 microcontroller via serial communication. Before I was using the USB cable and the communication worked flawlessly. However when I switched the same serial mode from USB to BLE (HM-10), the microcontroller fails to respond correctly for the first try, but it is okay after that. What could be a problem?
I tried searching if it was something to do with buffers or start/stop bits. But it didn't help me much because I had no clue about how to implement them through code. I'm using the MbedOS to program my dev board.
CODE:
#include "mbed.h"
DigitalOut led1(LED1);
#define MAX_INPUT_LENGTH 2
int code[MAX_INPUT_LENGTH];
Serial bt(PD_5, PD_6);
//Serial pc(USBTX, USBRX);
int main()
{
while(1)
{
while(bt.readable()==1)
{
volatile char str[2];
bt.scanf("%2s",str);
int index = 0;
while(index<=MAX_INPUT_LENGTH)
{
code[index] = str[index] - '0'; // convert to an int.
index++; // increase the index.
}
if(code[0]==0 && code[1]==1)
{
bt.printf("\n01 RECIEVED.");
for(int x=0;x<15;x++)
{
led1 = 1;
wait(0.25);
led1 = 0;
wait(0.25);
}
}
else
bt.printf("\nINCORRECT VALUE RECIEVED.");
}
}
}
I expected the output from ble serial to work the same way as the usb serial, but it failed for the first run.

windows getting serial port names using c++ [duplicate]

There are several ways to list serial ports under Windows but I'm not sure what is the proper way: the way that does detect all serial ports that are available.
One good code example is http://www.naughter.com/enumser.html - where there are 9 (nine!) ways of enumerating serial devices.
The question is: what is the optimal way of doing it.
Requirements:
to not open ports in order to check if they are available.
to be able to detect ports with different names than COMx.
to work on Windows XP SP2 or above
void SelectComPort() //added function to find the present serial
{
TCHAR lpTargetPath[5000]; // buffer to store the path of the COMPORTS
DWORD test;
bool gotPort=0; // in case the port is not found
for(int i=0; i<255; i++) // checking ports from COM0 to COM255
{
CString str;
str.Format(_T("%d"),i);
CString ComName=CString("COM") + CString(str); // converting to COM0, COM1, COM2
test = QueryDosDevice(ComName, (LPSTR)lpTargetPath, 5000);
// Test the return value and error if any
if(test!=0) //QueryDosDevice returns zero if it didn't find an object
{
m_MyPort.AddString((CString)ComName); // add to the ComboBox
gotPort=1; // found port
}
if(::GetLastError()==ERROR_INSUFFICIENT_BUFFER)
{
lpTargetPath[10000]; // in case the buffer got filled, increase size of the buffer.
continue;
}
}
if(!gotPort) // if not port
m_MyPort.AddString((CString)"No Active Ports Found"); // to display error message incase no ports found
}
If you can access the registry, the HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM key contains a list of COM ports Windows currently supports (in some cases, this information may be stale/incorrect; like, I suspect, when a plug & play device providing serial ports has not completed detection/installation or has been recently removed).
This is the way .NET Framework's SerialPort.GetPortNames() method reports available COM ports, and the above information is derived from the linked page.
Serial ports are very simple devices, dating from the stone age of computing hardware. They don't support Plug & Play, there is no way to tell that somebody plugged in a device. The only thing you can do is discover what ports are available, the SerialPort.GetPortNames() returns the list. Some USB emulators can generate a descriptive name to go with the port name, you can discover those with WMI, Win32_SerialPort class.
None of which helps you discover what COM port is connected to a particular device. Only a human knows, she physically plugged the cable in the connector. You'll need to provide a config UI that lets the user select the port number. A combo box gets the job done. Save the selection in your config data, it is very likely that the device is still connected to the same port the next time your program starts.
This is a modernized version of #michael-jacob-mathew's answer:
#include <iostream>
#include <string>
#include <Windows.h>
bool SelectComPort() //added function to find the present serial
{
char lpTargetPath[5000]; // buffer to store the path of the COMPORTS
bool gotPort = false; // in case the port is not found
for (int i = 0; i < 255; i++) // checking ports from COM0 to COM255
{
std::string str = "COM" + std::to_string(i); // converting to COM0, COM1, COM2
DWORD test = QueryDosDevice(str.c_str(), lpTargetPath, 5000);
// Test the return value and error if any
if (test != 0) //QueryDosDevice returns zero if it didn't find an object
{
std::cout << str << ": " << lpTargetPath << std::endl;
gotPort = true;
}
if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
}
}
return gotPort;
}
It produces the following output on my computer:
COM1: \Device\Serial0
COM3: \Device\VCP0
Modified #Dženan answer to use wide characters and returning list of ints
#include <string>
#include <list>
list<int> getAvailablePorts()
{
wchar_t lpTargetPath[5000]; // buffer to store the path of the COM PORTS
list<int> portList;
for (int i = 0; i < 255; i++) // checking ports from COM0 to COM255
{
wstring str = L"COM" + to_wstring(i); // converting to COM0, COM1, COM2
DWORD res = QueryDosDevice(str.c_str(), lpTargetPath, 5000);
// Test the return value and error if any
if (res != 0) //QueryDosDevice returns zero if it didn't find an object
{
portList.push_back(i);
//std::cout << str << ": " << lpTargetPath << std::endl;
}
if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
}
}
return portList;
}
You can check the windows registry base to list all COM ports. Here is my code > github file
CUIntArray ports;
EnumerateSerialPorts(ports);
for (int i = 0; i<ports.GetSize(); i++)
{
CString str;
str.Format(_T("COM%d"), ports.ElementAt(i));
m_ctlPort.AddString(str);
}

What is proper way to detect all available serial ports on Windows?

There are several ways to list serial ports under Windows but I'm not sure what is the proper way: the way that does detect all serial ports that are available.
One good code example is http://www.naughter.com/enumser.html - where there are 9 (nine!) ways of enumerating serial devices.
The question is: what is the optimal way of doing it.
Requirements:
to not open ports in order to check if they are available.
to be able to detect ports with different names than COMx.
to work on Windows XP SP2 or above
void SelectComPort() //added function to find the present serial
{
TCHAR lpTargetPath[5000]; // buffer to store the path of the COMPORTS
DWORD test;
bool gotPort=0; // in case the port is not found
for(int i=0; i<255; i++) // checking ports from COM0 to COM255
{
CString str;
str.Format(_T("%d"),i);
CString ComName=CString("COM") + CString(str); // converting to COM0, COM1, COM2
test = QueryDosDevice(ComName, (LPSTR)lpTargetPath, 5000);
// Test the return value and error if any
if(test!=0) //QueryDosDevice returns zero if it didn't find an object
{
m_MyPort.AddString((CString)ComName); // add to the ComboBox
gotPort=1; // found port
}
if(::GetLastError()==ERROR_INSUFFICIENT_BUFFER)
{
lpTargetPath[10000]; // in case the buffer got filled, increase size of the buffer.
continue;
}
}
if(!gotPort) // if not port
m_MyPort.AddString((CString)"No Active Ports Found"); // to display error message incase no ports found
}
If you can access the registry, the HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM key contains a list of COM ports Windows currently supports (in some cases, this information may be stale/incorrect; like, I suspect, when a plug & play device providing serial ports has not completed detection/installation or has been recently removed).
This is the way .NET Framework's SerialPort.GetPortNames() method reports available COM ports, and the above information is derived from the linked page.
Serial ports are very simple devices, dating from the stone age of computing hardware. They don't support Plug & Play, there is no way to tell that somebody plugged in a device. The only thing you can do is discover what ports are available, the SerialPort.GetPortNames() returns the list. Some USB emulators can generate a descriptive name to go with the port name, you can discover those with WMI, Win32_SerialPort class.
None of which helps you discover what COM port is connected to a particular device. Only a human knows, she physically plugged the cable in the connector. You'll need to provide a config UI that lets the user select the port number. A combo box gets the job done. Save the selection in your config data, it is very likely that the device is still connected to the same port the next time your program starts.
This is a modernized version of #michael-jacob-mathew's answer:
#include <iostream>
#include <string>
#include <Windows.h>
bool SelectComPort() //added function to find the present serial
{
char lpTargetPath[5000]; // buffer to store the path of the COMPORTS
bool gotPort = false; // in case the port is not found
for (int i = 0; i < 255; i++) // checking ports from COM0 to COM255
{
std::string str = "COM" + std::to_string(i); // converting to COM0, COM1, COM2
DWORD test = QueryDosDevice(str.c_str(), lpTargetPath, 5000);
// Test the return value and error if any
if (test != 0) //QueryDosDevice returns zero if it didn't find an object
{
std::cout << str << ": " << lpTargetPath << std::endl;
gotPort = true;
}
if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
}
}
return gotPort;
}
It produces the following output on my computer:
COM1: \Device\Serial0
COM3: \Device\VCP0
Modified #Dženan answer to use wide characters and returning list of ints
#include <string>
#include <list>
list<int> getAvailablePorts()
{
wchar_t lpTargetPath[5000]; // buffer to store the path of the COM PORTS
list<int> portList;
for (int i = 0; i < 255; i++) // checking ports from COM0 to COM255
{
wstring str = L"COM" + to_wstring(i); // converting to COM0, COM1, COM2
DWORD res = QueryDosDevice(str.c_str(), lpTargetPath, 5000);
// Test the return value and error if any
if (res != 0) //QueryDosDevice returns zero if it didn't find an object
{
portList.push_back(i);
//std::cout << str << ": " << lpTargetPath << std::endl;
}
if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
}
}
return portList;
}
You can check the windows registry base to list all COM ports. Here is my code > github file
CUIntArray ports;
EnumerateSerialPorts(ports);
for (int i = 0; i<ports.GetSize(); i++)
{
CString str;
str.Format(_T("COM%d"), ports.ElementAt(i));
m_ctlPort.AddString(str);
}