Non-printable control characters over serial port in C++ using WriteFile - c++

I am trying to write a control character (CTRL-T, which is #20 in ASCII table) to the serial port using the WriteFile() function, but apparently it does not work.
When I use putty and press CTRL+T, I receive a response over the serial port for communication with an ATI force sensor I work with. Below is a snapshot:
However, when I use the WriteFile() function in C++, I get no response from the sensor, which indicates to me that the CTRL-T command is not written to the serial port. Below is the code snippet:
// set write character to CTRL-T (#20 = 0x14)
char t = 0x14;
// write the character to the serial port
m_serialPort.Write(&t,1);
// read 14 bytes with 1000 ms timeout from the serial port
m_serialPort.Read_N(str_read,14,1000);
I have tested the functions Write and Read_N, and they work fine when I deal with printable characters.
Does anyone have any idea how to fix this?
EDIT: Here is a sample code:
// SerialTest.cpp : main project file.
#include "stdafx.h"
#include"SerialCommHelper.h"
#include <windows.h>
#include <iostream>
using namespace System;
CSerialCommHelper m_serialPort;
int main()
{
std::string comPort = "COM1";
std::string str_read;
// Open the serial Port
m_serialPort.Init(comPort,9600,0,1,8);
m_serialPort.Start();
m_serialPort.Purge();
// set write character to CTRL-T (#20 = 0x14)
char t = 0x14;
// write the character to the serial port
m_serialPort.Write(&t,1);
// read 14 bytes with 1000 ms timeout from the serial port
m_serialPort.Read_N(str_read,14,1000);
std::cout << str_read;
system("pause");
m_serialPort.Stop();
m_serialPort.UnInit();
return 0;
}

Related

Nucleo F401RE - can’t receive a data from rx pin (response from ESP32 WiFi module)

I have a problem with the UART communication from Nucleo f401re to ESP-Wroom-32 (WiFi BLE Click wifi module mikroe). I’m able to send an AT command but not to receive. I’m using the latest mbed-os verion, also I’m sending the at command via the ATCmdParser Api that it’s included on the “mbed.h” file. I had tried to receive with the the recv() function but it returns False. I tried also with the BufferedSerial.h with the read() but nothinguuu. I’m positive that i’m sending the command because i tried to receive the response from the esp32 module with the samd21 dev board and i’m receiving it fine.
Here is the code:
#include “mbed.h”
#include
#define ESP32_DEFAULT_BAUD_RATE 115200
BufferedSerial _serial;
ATCmdParser _parser;
/////~ set the debug parameter as a true of the ATCmdParser ~////
using namespace std;
char bufRead[100], buffWrite[50];
int main()
{
_serial = new BufferedSerial(D8, D2, ESP32_DEFAULT_BAUD_RATE);
_serial->set_format(
/* bits / 8,
/ parity / BufferedSerial::None,
/ stop bit */ 1
);
_parser = new ATCmdParser(_serial);
_parser->debug_on( 1 );
_parser->set_delimiter( “\r\n” );
bool result = false;
while(1){
_parser->send("AT");
int x = _serial->read(bufRead, 40);
printf("Response %s\n", bufRead);
printf("-> %d\n", x);
thread_sleep_for(2000);
}
}

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.

How to use C++ for transmitting data using xbee?

For a project i need to establish 2 way xbee communication. But I have a problem sending data from my pc. I use cpp with termios to transmitt a char array but on the xbee tx pin I do only get a signal (I observe this on an oscilloscope) when one of the chars is 0x0A.
The XBee module is on a 30011662-02 board, which is connected to my pc via usb.
I thought maybe this is some kind of starting parameter needed by the xbee board to transmit but couldnt find any information on this.
ctx->debug = debug;
//open USB port for read/write and check success
ctx->fd = open(devFileName, O_RDWR | O_NOCTTY); //opens the usb port for reading
if (ctx->fd < 0) {
cerr << "Could not open the USB Port. Try adding User to group dialout!" << endl;
return 0;
}
//is the opened port a terminal?
if(!isatty(ctx->fd)) {
close(ctx->fd);
errno = ENOTTY;
return 0;
}
//setup termios
tcgetattr(ctx->fd, &(ctx->oldtio));
cfmakeraw(&newtio);
cfsetispeed(&newtio, baudrate);
cfsetospeed(&newtio, baudrate);
tcsetattr(ctx->fd, TCSANOW, &newtio); //connects fd to newtio
tcflush(ctx->fd, TCIOFLUSH); //discards data not transmitted or received
lseek(ctx->fd, 0, SEEK_END);
ctx->bufIO = fdopen(ctx->fd, "r+");
bool connection_status=0;
unsigned char frame_id=0x00;
unsigned char checksum=0xff;
int j=0;
while(!connection_status){
checksum=0xFF;
unsigned char buffer[] = {
0x7E, //start delimiter
0x00,0x07,//length of the data packet
0x01,//API identifier (refer to XBee module manual for further details)
frame_id++, //frame id
0x00,0x0B,//destination address
0x00,//options
0x02,0x03,//data: 0,receiver address,mode
0x00}; //checksumm
for(unsigned int i=0;i<sizeof(buffer);i++){
checksum-=buffer[i];
}
cout << buffer << endl;
j++;
buffer[10]=checksum;
fwrite(buffer,sizeof(char),sizeof(buffer),ctx->bufIO);
usleep(2000000);
}
I do expect to see data on the xbee tx pin in every itteration of the while loop but so far it only works when frame_id is 0x0A or i manually enter 0x0A in the array buffer. But still it does not seem to be sending the correct data. Maybe you have some hints for me.
You're probably missing a setting (maybe O_NDELAY?) for the serial port (tty) and it's in line mode. You might want to look at this serial driver used in an Open Source XBee Host Library written in ANSI C (instead of C++). You might even be able to build your application on top of that library. At the very least, you could compile the samples and see if they work with your module as a way to verify your wiring and XBee configuration.

Arduino does not support messages larger than 65535 characters using websocket protocol?

I'm using the following Arduino websocket library, I had a problem when trying to send messages over than 65535 characters, I got handshake fail error.
As long as the message doesn't exceeds this length, it worked perfectly
There's a note on the main web page of the library that states:
Because of limitations of the current Arduino platform (Uno at the time of this writing),
this library does not support messages larger than 65535 characters.
In addition, this library only supports single-frame text frames.
It currently does not recognize continuation frames, binary frames, or ping/pong frames.
In the client header file named WebSocketClient.h there's the following comment:
// Don't allow the client to send big frames of data. This will flood the arduino memory and might even crash it.
#ifndef MAX_FRAME_LENGTH
#define MAX_FRAME_LENGTH 256
#endif
I'm using this old library because it is the only one worked for me on my Arduino WIFI shield, I couldn't find other libraries that support WiFi shield since most of the webscket libraries are written for Arduino Eathernet Shield support, which I don't have.
My Arduino Code is
/*DS18 Libs*/
#include <dht.h>
#include <OneWire.h>
#include <DallasTemperature.h>
/*Websocket Libs*/
#include <WebSocketServer.h>
#include <WebSocketClient.h>
#include <sha1.h>
#include <MD5.h>
#include <global.h>
#include <Base64.h>
#include <SPI.h>
#include <WiFiUdp.h>
#include <WiFiServer.h>
#include <WiFiClient.h>
#include <WiFi.h>
#include <string.h>
char ssid[] = "AMM";
char pass[] = "027274792";
int status = WL_IDLE_STATUS;
IPAddress server(192, 168, 1, 3);
WiFiClient WiFiclient;
WebSocketClient WSclient;
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
//Humidture
dht DHT;
#define DHT11_PIN 4
void setup()
{
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
//check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue:
while (true);
}
// attempt to connect to Wifi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
}
// you're connected now, so print out the data:
Serial.print("You're connected to the network");
/* Connect to the websocket server*/
if (WiFiclient.connect(server, 8080)) {
Serial.println("Connected");
}
else {
Serial.println("Connection failed.");
while (1) {
// Hang on failure
}
}
// Handshake with the server
WSclient.path = "/MyServer/endpoint/testtest/device/d6220ae7-caa9-48b5-92db-630c4c296ec4";
WSclient.host = "192.168.1.3:8080";
if (WSclient.handshake(WiFiclient)) {
Serial.println("Handshake successful");
}
else {
Serial.println("Handshake failed.");
while (1) {
// Hang on failure
}
}
/*DS18*/
sensors.begin();
}
void loop()
{
WSclient.sendData("{\"service_code\":\"89c4da72-a561-47db-bf62-8e63f8c4bbf0\",\"data\":[" + getHumidtureValue() + "],\"service_type\":\"TemperatureHumidityAnalysis\"}");
WSclient.sendData("{\"service_code\":\"bdc0f984-6550-4712-881f-b09071da5a73\",\"data\":" + getCBodyTempretureValue() + ",\"service_type\":\"TemperatureGaugeMonitor\"}");
//line-3 commented WSclient.sendData("{\"service_code\":\"8c212432-a86e-4c18-a956-9dc0dbb648d4\",\"data\":[" + getHumidtureValue() + "],\"service_type\":\"HumidityGaugeMonitor\"}");
}
String getCBodyTempretureValue()
{
sensors.requestTemperatures(); // Send the command to get temperatures
char charVal[10];
return dtostrf(sensors.getTempCByIndex(0), 4, 2, charVal);
}
String getHumidtureValue()
{
String str = "";
for (int i = 0; i < 2; i++)
{
int chk = DHT.read11(DHT11_PIN);
switch (chk)
{
case DHTLIB_OK:
Serial.println("OK,\t");
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.println("Checksum error,\t");
break;
case DHTLIB_ERROR_TIMEOUT:
Serial.println("Time out error,\t");
break;
default:
Serial.println("Unknown error,\t");
break;
}
char charVal[10];
double tempF = (DHT.temperature * 9) / 5 + 32;
str = dtostrf(tempF, 3, 1, charVal);
str = str + "," + dtostrf(DHT.humidity, 3, 1, charVal);
Serial.println(str);
delay(200);
}
return str;
}
The code above works perfectly, when I uncomment the third send statement in the loop function, I got the handshake failed error.
-Is it safe to modify the value of MAX_FRAME_LENGTH for the new versions of Arduino board, considering this library is an old one?
-Is there any other libraries better than this one that can support websocket on WiFi shield?
Any solution or idea will appreciated.
Thanks in advance.
Without having looked at the code of the library it is likely not safe to change the max frame length, because the websocket protocol encodes the payload length differently depending on how long it is:
Payload length: 7 bits, 7+16 bits, or 7+64 bits.
The length of the "Payload data", in bytes: if 0-125, that is the payload length. If 126, the following 2 bytes interpreted as a 16-bit unsigned integer are the payload length. If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the most significant bit MUST be 0) are the payload length.
When the library says it doesn't support payload length above 65535 byte, it likely means that it has no implementation for the 64-bit length encoding.
After many trials and many times the program behaves very strangely, which drives me crazy, I found the problem is that I'm using too much strings in my program which makes the Arduino-Uno easily runs out of RAM.
The main reason I got handshake failed error is that the Arduino cannot read the "Sec-WebSocket-Accept" header of the handshake response message (as many other headers also) which I made sure that they are sent, by debugging code on the server.
Actually this problem and many other strange behaviors keep happening until I reduce the amount of the memory used during program run.

