Go Down

Topic: New peek function for HardwareSerial (Read 10448 times) previous topic - next topic

HazardsMind

If your reffering to the post where PaulS was taking about the delay I put in the code and proper delimiters, the new code doesn't need any of them. The peek function that I modified looks at everything in the Rx buffer. The buffer is never actually cleared like I thought it was, instead the tail value is decremented with each call of read() giving the appearance of it being cleared. All in all the buffer just rolls over once it collects more than 64 bytes.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

westfw

Quote
elaborate on your rant, otherwise you just fall in to the category of "one of those C guys".

how about something so the code ends up looking like:
Code: [Select]
void loop() {
  char *p;
  int8_t cmd;
  int n;

  Serial.print(F("Enter command: "));

  int i = parseGetline();  // read a line of text

  do {
    enum {
      CMD_RED, CMD_GREEN, CMD_BLUE, CMD_RESET  // make sure this matches the string
    };
    cmd = parseKeyword(PSTR("red green blue reset")); // look for a command.

    if (cmd >= 0) {
      n = parseNumber();
    }
    switch (cmd) {
      case CMD_RED:
        red = n;
        break;
      case CMD_BLUE:
        blue = n;
        break;
      case CMD_GREEN:
        green = n;
        break;
      case CMD_RESET:
        red = green = blue = 0;
        break;
      case PARSER_EOL:
        Serial.print("RED = "); Serial.print(red);
        Serial.print(" GREEN = "); Serial.print(green);
        Serial.print(" BLUE= "); Serial.println(blue);
        break;
      default:
        Serial.println("Invalid command");
        break;
    }
  } while (cmd >= 0);
}



It lets you have dialogs like:

Enter command: red 123
RED = 123 GREEN = 0 BLUE= 0
Enter command: blue 789
RED = 123 GREEN = 0 BLUE= 789
Enter command: green 456
RED = 123 GREEN = 456 BLUE= 789
Enter command: reset
RED = 0 GREEN = 0 BLUE= 0
Enter command:


The current code isn't ready for publication, but it's about 600bytes of code, and 82bytes of RAM, which includes an 80byte line buffer and editing (backspace/del, ctrl-u, ctrl-r :-))   And no modifications to the arduino core.

HazardsMind

The code I gave was just an example to show how the peek function would be useful.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

Pranjal_Joshi

I am also having similar problem explained in first post. I also viewed updated hardwareSerial files by hazardsMind. My question is can we modify the find function that actually peeks data instead of reading and clearing it from buffer? Check stream.cpp for find function.

HazardsMind

#19
May 02, 2015, 06:51 pm Last Edit: May 02, 2015, 07:05 pm by HazardsMind
You can do whatever you want but there are ways to solve the solution rather than mod the libraries.

Like this here. This uses no modified libraries, but it does require the string to be in a certain format.
ie R123G200B25 The code will see this string and split the letters and numbers accordingly and put them in their proper places.

**You dont need to have the string as I have it above but it does need to be a letter directly followed by a number R123. So you can just change red and blue with R123B25 and green will remain what it was.

Its nothing fancy, but it gets the job done in a minimal amount of lines.

Code: [Select]
#define IsWithin(x,a,b) ((x >= a) && (x <= b))

int Value = 0;
char Color = 'R';
const byte R_pin = 2, G_pin = 3, B_pin = 4;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(R_pin, OUTPUT);
  pinMode(G_pin, OUTPUT);
  pinMode(B_pin, OUTPUT);
}

void loop()
{
  // put your main code here, to run repeatedly:
  if (Serial.available() > 0)
  {
    char tmp = Serial.read();
    if (IsWithin(tmp, '0', '9'))
      Value = (Value * 10) + tmp - '0';
    else if (IsWithin(tmp, 'a', 'z') || IsWithin(tmp, 'A', 'Z'))
    {
      Color = tmp;
      Value = 0;
    }

    switch (Color)
    {
      case 'R':
      case 'r':
        analogWrite(R_pin, Value);
        break;

      case 'G':
      case 'g':
        analogWrite(G_pin, Value);
        break;

      case 'B':
      case 'b':
        analogWrite(B_pin, Value);
        break;
    }
  }
}


My GitHub:
https://github.com/AndrewMascolo?tab=repositories

HazardsMind

#20
May 08, 2015, 02:12 pm Last Edit: May 08, 2015, 03:38 pm by HazardsMind
Yes, you can do that too.


Code: [Select]
#define IsWithin(x,a,b) ((x >= a) && (x <= b))
#define R_pin 2
#define G_pin 3
#define B_pin 4

typedef struct myColors
{
  byte R;
  byte G;
  byte B;
};

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(R_pin, OUTPUT);
  pinMode(G_pin, OUTPUT);
  pinMode(B_pin, OUTPUT);
}

void loop()
{
  // put your main code here, to run repeatedly:
  if (Serial.available() > 0)
  {
    myColors ReturnedColors = GetColors(Serial.read());
    analogWrite(R_pin, ReturnedColors.R);
    analogWrite(G_pin, ReturnedColors.G);
    analogWrite(B_pin, ReturnedColors.B);
  }
}

struct myColors GetColors(char tmp)
{
  static myColors C;
  static int Value = 0;
  static char Color = 'R';

  if (IsWithin(tmp, '0', '9'))
    Value = (Value * 10) + tmp - '0';
  else if (IsWithin(tmp, 'a', 'z') || IsWithin(tmp, 'A', 'Z'))
  {
    Color = tmp;
    Value = 0;
  }

  switch (Color)
  {
    case 'R':
    case 'r':
      C.R = Value;
      break;

    case 'G':
    case 'g':
      C.G = Value;
      break;

    case 'B':
    case 'b':
      C.B = Value;
      break;
  }
  return C;
}


My GitHub:
https://github.com/AndrewMascolo?tab=repositories

Go Up