Arduino Regex

Simple: how do I use regex in Arduino?

Complicated:
I am having a problem with a simple program that I wrote to monitor the status of my computer (mac), and send it to the arduino through serial usb, and have it displayed though led's. The code on the mac side is fairly straight forwards and passes a letter (depending on the status item) followed by the binary status.

#!/bin/bash
#This script sends an agnlegement signal along with net, power, email, and temp data to the arduino

#power variable is $powerStat
#net variable is $netStat
#speed variable is $speedStat
#email variable is $emailStat
#temp variable is $tempStat

#power test
isFullyCharged=`ioreg -n AppleSmartBattery | grep FullyCharged | awk '{ print $5 }'`
isCharging=`ioreg -n AppleSmartBattery | grep IsCharging | awk '{ print $5 }'`
timeLeft=`ioreg -n AppleSmartBattery | grep TimeRemaining | awk '{ print $5 }'` 

if [ $isFullyCharged = "Yes" ] ; then 
powerStat=1
elif [ $isCharging = "Yes" ]; then
powerStat=1
else 
powerStat=0
fi
#

#network test
networkTest=`ping -c 4 8.8.4.4 | grep -o "0.0"`

if [ $networkTest = "0.0" ] ; then
netStat=1
else
netStat=0
fi
#

#speed test
load=`uptime | grep -o ": ...." | grep -o "[0-9].[0-9][0-9]"`
cpuStat=`echo $load*100 | bc | grep -o "[0-9][0-9][0-9]"`

if [ "$cpuStat" -lt "400" ] ; then
speedStat=1
else
speedStat=1
fi
#

#email test
gmail=`gmail | grep -o "[0-9]"`

if [ "$gmail" -gt "0" ] ; then
emailStat=1
else
emailStat=0
fi
#


#temp test
temp=`temp | grep -o "[0-9][0-9]"`

if [ "$temp" -lt "85" ] ; then
tempStat=1
else
tempStat=0
fi
#

echo 'P'$powerStat'N'$netStat'L'$speedStat'E'$emailStat'T'$tempStat

The code on the arduino side is extremely basic as I am a beginner Arduino coder, and need help with the program.

int incomingByte = 0;      // for incoming serial data
String readString;
int cont = 1;
void setup() {
      Serial.begin(9600);      // opens serial port, sets data rate to 9600 bps

}

void loop() {
  while (Serial.available() && cont>0) {
    delay(100);
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
      }


    if (readString == '"P"[0-1]"N"[0-1]"L"[0-1]"E"[0-1]"T"[0-1]'){
     Serial.println("happy arduino");
     delay(100);
     cont = 0;
     break;
    }
    else if (readString == '"P"[0-9]'){
     Serial.println("meh");
     delay(100); 
     cont = 0;
     notify("E", 1);
     break;
    }
     else{
     Serial.println("bad nick");
     delay(100); 
     cont = 0;
     notify("E", 1);
     break;
    }
  }
  Serial.flush();
  readString = "";
  cont = 1;
  delay(100);
  }
  
int notify(String a, int b){
  String input;
}

Please try to give suggestions without being a scathingly mean trollgrammer. Please help...

Please try to give suggestions without being a scathingly mean trollgrammer.

Where's the fun in that? ;D

Regular expression parsing is not a trivial task. The Arduino (and, in general, C++) does not provide support for regular expression parsing.

Once you have the string, you can use indexOf() and substring() to extract substrings. Once you have a substring, you can use toCharArray() to extract the character array, and atoi() to convert that to an integer.

Once you have integer values for P, N, L, E, and T, you can make your decision(s) based on those values.

Thanks, your suggestion got me to the next step. In my hunt for indexOf() and substring() documentation I found a slightly simpler function suited for exactly what I'm looking for: charAt(). ;). My final code parses the input from the mac and takes the values based on their position in the sent string. I'm still finishing it off so Googlers beware, this code is buggy.

#!/bin/bash
#This script sends an agnlegement signal along with net, power, email, and temp data to the arduino

