I am working on a simple little robot to cure my boredom and all it has is a 64 x 32 OLED for the eyes, and a PAJ7620 Gesture recognition sensor with a Seeeduino Xiao as the main board.
Basically, when people swipe above the head where the sensor is, the robot will show the heart eyes. There are different reactions for different actions and all this is controlled through functions. When the sensor does not detect anything, the robot is supposed to cycle through a certain void which is determined based on how much it 'likes' the person.
Right now though, it just cycles through the function and does not respond to the sensor. My code isvery inefficient because of all the functions, but it makes it more readable and more easily editable. With all my functions, the gesture sensor takes too long to respond to the actions.
What can I do to fix this? Can someone please help or give advice on how I can improve my code?
#include <Arduino.h> #include <U8g2lib.h> #include <Wire.h> #include <DFRobot_PAJ7620U2.h> int like_score = 3;//Score for how much the bot likes you: this will impact which voids are used. int max_like_score = 17; char buffer[9]; unsigned long previousMillis = 0; const long interval = 1000; DFRobot_PAJ7620U2 paj; U8G2_SSD1306_64X32_1F_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE); // fonts https://github.com/olikraus/u8g2/wiki/fntlistall#4-pixel-height void setup(void) { u8g2.begin(); Serial.begin(115200); delay(300); u8g2.clearBuffer(); Serial.println("Gesture recognition system base on PAJ7620U2"); while (paj.begin() != 0) { Serial.println("initial PAJ7620U2 failure! Please check if all the connections are fine, or if the wire sequence is correct?"); delay(500); } Serial.println("PAJ7620U2 init completed, start to test the gesture recognition function"); paj.setGestureHighRate(true); } void normalL() { //normal forward expression u8g2.clearBuffer(); // clear the internal memory u8g2.drawBitmap(0, 0, 8, 32, normal); u8g2.sendBuffer(); } void blinkL() { //blinks u8g2.clearBuffer(); // clear the internal memory u8g2.drawBitmap(0, 0, 8, 32, blink); u8g2.sendBuffer(); } void left() { //looks left u8g2.clearBuffer(); // clear the internal memory u8g2.drawBitmap(0, 0, 8, 32, blinkleft); u8g2.sendBuffer(); } void right() { //looks right u8g2.clearBuffer(); // clear the internal memory u8g2.drawBitmap(0, 0, 8, 32, blinkright); u8g2.sendBuffer(); } void angryL() { //angry u8g2.clearBuffer(); // clear the internal memory u8g2.drawBitmap(0, 0, 8, 32, angry); u8g2.sendBuffer(); } void loveL() { //in love u8g2.clearBuffer(); // clear the internal memory u8g2.drawBitmap(0, 0, 8, 32, love); u8g2.sendBuffer(); } void sleepL() { //sleeping u8g2.clearBuffer(); // clear the internal memory u8g2.drawBitmap(0, 0, 8, 32, sleep); u8g2.sendBuffer(); } void susL() { //suspicious u8g2.clearBuffer(); // clear the internal memory u8g2.drawBitmap(0, 0, 8, 32, sus); u8g2.sendBuffer(); } void stunL() { //looks stunned u8g2.clearBuffer(); // clear the internal memory u8g2.drawBitmap(0, 0, 8, 32, stun); u8g2.sendBuffer(); } void upL() { //Looks up u8g2.clearBuffer(); // clear the internal memory u8g2.drawBitmap(0, 0, 8, 32, up); u8g2.sendBuffer(); } void gleeL() { u8g2.clearBuffer(); // clear the internal memory u8g2.drawBitmap(0, 0, 8, 32, glee); u8g2.sendBuffer(); } void randomEx() { int rand = random(1, 8); if (rand == 1) { normalL(); } else if (rand == 2) { left(); } else if (rand == 3) { right(); } else if (rand == 4) { angryL(); } else if (rand == 5) { loveL(); } else if (rand == 6) { susL(); } else if (rand == 7) { upL(); } else if (rand == 8) { gleeL(); } } void likeRoutine() { normalL(); delay(random(1000, 6500)); blinkL(); delay(90); normalL(); delay(random(1000, 4500)); randomEx(); delay(random(1000, 4500)); blinkL(); delay(90); loveL(); delay(random(2500, 4000)); blinkL(); delay(90); } void kindofLikeRoutine() { normalL(); delay(random(1000, 7000)); blinkL(); delay(90); normalL(); delay(random(1000, 4500)); randomEx(); delay(random(1000, 4500)); blinkL(); delay(90); loveL(); delay(random(1000, 3000)); blinkL(); delay(90); } void dislikeRoutine() { normalL(); delay(random(1000, 7000)); blinkL(); delay(90); normalL(); delay(random(1000, 6500)); randomEx(); delay(random(1000, 4000)); blinkL(); delay(90); angryL(); delay(random(1000, 3000)); blinkL(); delay(90); } void hateRoutine() { angryL(); delay(random(1000, 5000)); blinkL(); delay(90); normalL(); delay(random(1000, 6500)); randomEx(); delay(random(1000, 4000)); blinkL(); delay(90); angryL(); delay(random(1000, 3000)); blinkL(); delay(90); } void loop(void) { DFRobot_PAJ7620U2::eGesture_t gesture = paj.getGesture(); if (gesture != paj.eGestureNone) { String description = paj.gestureDescription(gesture); //Convert gesture number into string description if (gesture == 256) { //wave gleeL(); delay(random(1000, 4500)); } else if (gesture == 2 && like_score < max_like_score) { //pet blinkL(); delay(90); loveL(); like_score++; Serial.println(like_score); delay(random(1000, 3000)); if (like_score == max_like_score) { blinkL(); delay(90); loveL(); delay(random(1000, 3000)); } } else if (gesture == 16 && like_score <= max_like_score) { //thump stunL(); like_score--; Serial.println(like_score); delay(random(1000, 4000)); angryL(); delay(random(1000, 3000)); } else if (gesture == 128) { u8g2.clearBuffer(); u8g2.setFont(u8g2_font_t0_11_tf); // choose a suitable font dtostrf(like_score, 6, 0, buffer); String scoreStr = String(buffer); u8g2.drawStr(0, 20, scoreStr.c_str()); u8g2.sendBuffer(); delay(random(2000, 3500)); } } else { if (like_score >= 11) { likeRoutine(); } else if (like_score > 7 && like_score < 11) { kindofLikeRoutine(); } else if (like_score > 0 && like_score < 7) { dislikeRoutine(); } else if (like_score < 0) { hateRoutine(); } } }- Thank you, I will do that.Renier Jr.– Renier Jr.2023-07-07 15:41:33 +00:00CommentedJul 7, 2023 at 15:41
- @jsotola That looked very much like an answer to the question, not a request for clarifying information. Could you please turn it into an answer? Hint: cut and paste should work. Thanks!2023-07-08 06:22:47 +00:00CommentedJul 8, 2023 at 6:22
- My code is very inefficient because of all the functions ... - not at all. Using functions to make code readable is very common, and the slowdown is minimal.2023-07-08 06:23:56 +00:00CommentedJul 8, 2023 at 6:23
- @jsotola I'm just asking that your reasonable comment about using
delay()be incorporated into an answer and not a comment. However if you wish provide more code, but that wasn't what I was requesting.2023-07-08 07:27:51 +00:00CommentedJul 8, 2023 at 7:27
1 Answer1
The code is being slowed down by thedelay() function because it is ablocking function.
The delay function does not exit until delay time passes, so no other functions can run, such as sensor reading.
The simplest solution for your code may be an FSM library (finite state machine). It would look after all of the timing for you.
You could also replace thedelay() functions with your own delay function, something like
void myDelay(int totalDelay) { for (i = 0; i < totalDelay/100; i++) { // do some housekeeping here, like reading sensors delay(100); // this blocks for only 1/10 of a second } // adjust the delay value if housekeeping takes a lot of time}The delay gets broken into a lot of small delays with time to do other things in between.
Another way is to check at the begining ofloop() to see how much time has elapsed.See blinkWithoutDelay example code in the Arduino IDE.
Here is an example in a simulator that may help you.
- Thank you! This definitely helps a lot!Renier Jr.– Renier Jr.2023-07-08 13:05:42 +00:00CommentedJul 8, 2023 at 13:05
Explore related questions
See similar questions with these tags.