String extraction issue in Arduino - c++

I have the following Arduino code
#include "SIM900.h"
#include <SoftwareSerial.h>
#include "inetGSM.h"
#include<String.h>
InetGSM inet;
char msg[165];
char store[2];
char a;
char b;
char* disp;
boolean started=false;
void setup()
{
//Serial connection.
Serial.begin(9600);
Serial.println("GSM Shield testing.");
//Start configuration of shield with baudrate.
//For http uses is raccomanded to use 4800 or slower.
if (gsm.begin(2400)) {
Serial.println("\nstatus=READY");
started=true;
} else Serial.println("\nstatus=IDLE");
if(started)
{
//GPRS attach, put in order APN, username and password.
//If no needed auth let them blank.
if (inet.attachGPRS("TATA.DOCOMO.INTERNET", "", ""))
Serial.println("status=ATTACHED");
else Serial.println("status=ERROR");
delay(1000);
//TCP Client GET, send a GET request to the server and
//save the reply.
inet.httpGET("www.boat.esy.es", 80, "/retrieve.php", msg, 165);
//Print the results.
Serial.println("\nData received:");
disp = strstr(msg,"\r\n\r\n");
disp = disp+4;
a = disp[1];
b = disp[2];
}
}
void loop()
{
Serial.println("Begin");
Serial.println(a);
Serial.println("+");
Serial.println(b);
Serial.println("End");
delay(500);
}
The disp variable in my program accepts the value 1 & 1 as string. I want this 1 & 1 to be stored in two separate variables. SO I tried the way mentioned above and this is what I got
Output
Begin
1
+
End
Begin
1
+
End
Begin
1
+
End
If I understand array correctly, char arr[100] is same as char* arr, just that the former one reserves 100 character locations on the memory, then b = disp[2] should give the latter 1 of 11 right?
I am not trying to use the String library because that will occupy a lot of memory. So if there's any way that I'm not aware of that extract both the 1s & store them separately, please let me know.
Thank you for your time!

Your code is almost correct.
The problem is here:
disp = strstr(msg,"\r\n\r\n");
disp = disp+4; // now disp points to the string "11" (correct)
// what follows is wrong
a = disp[1]; // this is the second char element if the disp string
b = disp[2]; // this is the zero terminator of the disp string
You need this because in C arrays indexes start with 0:
a = disp[0];
b = disp[1];
Small test program:
#include <stdio.h>
#include <string.h>
int main()
{
char *disp;
char msg[] = "Fake Header\r\n\r\n12";
char a;
char b;
disp = strstr(msg,"\r\n\r\n");
disp = disp+4;
a = disp[0];
b = disp[1];
printf("a = %c\nb = %c\n", a, b);
return 0;
}
Output:
a = 1
b = 2

There are quite a few problems with your code here...
Firstly, all your variables are un-initialised and you're accessing them after their declaration without initially giving them any value in memory. To solve this set each variable to something before you continue on like so:
char a = ''; // & so on...
Next up, char* disp; is a pointer, not a variable. You dont actually know the physical location of disp, it points to somewhere it memory, maybe a bit of populated memory, maybe nothing at all. So the best way to store something in disp is to turn it into an array and they write to it part by part reading when you need and terminating the variable with the correct formatting.
e.g
char disp[2] = {}; // Declare disp...
disp[0] = '1'; // Write to disp...
disp[1] = '1';
disp[2] = '\0';
& finally the webserver you're connecting too has DynDNS attached to the address, and anybody can access it without a password and anybody can start attacking it, so I would hide it.

Related

Unable to understand libusb API