#power variable is $powerStat
#net variable is $netStat
#speed variable is $speedStat
#email variable is $emailStat
#temp variable is $tempStat

#power test
isFullyCharged=`ioreg -n AppleSmartBattery | grep FullyCharged | awk '{ print $5 }'`
isCharging=`ioreg -n AppleSmartBattery | grep IsCharging | awk '{ print $5 }'`
timeLeft=`ioreg -n AppleSmartBattery | grep TimeRemaining | awk '{ print $5 }'` 

if [ $isFullyCharged = "Yes" ] ; then 
powerStat=1
elif [ $isCharging = "Yes" ]; then
powerStat=1
else 
powerStat=0
fi
#

#network test
networkTest=`ping -c 4 8.8.4.4 | grep -o "0.0"`

if [ $networkTest == "0.0" ] ; then
netStat=1
else
netStat=0
fi
#

#speed test
load=`uptime | grep -o ": ...." | grep -o "[0-9].[0-9][0-9]"`
cpuStat=`echo $load*100 | bc | grep -o "[0-9][0-9][0-9]"`

if [ "$cpuStat" -lt "400" ] ; then
speedStat=1
else
speedStat=1
fi
#

#email test
gmail=`gmail | grep -o "[0-9]"`

if [ "$gmail" -gt "0" ] ; then
emailStat=1
else
emailStat=0
fi
#


#temp test
temp=`temp | grep -o "[0-9][0-9]"`

if [ "$temp" -lt "85" ] ; then
tempStat=1
else
tempStat=0
fi
#
echo $powerStat''$netStat''$speedStat''$emailStat''$tempStat
echo $powerStat''$netStat''$speedStat''$emailStat''$tempStat > /dev/tty.usbserial-A700dY3F
exit

and the Arduino Code

int incomingByte = 0;      // for incoming serial data
int repeat = 1;
//pin variables
int statPin = 3;
int redStatPin = 2;

int powerPin = 13;
int redPowerPin = 12;

int netPin = 11;
int redNetPin = 10;

int speedPin = 9;
int redSpeedPin = 8;

int emailPin = 7;
int redEmailPin = 6;

int tempPin = 5;
int redTempPin = 4;

// enviro variables
String readString;
int cont = 1;
void setup() {
  Serial.begin(9600);      // opens serial port, sets data rate to 9600 bps
  pinMode(statPin, OUTPUT);
  pinMode(redStatPin, OUTPUT);
  pinMode(powerPin, OUTPUT);
  pinMode(redPowerPin, OUTPUT);
  pinMode(netPin, OUTPUT);
  pinMode(redNetPin, OUTPUT);
  pinMode(speedPin, OUTPUT);
  pinMode(redSpeedPin, OUTPUT);
  pinMode(emailPin, OUTPUT);
  pinMode(redEmailPin, OUTPUT);
  pinMode(tempPin, OUTPUT);
  pinMode(redTempPin, OUTPUT);
}

void loop() {
  if (Serial.available()) {
    while (Serial.available() && cont>0) {
      delay(100);
      if (Serial.available() >0) {
        char c = Serial.read();  //gets one byte from serial buffer
        readString += c; //makes the string readString
      }

      if (readString.length() == 5){
        //the order for binary status is power, net, speed, email, temp
        if (readString.charAt(1) == '1'){notify(1, 1);}
        if (readString.charAt(1) == '0'){notify(1, 0);}
        if (readString.charAt(2) == '1'){notify(2, 1);}
        if (readString.charAt(2) == '0'){notify(2, 0);}
        if (readString.charAt(3) == '1'){notify(3, 1);}
        if (readString.charAt(3) == '0'){notify(3, 0);}
        if (readString.charAt(4) == '1'){notify(4, 1);}
        if (readString.charAt(4) == '0'){notify(4, 0);}
        if (readString.charAt(5) == '1'){notify(5, 1);}
        if (readString.charAt(5) == '0'){notify(5, 0);}
        Serial.println("notified");
        delay(100);
        cont = 0;
        break;
      }
      else if (readString == 2){
        Serial.println("bu hao");
        delay(100); 
        cont = 0;
        alert();
        break;
      }
    }
      Serial.flush();
      readString = "";
      cont = 1;
      delay(100);
  }
}

