Reading serial: also receiving characters I am sending - c++

I am communicating through Serial2 (arduino mega) by sending and receiving text.
95% of the time the communication goes well, but some of the text I am reading contains also parts of the text I am sending.
Code:
void setup (){
Serial.begin (19200);
while (!Serial) {
}
Serial1.begin(19200);
Serial2.begin (19200);
}
void loop (){
currentMillis = millis();
if(currentMillis > savedMillis + 1000){
Serial2.write("##geenbatterij##\r\n"); //check batterij
Serial2.write("##geensignaal##\r\n");
savedMillis = millis();
}
SerialEvent2zelf();
}
void serialEvent2zelf(){
if(Serial2.available()>0){
while (Serial2.available()){
processIncomingByte(Serial2.read ());
}
}
}
void processIncomingByte (const byte inByte){
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;
switch (inByte){
case '#': // end of text
input_line [input_pos] = 0; // terminating null byte
process_data (input_line);
input_pos = 0;
startSignReceived = false;
break;
// case '\r': // discard carriage return
// break;
case '#': // begin of text
startSignReceived = true;
break;
default:
if (input_pos < (MAX_INPUT - 1) && startSignReceived == true)
input_line [input_pos++] = inByte;
break;
}
}
Output (console reading):
odr/3.8
rnt/102h6m
as1/28.9
as2/28.8
ls1/0.1
ls2/0.1
bsn/82
kwt/74
wd1/4.7
wd2/0.7
rnt/102h6m
rpm/972
odr/3.7
rnt/102herijrnt/signaalrnt/102h6m //<-- see here
as1/28.9
as2/28.8
ls1/0.1
ls2/0.1
bsn/82
kwt/74
wd1/4.7
wd2/0.7
rnt/102h6m
rpm/981
odr/3.8
rnt/102h6m
as1/28.9
as2/28.8
ls1/0.1
ls2/0.1
What am I doing wrong and how to solve it? Thanks.

The fact that you have multiple instances of the Serial class is more than a little suspect because I am pretty sure you're only using a single serial port.
I'd suggest using only the first instance and completely removing serial1 and serial2.
Other notes :
code is missing. It could very well contain Undefined Behaviour
Maar weinig mensen lezen hier Nederlands. Het is niet de conventie om Nederlands te mengen met code

Related

Understanding a function that reads data from a serial port

I'm struggling to understand what is happening in part of an Arduino program I wrote, I copied the switch in processInput from another post about reading data from serial ports but have changed it a bit since then.
To me it seems like the output to the LCD screen should always be 0 since recievedNumber is set to 0 at the beginning of the function, it does output the data from the serial port correctly though. I'm also not sure what is happening on the line "receivedNumber += b - '0';" inside the last case.
Any advice or a breakdown of the logic would be appreciated, I intended to replace the last case with an if statement to learn how to do it without using the GNU extension but I just don't understand what is happening.
An example of data in the serial port:
<45,56><55,54>
Sorry if this is the wrong place but it felt too related to programming to post on the Arduino StackExchage.
const char startOfNumberDelimiter = '<';
const char middleOfNumbersDelimiter = ',';
const char endOfNumberDelimiter = '>';
void processNumberC (const long c)
{
lcd.setCursor(10,0);
lcd.print(c);
lcd.print("C");
}
void processNumberG (const long g)
{
lcd.setCursor(10,1);
lcd.print(g);
lcd.print("C");
}
void processInput ()
{
static long receivedNumber = 0;
byte b = Serial.read ();
switch (b)
{
case middleOfNumbersDelimiter:
processNumberC (receivedNumber);
receivedNumber = 0;
break;
case endOfNumberDelimiter:
processNumberG (receivedNumber);
break;
case startOfNumberDelimiter:
receivedNumber = 0;
break;
case '0' ... '9':
receivedNumber *= 10;
receivedNumber += b - '0';
break;
} // end of switch
} // end of processInput
void loop()
{
while (Serial.available ())
processInput ();
}

How to get the progress of a TRichEdit?