I am working in libusb and have minimal knowledge on C++. I am trying to understand the API of libusb and write code accordingly. But I am unable to understand how to declare and use variables as variable or pointer or double or triple pointer.
The below code is from question. How to find what level of pointers to be used while declaring these variables from the API documentation. Is there any documentation or tutorial videos that explains these things.
libusb_context *context = NULL ;
libusb_device_handle *dev_handle = NULL ;
libusb_device **devs ;
int rc = 0 ;
ssize_t count ; //holding number of devices in list
For example, consider libusb_device_handle. How to declare this and use it?
typedef struct libusb_device_handle libusb_device_handle
The syntax of libusb_strerror() is const char * libusb_strerror (int errcode). The function returns constant string. Should I declare a char or char array or string to read the returned value. If the below way of usage right?
char char *err_code;//declaration
err_code = libusb_strerror(rc);
if the returned value is a string, then how can a characer pointer hold it?
An example would be really helpful.
3)Here is my entire code. I can open the device. But the bulk transfer command returns 5 and fails. I am not sure at which part I am making mistake.
#include <iostream>
#include "libusb.h"
#define IN_EP 0x81
#define OUT_EP 0x02
int main(){
libusb_context *context = NULL;
libusb_device_handle *dev_handle = NULL ;
libusb_device **devs ;
int rc = 100 ;
//ssize_t count ; //holding number of devices in list
unsigned int vid=0x1234;
unsigned int pid=0x5678;
unsigned char data[10];
data[0]=128;
int transferred = 0;
unsigned int timeout = 5000;
//std::string str[100];
const char* err_code;
rc = libusb_set_option(context, LIBUSB_OPTION_LOG_LEVEL,2);
if (rc==0){ std::cout<<"libusb_setOption worked:"<<rc<<"\n"; }
else{ std::cout<<"libusb_setOption_Failed:"<<rc<<"\n"; }
rc = libusb_init(&context);
if (rc==0){ std::cout<<"libusb_init worked:"<<rc<<"\n"; }
else{ std::cout<<"libusb_init Failed"<<rc<<"\n"; }
dev_handle = libusb_open_device_with_vid_pid(context,vid,pid);
if (dev_handle == NULL){
std::cout<<"libusb_open Failed"<<"\n";
libusb_exit(context);std::cout<<"libusb_exit"<<"\n";exit(1); }
else{ std::cout<<"libusb_opened"<<"\n"; }
rc = libusb_bulk_transfer(dev_handle,OUT_EP,data,1,&transferred, timeout); //Send data to device
if (rc==0){ std::cout<<"libusb_write worked:"<<rc<<"; Wrote "<<transferred<<" bytes\n"; }
else{ std::cout<<"libusb__Write failed"<<rc<<"; Wrote "<<transferred<<" bytes\n"; }
err_code = libusb_strerror(rc);
rc = libusb_bulk_transfer(dev_handle,IN_EP,data,3,&transferred, timeout); //Read data from device
if (rc==0){ std::cout<<"libusb_read worked:"<<rc<<" ; Read"<<transferred<<" bytes; Data:"<<data<<"\n";
std::cout<<data[0]<<" "<<data[1]<<" "<<data[2]<<"\n"; }
else{ std::cout<<"libusb__read failed"<<rc<<"; Read "<<transferred<<" bytes\n"; }
libusb_close(dev_handle);
std::cout<<"libusb_close"<<"\n";
libusb_exit(context);
std::cout<<"libusb_close"<<"\n";
return 0;
}
Any help will be appreciated.
[...] For example, consider libusb_device_handle. How to declare this and use it?
You declare it exactly like in your code:
libusb_device_handle *dev_handle = NULL;
Because libusb_open_device_with_vid_pid() returns a pointer to libusb_device_handle, your dev_handle must also be a pointer to that.
You might be confused because of devs being a pointer-to-pointer. This is because it is actually returning a pointer to an array, but since you are not even using that in your code, I would forget about it for now.
The syntax of libusb_strerror() is const char * libusb_strerror (int errcode). The function returns constant string. Should I declare a char or char array or string to read the returned value?
You should declare a variable exactly the same as the return type of libusb_strerror(), thus:
const char *err_string;
err_string = libusb_strerror(rc);
If the returned value is a string, then how can a characer pointer hold it?
The returned value is a pointer, you just make a copy of the pointer. The pointer points to some part of memory where the string is stored. You don't have to worry about how libusb allocated it.
I can open the device. But the bulk transfer command returns 5 and fails. I am not sure at which part I am making mistake.
The code looks mostly fine, except you want to call libusb_strerror() after the second call to libusb_bulk_transfer(), not right before it. Error code -5 is LIBUSB_ERROR_NOT_FOUND. This might mean it didn't find the endpoint. Are you sure IN_EP and OUT_EP are set correctly?

