Converting Serial read data to Serial.println Base64, something went wrong

I am using arduino uno R2 and i have some problems with code - b.toCharArray(tok,atm) function. Somehow it is not possible to clear b and tok, but if i comment out toCharArray, there are no problems, except that it do not convert serial input to base64.

i am using this code to read serial input and convert it to base64 code, maybe there are easier way to do this.

Here is the code:

#include <Streaming.h>
#include <Base64.h>

String b = ""; 
byte atm = 0;
char* tok  = "";
char gatavais[200] = "";

void setup() {
   Serial.begin(115200);
 b.reserve(200);
 
}
void loop()
{
 while (Serial.available()) { 
     char o = (char)Serial.read();
     b += o;   
        if (o == '\n') {
     Serial.println(b);
     atm = b.length(); 
     b.toCharArray(tok,atm);            
     
     base64_encode(gatavais, tok, atm);
     Serial << gatavais << endl;    
     b = "";
     tok = "";  
     atm = 0;
     
     }
 }
}

and here is what serial monitor shows:

hi

aGkA
hijoke

aGlqb2tlAA==
hijokenot again

S4HNQxkq10BDMDnS837l/A==
hijokenotS4HNQxkq10BDMDnS837l/A==hello

S4HNQxkq10BDMDnS837l/Mr0PoDd1epSecAYaAsLpWi5NDl3JYf2
hijokenotS4HNQxkq10BDMDnS837l/Mr0PoDd1epSecAYaAsLpWi5NDl3JYf2i do not understand

S4HNQxkq10BDMDnS837l/Mr0PoDd1epSecAYaAsLpWi5NDl3JYf2R474uppJR/PKYJ4Z91sVd/DdGMEaHAdUr3Qod2Cc1nrzvTBo39kvF9P7

i hope that someone could help me with this problem.

     char o = (char)Serial.read();

The cast is unnecessary.

     b.toCharArray(tok,atm);

This copies the data from b into the memory you have allocated to hold the data. Let's see where you allocated that memory.

char* tok  = "";

Bzzzt. Completely wrong.

I tried what You suggested, but still no end to my problem. Looks like problem is that i do not know how to empty char tok and String b, i tried many ways to do that, but i have not succeed. i added to code more Serial.println to see what is happening.

i am new to C, my previous programming experience was Pascal.

Here is code:

#include <Streaming.h>
#include <Base64.h>

String b = ""; 
byte atm = 0;
char* tok;
char gatavais[200] = "";
char o;

void setup() {
   Serial.begin(115200);
 b.reserve(200); 
}
void loop()
{
 while (Serial.available()) { 
     o = (char)Serial.read();
     b += o;   
        if (o == '\n') {
           Serial << "Entered:  " <<  b <<  endl;
           atm = b.length(); 
           b.toCharArray(tok,atm);  
           base64_encode(gatavais, tok, atm);
           Serial << "Encoded:  " << gatavais << endl;    
           b = "";
           tok = "";  
           atm = 0;           
           Serial << "b:   " << b << endl;
           Serial << "tok: " << tok << endl;
           Serial << "atm: " << atm << endl;
     }
 }
}

Serial monitor:

Entered:  apple

Encoded:  gAByFIBy
b:   
tok: 
atm: 0
Entered:  apple

Encoded:  YXBwbGUA
b:   apple
tok: apple
atm: 0
ppleappleapple

Encoded:  YXBwbGVhcHBsZQA=
b:   appleapple
tok: appleapple
atm: 0
ppleappleappleappleapple

pleYXBwbGVhcHBsZWFwcGxlAA==
b:   appleappleapple
tok: appleappleapple
atm: 0
ppleappleappleappleappleappleapple

pleappleYXBwbGVhcHBsZWFwcGxlYXBwbGUA
b:   appleappleappleapple
tok: appleappleappleapple
atm: 0
ppleappleappleappleappleappleappleappleapple

pleappleappleYXBwbGVhcHBsZWFwcGxlYXBwbGVhcHBsZQA=
leappleappleappleappleapple
tok: appleappleappleappleapple
atm: 0
ppleappleappleappleappleappleappleappleappleappleapple

pleappleappleappleYXBwbGVhcHBsZWFwcGxlYXBwbGVhcHBsZWFwcGxlAA==
leappleappleappleappleappleappleapple
eappleappleappleappleappleapple
atm: 0
ppleappleappleappleappleappleappleappleappleappleappleappleapple

pleappleappleappleappleYXBwbGVhcHBsZWFwcGxlYXBwbGVhcHBsZWFwcGxlYXBwbGUA
leappleappleappleappleappleappleappleappleapple
eappleappleappleappleappleappleappleapple
0
ppleappleappleappleappleappleappleappleappleappleappleappleappleappleapple

correct "apple" encoding is "YXBwbGUA" , what it answers only when second time i entered apple, and with any second entered "apple" seems that program somehow losts or forget to print out text and do not encode anything right.

I tried what You suggested, but still no end to my problem. Looks like problem is that i do not know how to empty char tok and String b, i tried many ways to do that, but i have not succeed. i added to code more Serial.println to see what is happening.

char* tok;
           b.toCharArray(tok,atm);

No, you didn't. You are still trying to extract the character data in the String object, b, to a place you have not reserved space at.

char tok[200]; // Or, whatever size is appropriate
           b.toCharArray(tok,atm);

Until you fix this fundamental flaw in your program, the rest of your issues will remain.

Seems to me that i almost do not know a thing about programming. :smiley:
Now, when You told what exactly i need to change, code encodes right, but still i can not manage that after each encoding String "b" and char "tok" are "clear".

It seems like it continue to add all what i enter at console to string "b" and i am so dumb , that i can not make string "b" empty.

If you are going to use a character array anyway, get rid of the stupid String class. Store the data read from the serial port in the tok array (after you give it a better name). All you need to add is a variable to keep track of where in the array to store the next character, and to add a trailing NULL after each character.

The functionality that the String class offers you is not worth the overhead and aggravation it causes.

i don't know how to store serial data to char, so i store it in string.

it sounds so easy, but for me it will be taking some hours to do... probably two days :smiley:

i don't know how to store serial data to char, so i store it in string.

Like so:

char buffer[40];
byte index = 0;

void loop()
{
   while(Serial.available() > 0)
   {
      char aChar = Serial.read();
      if(index < 39) // One less than the array size
      {
         buffer[index] = aChar;
         index++;
         buffer[index] = '\0';
      }
   }
}

Keep in mind that a packet is not received all at once, so you need to add some code to this to detect the start and end of a packet in the stream of data. Almost certainly, you do not want to call base64_encode() with random parts of the packet.

ardonis:
correct "apple" encoding is "YXBwbGUA"

Actually it is "YXBwbGU=".

See: Base64 Online - base64 decode and encode

The encoding you gave was for "apple\0".

Somehow i managed to get what i need:

#include <Streaming.h>
#include <Base64.h>

String b = ""; 
byte atm = 0;
char tok[200];
char gatavais[200] = "";
char o;


void setup() {
   Serial.begin(115200);
}
void loop()
{
while (Serial.available()) { 
     o = (char)Serial.read();
     b += o;   
        if (o == '\n') {
           Serial << "Entered:  " <<  b <<  endl;
           atm = b.length(); 
           b.toCharArray(tok,atm);  
           base64_encode(gatavais, tok, atm);
           Serial << "Encoded:  " << gatavais << endl;
           b = 0;
           tok[200] = NULL;
           atm = 0;   
     }
 }  

}

But i could not manage part of detecting start and end packet.

byte atm = 0;
...
char o;

Rather confusing data names don't you think?