The code below is what I am using to send and receive information from my Arduino. My problem is when the Arduino is first plugged in. Reading from it hangs because the command doesn't return anything because there is nothing there yet so my whole program crashes. How can I add a time-out to the read function, which is arduino->ReadLine();, that causes the issue? That way will it keep going after a second?
#include "stdafx.h"
#include <iostream>
using namespace System;
using namespace System::IO::Ports;
int main(int argc, char* argv[])
{
using namespace std;
String^ portName;
int baudRate=9600;
portName="COM4";
// Arduino settings.
SerialPort^ arduino;
arduino = gcnew SerialPort(portName, baudRate);
// Open port.
try
{
arduino->Open();
{
if (strcmp(argv[1],"-send")==0) {
String^ command = gcnew String(reinterpret_cast<const char*>(argv[2]));
if (String::Compare(command,"int6")==0) {
arduino->Write("^");
}
else
arduino->Write(command);
}
if(strcmp(argv[1],"-get")==0) {
String^ command = gcnew String(reinterpret_cast<const char*>(argv[2]));
arduino->WriteLine(command);
String^ result = arduino->ReadLine();
Console::Write(result);
}
}
Set arduino->ReadTimeout = duration_in_ms and then catch TimeoutException.
In addition to the timeout your code should loop until the BytesToRead property of the SerialPort is greater than zero
while (arduino->BytesToRead==0) {}
You could keep track of how long you have looped and exit gracefully with a user message if there is nothing received from the arduino within the expected time frame.
Related
First of all - I'm a student from Germany, so please excuse my bad english.
At the moment, I'm working on a Project which target is to controll servo Motors on an arduino board by Serial communication through xbee modules.
So now I'm studying the SerialPort but got Problems by using the write().
My plan is to send integer values seperated by a commata through my Serial Port.
Visual Studio Reports an error and says that there is no Argument type that fits.
I really don't know how to handle this problem, because I'm completely new to this whole programming topic.
#include <iostream>
using namespace std;
#using <System.dll>;
using namespace System;
using namespace System::IO::Ports;
using namespace System::Threading;
int main() {
unsigned char values[2] = { 50, 120 };
SerialPort^ mySerialPort = gcnew SerialPort("COM3");
mySerialPort->BaudRate = 9600;
mySerialPort->Open();
while (true) {
mySerialPort->Write(values);
}
}
You can fix it this way:
#include <iostream>
using namespace std;
#using <System.dll>
using namespace System;
using namespace System::IO::Ports;
using namespace System::Threading;
int main() {
// Managed array
cli::array<unsigned char> ^values = { 50, 120 };
SerialPort^ mySerialPort = gcnew SerialPort("COM3");
mySerialPort->BaudRate = 9600;
mySerialPort->Open();
while (true) {
// some work with values goes here...
// We should specify buffer offset and length
mySerialPort->Write(values, 0, values->Length);
}
}
As you noticed, you can also send this data as string:
mySerialPort->WriteLine(String::Format("val1 = {0}; val2 = {1}", values[0], values[1]));
But be warned that mySerialPort->Write() sends raw bytes, and mySerialPort->WriteLine() sends each character as a single byte.
For instance:
cli::array<unsigned char> ^buffer = {123};
// Send one single byte 0x7b
mySerialPort->Write(buffer, 0, buffer->Length);
// Send 3 bytes (0x49, 0x50, 0x51)
mySerialPort->WriteLine(String::Format("{0}", buffer[0]));
I have a C++ application that will be running constantly. It is listening for messages from a wireless module.
#include <stdlib.h>
#include <stdio.h>
struct payload {
char node[16];
char message
};
...
int main(int argc, char** argv) {
mesh.setNodeID(0); //irrelevant
mesh.begin(); //irrelevant
while(1){
mesh.update(); //irrelevant
mesh.DHCP(); //irrelevant
while(network.available()) {
struct payload received;
mesh.read(header, &received, sizeof(received)); //irrelevant
}
//below code goes here
}
And I want to be able to also send messages from this system.
I am currently reading a line from file:
//pseudo code
if (!fileEmpty) {
line = readLine();
struct payload send;
send.node = //splitted line
send.message = //splitted line
mesh.write(header, &send, sizeof(send));
And I split the line using strtok and assign the parts to a struct.
But there should be a better way.
I can't split the code for sending in different file (called with arguments) because there is some problem with the wireless module when I am listening and sending messages simultaneously. Assuming I splitted the code in two different files, I can kill the listening program when sending and then run it again, but this seems like a bad way of doing things.
So I am out of ideas.
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;
}
Please have a look at the following code:
#pragma once
using namespace System::IO::Ports;
using namespace System::Text::RegularExpressions;
using namespace System::Collections::Generic;
ref class SMS
{
public:
SMS(void);
void sendMessage();
private:
System::IO::Ports::SerialPort ^port;
};
And the cpp file
#include "StdAfx.h"
#include "SMS.h"
SMS::SMS(void)
{
//Initialize the Serial Port
port = gcnew System::IO::Ports::SerialPort();
port->PortName = "COM12";
port->BaudRate = 9600;
port->Parity = Parity::None;
port->DataBits = 8;
port->StopBits = StopBits::One;
port->Handshake = Handshake::RequestToSend;
port->DtrEnable = true;
port->RtsEnable = true;
port->NewLine = System::Environment::NewLine;
if(!port->IsOpen)
{
port->Open();
}
//Set message format
port->WriteLine("AT+CMGF=1");
//Turn off echo
port->WriteLine("ATE0");
//Set memory configurations
port->WriteLine("AT+CPMS=\"ME\",\"ME\",\"ME\"");
}
//This method will send the SMS
void SMS::sendMessage()
{
if(!port->IsOpen)
{
port->Open();
}
port->WriteLine("AT+CMGS=\"012121212\"");
port->WriteLine("Test Message From C#");
port->WriteLine(System::Convert::ToString((char)(26)));
port->Close();
}
I am trying to send SMS by accessing the dongle. The port is correct and the dongle also fine because it responded to my friend's code few hours back. What am I doing wrong here? Have I done anything incorrect with C++/CLI ? AT Commands?
try adding "CR" "LF" (Carriage Return and Line Feed characters) after each AT command, some GSM dongles (like SIM900) needem in order to work. I hope this helps
Regards
if for win32,..
prefer using
HFILE OpenFile(
LPCSTR lpFileName, // pointer to filename
LPOFSTRUCT lpReOpenBuff, // pointer to buffer for file information
UINT uStyle // action and attributes
);
with other events,...
if using SMS gateway with modem AT command capability, that's fine for direct read and write to COM port
if U using cell phone, many of this will not work. example nokia 6070, 3100 model group
best test it using hyperterminal.
I used CBuildre6 for
https://sites.google.com/site/xpressdms/rosegarden
cheer.
A C++ question on running 2 processes at a time.
I have a client-server model kind of C++ code. My server will fork for every connection from the client. This is a system that also has a reminder module. This reminder module will need to send an email when, let's say, it counts down from 1000 to 0: when it reaches 0, it will perform its code.
But my server is already running in a while(1) loop. How do I invoke this reminder thing together while not affecting the server listening to connections?
Thanks for all help and suggestions.
You are looking for what is commonly know as threads.
Here is an example using Boost.Thread:
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
bool worker_running = true;
void workerFunc() {
while (worker_running) {
boost::posix_time::seconds workTime(3);
// do something
boost::this_thread::sleep(workTime);
}
}
int main(int argc, char* argv[])
{
//before your while loop:
boost::thread workerThread(workerFunc);
//while loop here
worker_running = false;
workerThread.join();
return 0;
}