I have a simple 'brut' big text file (20MB). I would like to show it in a TRichEdit. The problem is that it takes 6 seconds for the showing. I would like to put a progess bar in the bottom of the application to avoid this bad UX design.
My question is how to get the progress of the TRichEdit showing ? With the TRichEdit::LoadFromStream method, it goes from 0 to 100% fast (less than 1 second) but after the application wait 6 secondes during the first show.
I created this class FileStreamProgress with TFileStream inherit. I overide the TFileStream::Read()
int __fastcall FileStreamProgress::Read(void *Buffer, int Count)
{
__int64 previousPosition = this->Position;
int ret = TFileStream::Read(Buffer, Count);
if (this->Position == 0 || this->Position == this->Size || (previousPosition/128000) != (this->Position/128000)) {
ProgressCallBack(ProgressCallBackParam1, this->Position, this->Size);
}
return ret;
}
static void FileStreamProgress::ProgressCallBack(void*thiz, int i, int max)
{
TProgressBar* ProgressBar = (TProgressBar*)thiz;
if (ProgressBar)
{
if (max > 0)
{
ProgressBar->Position = int(i * 100 / max);
}
if (Application)
{
Sleep(1);
Application->ProcessMessages();
}
}
}
This is how I test it :
void MyApp::CreatePage(AnsiString filename)
{
ProgressBar->Visible = true;
FileStreamProgress::ProgressCallBackParam1 = (void*)this->ProgressBar;
TFileStream * stream = new FileStreamProgress(filename.c_str(), fmOpenRead);
TPageMemo* Page = new TPageMemo(this);
Page->Parent = PControl;
Page->PageControl = PControl;
MessageDlg("111",mtError,TMsgDlgButtons()<<mbOK,0);
Page->Texte->Lines->LoadFromStream(stream);
MessageDlg("222",mtError,TMsgDlgButtons()<<mbOK,0);
PControl->ActivePage = Page;
}
There are 7 secondes between the 2 message dialogs "111" and "222". And my progress bar wait 6 secondes at 100% (during the showing)
I tried to go deeper with the win32 API's SendMessage and Handle without the expected result.
At the end, I used a TMemo yesterday cuz it's a brut text. It's very fast (instant open) but some functions are missing like FindTextW(). I rewrote it. Thanks
http://docwiki.embarcadero.com/RADStudio/Rio/en/Memo_and_Rich_Edit_Controls
was curious so I tested the TRichEdit and came up with this:
//---------------------------------------------------------------------------
void load_text(TRichEdit *re,AnsiString filename,TProgressBar *pb)
{
// variables
int hnd,adr,siz,len,i;
const int _buf=128*1024; // buffer size
AnsiString s,s0;
char buf[_buf+1];
// open file and detect size
hnd=FileOpen(filename,fmOpenRead); if (hnd<0) return;
siz=FileSeek(hnd,0,2);
FileSeek(hnd,0,0);
// prepare progress bar
pb->Position=0;
pb->Max=siz;
pb->Visible=true;
// process txt file by chunks
for (s0="",adr=0;adr<siz;)
{
// update progress bar and GUI
pb->Position=adr;
Application->ProcessMessages();
// load chunk
len=FileRead(hnd,buf,_buf);
adr+=len; buf[len]=0;
// handle cutted lines by chunk size
s=s0; s0="";
// ignore last 2 lines for chunks (except last chunk)
if (len==_buf)
{
// skip last line
for (i=len-1;i>=0;i--)
if ((buf[i]==13)||(buf[i]==10))
{
i--;
if (i>=0)
if (buf[i]!=buf[i+1]) // different eol code to ignore empty line
if ((buf[i]==13)||(buf[i]==10)) // eol code
i--;
break;
}
// skip another line to avoid inserting empty line if eol is cutted
for (;i>=0;i--)
if ((buf[i]==13)||(buf[i]==10))
{
s0+=buf+i+1; // copy last 2 lines into s0
i--;
if (i>=0)
if (buf[i]!=buf[i+1]) // different eol code to ignore empty line
if ((buf[i]==13)||(buf[i]==10)) // eol code
i--;
i++; if (i<0) i=0; buf[i]=0; // end of string
break;
}
}
// last chunk ignore last eol
else{
// skip last line
i=len-1;
if ((buf[i]==13)||(buf[i]==10)) // eol code
{
i--;
if (buf[i]!=buf[i+1]) // different eol code to ignore empty line
if ((buf[i]==13)||(buf[i]==10)) // eol code
i--;
i++; if (i<0) i=0; buf[i]=0; // end of string
}
}
// add actual chunk
s+=buf;
re->Lines->Add(s);
}
// tidy up
pb->Visible=false;
FileClose(hnd); hnd=-1;
}
//---------------------------------------------------------------------------
Looks like it works without the ending pause you describe however that might be related to version of IDE/VCL/compiler I am using BDS2006 Turbo C++. When Tested on ~23 MByte STL file the load time is ~10sec (TMemo takes twice of that god know why)...
The saved file (while PlainText=true) is identical to the loaded one so the code should be correct.
Here animated GIF of preview:
while used like this:
void __fastcall TForm1::FormActivate(TObject *Sender)
{
//tbeg();
load_text(re_txt,"in.txt",pb_progress);
//tend();
//Caption=tstr();
re_txt->Lines->SaveToFile("out.txt");
}
where pb_progress is the TProgressBar and and re_txt is the TRichEdit.
As you can see no callback is needed ...
PS. If you want to measure the time like I did (the commented lines) the implementations of tbeg/tend/tstr functions are here:
performance.h