CHAR Compare is right, even when it's wrong

first im new at c++ programming and at the moment im stuck in a maybe very easy problem.
I thought, after get the other stuff working and in my oppinion, much harder, i will implement a little string compare and im are ready, ha ha...
I tryed to figure out what is the problem and working on it since hours...
I try to make a string compare.
With serial print i see the correct letters. For Example i compare "A" and "B".
My Problem is, that this compare is right, even when it's wrong.
bool debug = true;
void setup() {
// put your setup code here, to run once:
if (debug) { Serial.begin(9600); }; // Initialize serial communications with the PC
}
void loop() {
int result;
char myWord[6] = "#VOGEL";
char wordBuff[5];
char wordLetter;
char letterBuff;
// I do this here, because actually i get all values from two RFID Reader
strncpy( wordBuff, &myWord[1], 5 );
wordBuff[5] = '\0';
for (int fieldNr = 0; fieldNr < 5; fieldNr++)
{
wordLetter = wordBuff[fieldNr];
letterBuff = 'L';
result = strcmp(letterBuff,wordLetter); // Should be every time wrong? But it is sometimes true?
if ( result == 0)
{
if(debug){ Serial.print(F("Right Field: "));Serial.println(fieldNr);
Serial.print(F(" LetterA: "));Serial.print(wordLetter);Serial.println(F("#"));
Serial.print(F(" LetterB: "));Serial.print(letterBuff);Serial.println(F("#"));}
}
else
{
if(debug){ Serial.print(F("Wrong Field: "));Serial.println(fieldNr);
Serial.print(F(" LetterA: "));Serial.print(wordLetter);Serial.println(F("#"));
Serial.print(F(" LetterB: "));Serial.print(letterBuff);Serial.println(F("#"));}
}
}
delay(1000); //NUR für TESTZWECKE
}
strcmp is only for const char *, not a single char like you are using it.
I don't remember if Arduino permits you to use the std::string but in case just use it.
It introduce you lot more methods for string handling. Like s.find(c) that return directly the position of the char in the string.
By the way, to compare 2 char, in your example, just use a simple:
if(c1 == c2)
...
else
...
It should solve it.

Writing Char to Arduino EEPROM