int notify(int a, int b){
  //the order for binary status is power, net, speed, email, temp
  if (a == 1 && b == 1){digitalWrite(redPowerPin, LOW); digitalWrite(powerPin, HIGH);}
  if (a == 1 && b == 0){digitalWrite(powerPin, LOW); digitalWrite(redPowerPin, HIGH);}
  if (a == 2 && b == 1){digitalWrite(redNetPin, LOW); digitalWrite(netPin, HIGH);}
  if (a == 2 && b == 0){digitalWrite(netPin, LOW); digitalWrite(redNetPin, HIGH);}
  if (a == 3 && b == 1){digitalWrite(redSpeedPin, LOW); digitalWrite(speedPin, HIGH);}
  if (a == 3 && b == 0){digitalWrite(speedPin, LOW); digitalWrite(redSpeedPin, HIGH);}
  if (a == 4 && b == 1){digitalWrite(redEmailPin, LOW); digitalWrite(emailPin, HIGH);}
  if (a == 4 && b == 0){digitalWrite(emailPin, LOW); digitalWrite(redEmailPin, HIGH);}
  if (a == 5 && b == 1){digitalWrite(redTempPin, LOW); digitalWrite(tempPin, HIGH);}
  if (a == 5 && b == 0){digitalWrite(tempPin, LOW); digitalWrite(redTempPin, HIGH);}
}

String alert(){
  while (repeat==1){
    delay(50);
    digitalWrite(13, HIGH);
    delay(50);
    digitalWrite(13, LOW);
    delay(50);
    digitalWrite(12, HIGH);
    delay(50);
    digitalWrite(12, LOW);
    delay(50);
    digitalWrite(11, HIGH);
    delay(50);
    digitalWrite(11, LOW);
    delay(50);
    digitalWrite(10, HIGH);
    delay(50);
    digitalWrite(10, LOW);
    delay(50);
    digitalWrite(9, HIGH);
    delay(50);
    digitalWrite(9, LOW);
    delay(50);
    digitalWrite(8, HIGH);
    delay(50);
    digitalWrite(8, LOW);
    delay(50);
    digitalWrite(7, HIGH);
    delay(50);
    digitalWrite(7, LOW);
    delay(50);
    digitalWrite(6, HIGH);
    delay(50);
    digitalWrite(6, LOW);
    delay(50);
  }
}
      Serial.flush();

No! No! No!

Unless you really know what you are doing, dumping random amounts of serial data into the bit bucket is going to bite you in the posterior one of these days.

You might want to work on the code, just as an exercise, to make it work with indexOf and substring. Someday, you may want to pass more that one digit numbers to the Arduino.

I was unaware of the dangers of Serial.flush(), what exactly can go wrong? I thought I was just wiping the serial buffer. As for the project in general, I got it working flawlessly five minutes ago! indexOF and subString are good functions to learn, however I think I will save them for when they are needed. Thanks for the advice PaulS!

what exactly can go wrong? I thought I was just wiping the serial buffer.

It is. But, do you have complete control over when serial data is sent? Do you know what you are deleting from the serial buffer? Do you know how much serial data you are deleting? Why are you sending serial data if you don't want it all processed? Why send data that is not going to be even acknowledged, let alone processed?

If you can define/determine answers to all these questions, then, by all means, use Serial.flush(). If not, then, don't.

Regular expression parsing is not a trivial task.

Heck - regex writing isn't a trivial task; regex is what gives Perl the moniker of "line noise" (Perl can be a very nice language to look at, as long as you stay away from excessive regex usage and format things properly - two things which I think aren't in the vocab of most Perl coders).

Can you imagine the newbie outpouring on how to use regex (gah, I've been coding for over 20 years, and I still think regex is one of the worst things to have been foisted on the community - yeah it has power, but so does a UTM, which regex arguably is, but you don't us all coding for such a beast, do you? Whitespace and BrainF**k programmers excepted, of course).

;D