xlib XNextEvent checking if a key is held down

I am using xlib to get keyboard input I want to simulate windows its getAsynckeystate() to check if a button is being pressed I tried using a timer to fix the result but its still broken. the function should always return true if 'z' is held down even if other keys are pressed or released at the same time (not working right now)
Code below
bool KeyboardState::keyPressed(Display* d, Window curFocus,int revert, Window root) {
XEvent ev;
XNextEvent(d, &ev);
clock_t startTime;
switch (ev.type) {
case FocusOut:
if (curFocus != root)
XSelectInput(d, curFocus, 0);
XGetInputFocus(d, &curFocus, &revert);
printf("New focus is %d\n", (int) curFocus);
if (curFocus == PointerRoot)
curFocus = root;
XSelectInput(d, curFocus, KeyReleaseMask | FocusChangeMask | KeyPressMask);
break;
case KeyPress:
ks = XLookupKeysym(&(ev.xkey), 0);
if (ks == XK_z) {
keyState = true;
startTime = clock();
}
break;
case KeyRelease:
if(ks == XK_z && startTime - clock() > 0){
ks = XLookupKeysym(&(ev.xkey), 0);
keyState = false;
}
}
return keyState;
}
n.m linked following function which is accepted as answer:
tronche.com/gui/x/xlib/input/XQueryKeymap.html
I wrote the following code snippet to help do keyboard shortcuts with multiple non-modifier keys e.g. super + up + right.
#include <X11/Xlib.h>
// Returns 0 if key is not down;
// A non-zero integer if it is down.
// targetString should be appropriate for XStringToKeysym.
int is_down(Display *dis, char *targetString)
{
char keys_return[32] = {0};
KeySym targetSym = XStringToKeysym(targetString);
KeyCode targetCode = XKeysymToKeycode(dis, targetSym);
int targetByte = targetCode / 8;
int targetBit = targetCode % 8;
int targetMask = 0x01 << targetBit;
XQueryKeymap(dis, keys_return);
return keys_return[targetByte] & targetMask;
}
I've posted a more complete example with compilation instructions on GitHub. You can find a complete list of key names in a file named X11/keysymdef.h; on my Arch computer it was at /usr/include/X11/keysymdef.h. I also found an example on the web as the second Google result for x11 keysymdef.

How do I convert my GPS NEMA sentences to a string using an Arduino?