I'm having a problem passing data to EEPROM. It seemed to be not accepting a char variable. I'm doing exactly what is told here: https://www.arduino.cc/en/Reference/EEPROMPut
So my this is my Object Structure
struct DeviceDataObject {
bool flag;
char data[20];
char data2[20];
int rate1;
int rate2;
int rate3;
};
So as I test with:
int RATES[3] = {300, 1500, 3600};
DeviceDataObject new_data = {true, "Data1Sample", "Sample2", RATES[0], RATES[1], RATES[2]};
WRITE_Device(new_data);
Here's my writing function
void WRITE_Device(DeviceDataObject data) {
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
int eeAddress = 0;
float f = 123.456f; //Variable to store in EEPROM.
EEPROM.put(eeAddress, f);
eeAddress += sizeof(float); //Move address to the next byte after float 'f'.
EEPROM.put(eeAddress, data);
//Serial.println("Memory Data Updated");
}
Everything seemed to be OK. But if I replace "Data1Sample" and "Sample2" with a variable, EEPROM's data seemed to be changed in incorrectly.
void ChangeValue(String value) {
int RATES[3] = {300, 1500, 3600};
char charBuf[20];
value.toCharArray(charBuf, 20); //Convert to char
DeviceDataObject new_data = {true, "", {charBuf}, RATES[0], RATES[1], RATES[2]}
WRITE_Device(new_data);
}
What could be the mistake?
Looks like a pointer problem, try this
void ChangeValue(String value) {
int RATES[3] = {300, 1500, 3600};
DeviceDataObject new_data = {true, "", "", RATES[0], RATES[1], RATES[2]}
value.toCharArray(new_data.data2, 20); //Convert to char
WRITE_Device(new_data);
}
(you were creating a string where the first character was the pointer to your stack variable charBuf, rather than copying the string)
A somewhat long-winded approach would be to write each element of the structure to EEPROM individually. The code would look something like this and should allow you to isolate any issues more effectively.
ee_address = 0;
EEPROM.put(ee_address, new_data.flag);
ee_address += sizeof(new_data.flag); // Update address to store next variable
EEPROM.put(ee_address, new_data.data);
ee_address += sizeof(new_data.data);
EEPROM.put(ee_address, new_data.data2);
ee_address += sizeof(rawdata.data2);
EEPROM.put(ee_address, new_data.rate1);
ee_address += sizeof(new_data.rate1);
EEPROM.put(ee_address, new_data.rate2);
ee_address += sizeof(new_data.rate2);
EEPROM.put(ee_address, new_data.rate3);
ee_address += sizeof(rawdata.rate3);
This will make it easier to troubleshoot whether variables are not being written to EEPROM correctly or whether the issue stems from something else.
This is the approach I typically take when storing structures which I have defined to the EEPROM, as it gives more control when retrieving this information from the EEPROM at a later point.
I'll be the first to admit this is perhaps not the most elegant solution, but it should help address your issues.

Displaying element from pointer struct

I have run onto a little problem and I have looked everywhere but I believe I am looking in the wrong direction. I created an account here in hopes of solving a slight issue I have. I am in the middle of programming an RPG and when I attempt to display one characters "magic spells", I can only display [3]. [0] [1] [2] crashes my game. Game is in C++.
Example of my code below:
Create my struct:
struct Fighter {
int HP; //max 999
int maxHP;
int MP; //max 999
int maxMP;
int STR; //max 255
int CON; //max 255
int AGL; //max 100
bool dead;
const char* Magic[];
};
Fighter * player = new Fighter[5];
Initializing and assigning elements with these parameters for 4 party members:
void InitPlayer(int pClass, int p)
{
if(pClass == 0) //Knight
{
player[p].maxHP = 750;
player[p].HP = player[p].maxHP;
player[p].maxMP = 0;
player[p].MP = player[p].maxMP;
player[p].STR = 200;
player[p].CON = 0;
player[p].AGL = 35;
}
else if(pClass == 1) //Ninja
{
player[p].maxHP = 675;
player[p].HP = player[p].maxHP;
player[p].maxMP = 0;
player[p].MP = player[p].maxMP;
player[p].STR = 175;
player[p].CON = 0;
player[p].AGL = 80;
player[p].Magic[0] = "Cure";
player[p].Magic[1] = "Haste";
player[p].Magic[2] = "Sleep";
}
//... More Character code
}
Here I draw/print "Magic" to the screen:
Printf_xy(123,223,player[0].Magic[0]); //Crash
Printf_xy(123,233,player[1].Magic[0]); //Crash
Printf_xy(123,243,player[2].Magic[0]); //Crash
Printf_xy(123,253,player[3].Magic[0]); //Prints "Cure" does not crash
As you can see, it will work but only if I display player[3]. I am sure I am forgetting to do something or initializing something incorrectly. Any help would be greatly appreciated.
Magic is a zero length array - when you assign anything into it, or even try to access Magic[0] you are accessing outside of the array boundaries.
If you know the maximum number of magic entries you need, use that as your array size, something like:
const int MagicLimit = 10
...
const char* Magic[MagicLimit];
Better still, if you are using c++, use a std::vector to hold the magic strings (also use std::string), that way you can easily tell the length of the list.
For example:
std::vector<std::string> Magic;