Serial communication between pc and arduino via RS232 using c++

I am trying to communicate with my arduino duemilanove via an RS232 cord. I simply want to be able to send a byte (or char) to my arduino from a desktop application. The Arduino is plugging into USB COM5 on my computer. I have the RS232 plugged into COM1, and then I have pins 2 3 and 5 on the other end of the RS232 connected to arduino pins TX, RX, and GND, respectively.
I found a serial comm class for c++ at the following link:
http://playground.arduino.cc/Interfacing/CPPWindows
I have added the .h and .cpp files from the above example as Serial.h and Serial.cpp (i think the example uses SerialClass.h and SerialClass.cpp, I just changes the names).
On my arduino, I have the following code running:
// ARDUINO
char incomingByte = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
Serial.print("I received: ");
Serial.println(incomingByte, HEX);
}
}
And my c++ program is the following:
// C++
#include <iostream>
#include <Windows.h>
#include "Serial.h"
using namespace std;
int main(void)
{
Serial port("COM1");
char* msg = "Hello Arduino!";
int msgLen = strlen(msg);
bool writeSuccess = port.WriteData(msg, msgLen);
cout << "\n\n";
system("PAUSE");
}
When I use the Arduino's serial port viewer to see what is bring printed, I'm getting very strange values that don't match what I'm sending (as far as I can tell).
When I send "Hello Arduino!", the arduino prints the following:
I received: FFFFFFAB
I received: 3A
I received: 3A
I received: A
I received: FFFFFFFA
I received: FFFFFFEB
I received: 6D
I received: 37
I received: 15
I received: 2D
I received: 23
I received: 21
I received: FFFFFFBD
I received: 0
This does not appear to be the correct hex for "Hello Arduino!", but I have no idea why it's not correct. Does anyone have any clue what I'm doing wrong?
Arduino used TTL logic for Serial connection. It expects values at 0 and 5V. RS232 used a different voltage -V to +V. You may need a converter.
Ehm... No! pull up and pull down are not for this reason..
TTL = low: 0V, high: 5V
RS232 = low: +3:+15V, high: -3:-15V
Consequently.. You need a voltage converter (and inverter), like David Skogan correctly pointed out.
Examples:
Using discrete components (has automatic echo feature, i.e. on the PC you will see the data you send): http://project.irone.org/simple-rs232-to-ttl-level-converter.html or http://circuit-diagram.hqew.net/Simple-TTL$2dRS232-Level-Converter-Using-Transistor_2757.html
Common circuit with a MAX232 (or equivalent) and four capacitors
Instead of using a USB-RS232 converter use a USB-UART one, using for instance a FT232 or something like that. This does not need any interface
Or.. simply use the USB port on the Arduino, which already has a FT232 on it.
Personal comment: i'd avoid solution 1...