I am attempting to parse information from a GPS module using an Arduino Uno. My thought was to convert the NEMA sentences to strings, then use a simple code to split the comma separated text into groups. Once that is accomplished I can then display certain portions of those groups to a screen.
Is this possible? I have included my very simple code below. Please keep in mind I am a beginner when it comes to code.
int rxPin = 0; // RX PIN
int txPin = 1; // TX TX
String text = Serial.read();
String message = text;
int commaPostion;
void setup() {
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
Serial.begin(4800);
Serial.println(message);
do{
commaPosition = message.indexof(',');
if(commaPosition != -1)
{
Serial.println(message.substring(0,commaPosition));
message = message.substring(commaPosition+1, message.length());
}
else
{ //here after last comma is found
if(message.length() > 0)
Serial.println(message);
}
while(commaPosition >=0);
{
}
void loop() {
}
In programming, laziness is a virtue. Why reinvent the wheel, right?
Check out the TinyGPS library designed to do exactly what you're trying to accomplish.

How to write nested if or case to make a prompted input menu?

I'm working on an experience design project for one of my classes using a rotary phone and arduino kit to create a game based on automated phone menus. Serial input from the rotary dial is running through arduino and now I am using processing to write the menu.
I have an outline of actions and have started to code some if then statements to get going but now I have stumbled upon case and switch.
I am completely new to this but have learned a lot in class.
My question is how do I make a continuous set of nested if/then statments OR use case and switch to move through a series of prompts and inputs?
Here is my sketch so far:
import processing.serial.*;
Serial port; // Create object from Serial class
float val; // Data received from the serial port
boolean task1prompted;
boolean task1;
boolean task2;
boolean dialed;
PFont font;
void setup() {
size(800, 400);
background(0, 0, 0);
smooth();
// IMPORTANT NOTE:
// The first serial port retrieved by Serial.list()
// should be your Arduino. If not, uncomment the next
// line by deleting the // before it. Run the sketch
// again to see a list of serial ports. Then, change
// the 0 in between [ and ] to the number of the port
// that your Arduino is connected to.
//println(Serial.list());
String arduinoPort = Serial.list()[0];
port = new Serial(this, arduinoPort, 9600);
task1 = false;
task2 = false;
task1prompted = false;
font = createFont("Arial", 32);
textFont(font, 32);
textAlign(CENTER);
}
void draw() {
if (port.available() > 0) { // If data is available,
val = port.read(); // read it and store it in val
if (val >= 48 && val <= 57) {
val = map(val, 48, 57, 0, 9); // Convert the value
}
println(val);
}
if (val == 97) {
println("dialing");
}
if (val == 98){
println("dialed");
dialed = true;
}
/// switch will activate the task1 variable.
// Play sound file for the prompt.
if (task1prompted == false){
delay(1000);
println("for spanish, press one. for french, press 2...");
task1prompted = true;
}
task1 = true;
if (task1 == true && dialed == true) {
///play sound file
if (val == 5) {
println("Thank you for playing... Blah blah next prompt.");
dialed = true;
task1=false;
task2=true;
} else
if (val != 5) {
println("We're sorry, all of our international operators are busy");
task1 = true;
task2 = false;
dialed = false;
}
}
else
if (task2 == true){
delay(1000);
println("task2 start");
}
}
My instructor helped me to get this far and I have been scouring for answers on how to keep going on to the next task/prompt. Would it be easier to use case and switch? And am I even doing nested if statements the right way?
Well I just tried this out with sketch and case commands as follows:
/// Switch will activate the task1 variable.
// Play sound file for the prompt.
if (task1prompted == false){
delay(1000);
println("for spanish, press one. for french, press 2...");
task1prompted = true;
}
task1 = true;
if (task1 == true && dialed == true) {
///Play sound file
int lang = (int)(val+0);
switch(lang) {
case 1:
case 2:
case 3:
case 4:
println("sorry no international operators"); // If 1-4 go back to choices
task1 = true;
task2 = false;
dialed = false;
break;
case 5:
println("thank you, move to next prompt"); // If 5 go to next prompt
task1=false;
task2=true;
dialed = true;
break;
case 6:
case 7:
case 8:
case 9:
case 0:
println("not a valid option, you lose"); // If not 1-5 go back to beginning
task1=false;
task2=false;
dialed = true;
break;
}
if (task2prompted == false){
delay(1000);
println("please listen while we test the line");
task2prompted = true;
}
task2 = true;
if (task2 == true && dialed == true) {
} ///Play sound file
int tone = (int)(val+0);
switch(tone) {
case 1:
case 2:
case 3:
case 5:
case 6:
case 7:
case 8:
case 9:
case 0:
println("not a valid connection, you lose"); // If not 4 go back to beginning
task2 = false;
task3 = false;
dialed = false;
break;
case 4:
println("thank you, move to next prompt"); // If 4 move to next prompt
task2=false;
task3=true;
dialed = true;
break;
}
}
}
I'm still confused on how to make this have levels and not all happen simultaneously.
You might want to look up finite state machines. It's a pretty common approach to dealing with event driven user interfaces.
I'm not entirely sure what your question is but maybe something here will answer it, if not just clarify what you're looking for
With case statements you don't need to make a case for every single output that can happen. the way you can avoid doing that is by using a default statement
Example:
switch(tone) {
case 4:
println("thank you, move to next prompt"); // If 4 move to next prompt
task2=false;
task3=true;
dialed = true;
break;
default:
println("not a valid connection, you lose"); // If not 4 go back to beginning
task2 = false;
task3 = false;
dialed = false;
}
The default case doesn't need a break because it is at the end. But essentially it is the catch all case if nothing else is hit.
Also in some of your code above
if (val == 97) {
println("dialing");
}
if (val == 98){
println("dialed");
dialed = true;
}
it is better to use an "else if" to make it not have to check through both if one is correct
if (val == 97) {
println("dialing");
}
else if (val == 98){
println("dialed");
dialed = true;
}