Why does my array element retrieval function return random value?

I am trying to make an own simple string implementation in C++. My implementation is not \0 delimited, but uses the first element in my character array (the data structure I have chosen to implement the string) as the length of the string.
In essence, I have this as my data structure: typedef char * arrayString; and I have got the following as the implementation of some primal string manipulating routines:
#include "stdafx.h"
#include <iostream>
#include "new_string.h"
// Our string implementation will store the
// length of the string in the first byte of
// the string.
int getLength(const arrayString &s1) {
return s1[0] - '0';
}
void append_str(arrayString &s, char c) {
int length = getLength(s); // get the length of our current string
length++; // account for the new character
arrayString newString = new char[length]; // create a new heap allocated string
newString[0] = length;
// fill the string with the old contents
for (int counter = 1; counter < length; counter++) {
newString[counter] = s[counter];
}
// append the new character
newString[length - 1] = c;
delete[] s; // prevent a memory leak
s = newString;
}
void display(const arrayString &s1) {
int max = getLength(s1);
for (int counter = 1; counter <= max; counter++) {
std::cout << s1[counter];
}
}
void appendTest() {
arrayString a = new char[5];
a[0] = '5'; a[1] = 'f'; a[2] = 'o'; a[3] = 't'; a[4] = 'i';
append_str(a, 's');
display(a);
}
My issue is with the implementation of my function getLength(). I have tried to debug my program inside Visual Studio, and all seems nice and well in the beginning.
The first time getLength() is called, inside the append_str() function, it returns the correct value for the string length (5). When it get's called inside the display(), my own custom string displaying function (to prevent a bug with std::cout), it reads the value (6) correctly, but returns -42? What's going on?
NOTES
Ignore my comments in the code. It's purely educational and it's just me trying to see what level of commenting improves the code and what level reduces its quality.
In get_length(), I had to do first_element - '0' because otherwise, the function would return the ascii value of the arithmetic value inside. For instance, for decimal 6, it returned 54.
This is an educational endeavour, so if you see anything else worth commenting on, or fixing, by all means, let me know.
Since you are getting the length as return s1[0] - '0'; in getLength() you should set then length as newString[0] = length + '0'; instead of newString[0] = length;
As a side why are you storing the size of the string in the array? why not have some sort of integer member that you store the size in. A couple of bytes really isn't going to hurt and now you have a string that can be more than 256 characters long.
You are accessing your array out of bounds at couple of places.
In append_str
for (int counter = 1; counter < length; counter++) {
newString[counter] = s[counter];
}
In the example you presented, the starting string is "5foti" -- without the terminating null character. The maximum valid index is 4. In the above function, length has already been set to 6 and you are accessing s[5].
This can be fixed by changing the conditional in the for statement to counter < length-1;
And in display.
int max = getLength(s1);
for (int counter = 1; counter <= max; counter++) {
std::cout << s1[counter];
}
Here again, you are accessing the array out of bounds by using counter <= max in the loop.
This can be fixed by changing the conditional in the for statement to counter < max;
Here are some improvements, that should also cover your question:
Instead of a typedef, define a class for your string. The class should have an int for the length and a char* for the string data itself.
Use operator overloads in your class "string" so you can append them with + etc.
The - '0' gives me pain. You subtract the ASCII value of 42 from the length, but you do not add it as a character. Also, the length can be 127 at maximum, because char goes from -128 to +127. See point #1.
append_str changes the pointer of your object. That's very bad practice!
Ok, thank you everyone for helping me out.
The problem appeared to be inside the appendTest() function, where I was storing in the first element of the array the character code for the value I wanted to have as a size (i.e storing '5' instead of just 5). It seems that I didn't edit previous code that I had correctly, and that's what caused me the issues.
As an aside to what many of you are asking, why am I not using classes or better design, it's because I want to implement a basic string structure having many constraints, such as no classes, etc. I basically want to use only arrays, and the most I am affording myself is to make them dynamically allocated, i.e resizable.