Hello Humans,
I am having trouble wrapping my head around C-Strings VS Strings and the proccess behind moving data between each other.
As far as i have worked out: (I am probably wrong)
A C-String/Char Array is
- Defined as
char receivedChars[numChars];
- When viewed contains an array like
["M","1","0","0","P","1","0","0","S","0","4","0"]
- Each index is considered a Char even when containing more than one character and can be editied using Char Operators.
- Can only have data added if space has been previously allocated for it (Still unsure how to allocate array size outside of definition.)
A String is
- Defined as
String IAMASTRING;
- When viewed contains
M100P100S040
- Is not the sum of its parts, is only a string. Cannot be referenced using Char Operators.
- Can dynamically allocate its own memory as it is written to.
(I have no idea if C-string and Char Array are different names for the same thing. Stack exchange forums seem to refer to them as the same. )
I've tried using strcat and a few other functions to append a string onto a C-string/Char Array with no luck.
I manage to get a clean compile using a for loop but i havent tested this working yet.
for (int a = i; i < (CMDChars + i); i++){
CMD += receivedChars[a]; /// Add Elements to CMD String
}
- My main code takes in serial data;
- Saves it to a C-String/Array that is pre-allocated 32(bytes/cookies)? ; "writing over itself from 0 index if exceeding 32"
- Searches through each index for an alphabetical character.;
- If it finds an alphabetical character it searches the next 3 indexs for a number 0 to 9;
- If 3 fails, use a for loop to move all C-string elements - 1 starting from 0 index;
- if 4 fails, use a for loop to move all C-string elements - 4 starting from 0 index;
Then a later date I would like to set the allocated char array to reduce its size after receiving data. Then increase its size to 32 again at the start of data receiving.
TLDR:
If someone can help me clarify the differences and pros and cons between moving data between strings/CharArrays/C-Strings that would be sweet.
I kind of made a mess of this post but i didn't want to leave any information out so here is the code ive got so far.
Func at line 152 is where it starts. A note to make is that i am using FastLED which fudges serial data. So im writing into a C-string/Array to get serial reading done ASAP.
///#define FASTLED_ALLOW_INTERRUPTS 0
#include "FastLED.h"
#include <SoftwareSerial.h>
#define NUM_LEDS 144 ///144
#define PIN 3 // LED signal Pin
SoftwareSerial HM10(9, 8);///9 (RX) ///8 (TX)
CRGB pixels[NUM_LEDS];
int leds[294]; ///For Aligning Vertical/Horizontal Motion /// NUMBER OF LEDS IN ONE CIRCLE~?leds[NUM_LEDS/4];
int max_overall_brightness = 255;
int overall_brightness = 255;
float red_max = 1;
float green_max = 1;
float blue_max = 1;
int red;
int green;
int blue;
int animation_rate = 5;
int MAXanimation_rate = 10;
int mode = 1; // Animation mode index
int MAXmode = 14; // max mode index
int incoming_command = 0;
int animation_speed = 2;
// These variables are used within the animation methods.
// They are scoped by name, but global in the sketch,
// so that animations will not restart when commands are received.
///////////////////////////////Serial BT Receiver
int Power;
const byte CMDChars = 4;
const byte numChars = 32; //array size limiter
char receivedChars[numChars]; // Array of received data
boolean RecNewData = false;
boolean SendNewData = false;
static byte ndxRx = 0; // index size of "received data" storage
static byte ndxSort = 0; // index size of array
bool NewDataRx = false;
bool RxValidData = false;
String CMD;
char CSV[2] = {',','\0'};
//char AAA[4] = {'M', '1', '3','\0'};
//char BBB[3] = {'S', '4','\0'};
//char CCC[4] = {'V', '8','0','\0'};
//char DDD[3] = {'P', '1','\0'};
///////////////////////////////
int DataCleanUp = 0;
////////////////////
//BeaconEDIT Vars
int VerticalLEDs = 6;
int HorizontalLEDs = 24; //LEDS in one circle
// Beacon Vars
double beacon_angle = 0;
int beacon_led_angle = 0;
double beacon_left_distance = 0;
double beacon_right_distance = 0;
double beacon_absolute_distance = 0.0;
int beacon_beam_width = 10; // in degrees
int beacon_beam_width_Half = (HorizontalLEDs / VerticalLEDs);
int beacon_falloff = 35; // in degrees
int beacon_pixel_brightness = 0; // in degrees
bool CanReadSoftSerial = true;
volatile boolean animate = true;
volatile long animation_change_timeout;
void setup() {
LEDS.setBrightness(255);
FastLED.addLeds<WS2812B, PIN, GRB>(pixels, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setMaxPowerInVoltsAndMilliamps(5, 700); // limit power of LED strip to 5V, 500mA
FastLED.clear();
Serial.begin(38400);
HM10.begin(38400);
Serial.println("Setup Complete");
}
void loop() {
// unsigned long start = micros();
recvWithStartEndMarkers(); // Receive BT serial data
// unsigned long end = micros();
// unsigned long delta = end - start;
// Serial.print("SerialBufferScan = ");
// Serial.println(delta);
DataChecker();
SortRxData ();
}
void recvWithStartEndMarkers() {
NewDataRx = false;
RxValidData = false;
char IncomingChar;
//if (HM10.available() == 0){ //////Clock speed determins animation speed
// FastLED.show();
// }
while (HM10.available() > 0 && RecNewData == false) {
IncomingChar = HM10.read();
Serial.print("IncomingChar:");Serial.println(IncomingChar);
HM10.print(IncomingChar); // Send CheckByte
HM10.flush(); ///WAIT FOR DATA TO SEND
delay(2); ///WAIT FOR LAST DIGIT OF DATA TO SEND.
if (ndxRx >= numChars) { // if index exceeds byte limit
// ndxRx = numChars - 1; // set index to re-write over last char in array
ndxRx = 0; // set index to re-write over last char in array
}
receivedChars[ndxRx] = IncomingChar; // index chars in array index ndx
ndxRx++; // increase index number
// Serial.print("ndxRx:");Serial.println(ndxRx);
// Serial.print("RxCharArray:");Serial.println(receivedChars);
// Serial.print("RxCharArraySize:");Serial.println(strlen(receivedChars));
RxValidData = true;
}
}
// if (HM10.available() == 0){ //////Clock speed determins animation speed
// FastLED.show();
// }
//}
//Just for completeness:
//
//read first c-string array index:
//if c is (Any Letter): get next character
//if c is digit: get next character
//if c is something else: stop and remove from c to last digit from c-string.
//if there are no more characters: Change checker bool to false;
//isalpha() = letter OR? isupper()?
//isdigit() = number
void DataChecker() {
int i = 0;
int x = 0;
if (RxValidData == true){
for (i = 0; i < receivedChars; i++){ /// For every element in recChars AKA "C-String"
if (isalpha(receivedChars[i])) { // if element is alphabetic letter
for (x = i; i < (CMDChars + i); i++){ /// for 3 indexs above element i
if (isdigit(receivedChars[x])){ /// if element is number
DataCleanUp = 0; //SwitchCase to save
}
else {
DataCleanUp = 2; // Remove from X to I index from Cstring
break; // Exit For-Loop with Last Numbers Index as x
}
}
}
else {
DataCleanUp = 1; // Remove First Index from Cstring
break; // Exit For-Loop with First Letters Index as i
}
}
switch(DataCleanUp){
case 0: //Valid Receive create CMD string
for (int a = i; i < (CMDChars + i); i++){
CMD += receivedChars[a]; /// Add Elements to CMD String (DONT FORGET TO EMPTY STRING AFTER USAGE)
}
break;
case 1: // INVALID RECEIVED remove first index from C-string /// CSTRING = Get length of string; MOVE i+1 to i; MOVE i+2 to i+1; MOVE i+3 to i+2; MOVE i+4 to i+3; MOVE i+5 to i+4
for (int p = 0; p <= (receivedChars.length()); p++){
receivedChars[p] = receivedChars[p+1];
}
break;
case 2: // INVALID RECEIVED remove X to I index from C-string /// CSTRING = Get length of string; MOVE x+1 to i; MOVE X+2 to i+1; MOVE X+3 to i+2; MOVE X+4 to i+3; MOVE X+5 to i+4
for (int d = 0; d <= ((receivedChars.length()) - x); d++){
receivedChars[d] = receivedChars[((x+1)+d)];
}
break;
default:
break;
}
}
}
void SortRxData (){
if (RxValidData == true){
CMD = String(receivedChars);
Serial.print("CMD:");Serial.println(CMD);
// Serial.print("RxCharArray:");Serial.println(receivedChars);
for (int i=0; i <= (numChars-1); i++){
receivedChars[i] = NULL; // Set all array to null
}
// delete[] receivedChars; // Delete array to free memory
// Serial.print("RxCharArrayCleared:");Serial.println(receivedChars);
CheckNewDataFunc();
}
}
void CheckNewDataFunc() { /// Find values in received Data
if (CMD.indexOf('M') == 0){ // if mode('M') char found
if (CMD.indexOf('1') == 1){
// Serial.println("ITS An M+");
if ((mode < MAXmode)&&(mode != 99)){
mode += 1;
}
else if (mode == 99){
mode = 0;
}
}
else if (CMD.indexOf('0') == 1){
// Serial.println("ITS An M-");
if ((mode > 0)&&(mode != 99)){
mode -= 1;
}
else if (mode == 99){
mode = 0;
}
}
Serial.print("mode:"); // print mode result
Serial.println(mode); // print mode result
}
else if (CMD.indexOf('S') == 0){ // if mode('M') char found
if (CMD.indexOf('1') == 1){
Serial.println("ITS An S+");
// if (animation_rate < MAXmode){
// animation_rate += 1;
// }
}
else if (CMD.indexOf('0') == 1){
Serial.println("ITS A S-");
// if (MAXanimation_rate > 0){
// animation_rate -= 1;
// }
}
}
else if (CMD.indexOf('V') == 0){ // if mode('M') char found
if (CMD.indexOf('1') == 1){
// Serial.println("ITS A V+");
if (overall_brightness < max_overall_brightness){
overall_brightness += 5;
}
}
else if (CMD.indexOf('0') == 1){
// Serial.println("ITS A V-");
if (overall_brightness > 5){
overall_brightness -= 5;
}
}
}
else if (CMD.indexOf('P') == 0){ // if mode('M') char found
if (CMD.indexOf('1') == 1){
// Serial.println("ITS A P+");
mode = 0;
Power = 1;
}
else if (CMD.indexOf('0') == 1){
// Serial.println("ITS A P-");
mode = 99;
Power = 0;
}
}
else if (CMD.indexOf('R') == 0){ // if Red ('R') char found
String CMDVal = CMD;
CMDVal.remove(0,1);
int Rxred_max = CMDVal.toInt();
green_max = ((float)Rxred_max / 255); /// convert 255 into decimal for animations
Serial.print("IT IS RED:");Serial.println(red_max);
// incoming_command = 99;
}
else if (CMD.indexOf('G') == 0){ // if Red ('R') char found
String CMDVal = CMD;
CMDVal.remove(0,1);
int Rxgreen_max = CMDVal.toInt();
red_max = ((float)Rxgreen_max / 255); /// convert 255 into decimal for animations
Serial.print("IT IS GREEN:");Serial.println(green_max);
// incoming_command = 99;
}
else if (CMD.indexOf('B') == 0){ // if Red ('R') char found
String CMDVal = CMD;
CMDVal.remove(0,1);
int Rxblue_max = CMDVal.toInt();
blue_max = ((float)Rxblue_max / 255); /// convert 255 into decimal for animations
Serial.print("IT IS BLUE:");Serial.println(blue_max);
// incoming_command = 99;
}
else {
for (int i=0; i<numChars; i++){
CMD[i] = NULL;
}
}
Serial.println("///////////LOOP////////////");
}