|
| 1 | + |
| 2 | + |
| 3 | +//resolved the delay caused between led and virtual display |
| 4 | +// reduced the input taking virtual pin condition |
| 5 | +// added superchart widget for no. of message count |
| 6 | +// TOTAL_MSG_ACCEPTED 3 |
| 7 | +// MSG_ACCEPTED_PER_SESSION 50 |
| 8 | +// msg count feature make a count of all msg recieved when the count reaches MSG_ACCEPTED_PER_SESSION then stop accepting the input and only allow the further input only after he resets the count |
| 9 | +// reset button always clears the msgs but when MSG_ACCEPTED_PER_SESSION is reached until then only messages are reset but the count is still counting |
| 10 | + |
| 11 | +#define BLYNK_TEMPLATE_ID "TMPL358V3gw6r" |
| 12 | +#define BLYNK_TEMPLATE_NAME "v101" |
| 13 | +#define BLYNK_AUTH_TOKEN "CLfyXI8VGnmuN1NjhnmEJTVO9Ff3h6oo" |
| 14 | + |
| 15 | +#define BLYNK_PRINT Serial |
| 16 | + |
| 17 | +#include <string.h> |
| 18 | +#include <WiFi.h> |
| 19 | +#include <BlynkSimpleEsp32.h> |
| 20 | +#include <MD_Parola.h> |
| 21 | +#include <MD_MAX72xx.h> |
| 22 | +#include <SPI.h> |
| 23 | + |
| 24 | +#define MAX_MESSAGE_LENGTH 100 |
| 25 | +#define TOTAL_MSG_ACCEPTED 3 //if u change this number u have to change some lines the program too |
| 26 | +#define MSG_ACCEPTED_PER_SESSION 50 |
| 27 | +#define HARDWARE_TYPE MD_MAX72XX::FC16_HW |
| 28 | +#define MAX_DEVICES 4 //If you're only using a single 32x8 display then please set this to 4. |
| 29 | + |
| 30 | +#define CLK_PIN 18 //yellow |
| 31 | +#define DATA_PIN 19 //green |
| 32 | +#define CS_PIN 5 //orange |
| 33 | + |
| 34 | +// MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES); //@sanjaybyranna |
| 35 | +MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); |
| 36 | + |
| 37 | +// Your WiFi credentials. |
| 38 | +// Set password to "" for open networks. |
| 39 | +char ssid[] = "sanjaysb"; |
| 40 | +char pass[] = "123456789"; |
| 41 | +char auth[] = BLYNK_AUTH_TOKEN; |
| 42 | +char mode[] = "wifi"; |
| 43 | + |
| 44 | + |
| 45 | + |
| 46 | + |
| 47 | +bool isMessage1Filled = false; |
| 48 | +bool isMessage2Filled = false; |
| 49 | +bool isMessage3Filled = false; |
| 50 | + |
| 51 | +char message1[MAX_MESSAGE_LENGTH]; |
| 52 | +char message2[MAX_MESSAGE_LENGTH]; |
| 53 | +char message3[MAX_MESSAGE_LENGTH]; |
| 54 | + |
| 55 | +void rotateMessages(const char* newMessage) { |
| 56 | + // Rotate messages: move message2 to message1, message3 to message2, and add new message to message3 |
| 57 | + strncpy(message1, message2, MAX_MESSAGE_LENGTH); |
| 58 | + strncpy(message2, message3, MAX_MESSAGE_LENGTH); |
| 59 | + strncpy(message3, newMessage, MAX_MESSAGE_LENGTH); |
| 60 | +} |
| 61 | + |
| 62 | +// delay between messages |
| 63 | +int delayValue; //default value |
| 64 | +int delayValue_ms; |
| 65 | +int messagecount = 0; |
| 66 | +BLYNK_WRITE(V4) { |
| 67 | + delayValue = param.asInt(); |
| 68 | + delayValue_ms = 1000 * delayValue; |
| 69 | + Blynk.virtualWrite(V2, "Delay changed"); |
| 70 | + // we convert this to milli sec later in loop |
| 71 | +} |
| 72 | + |
| 73 | +BLYNK_WRITE(V5) { |
| 74 | + messagecount++; |
| 75 | + Blynk.virtualWrite(V3, messagecount); |
| 76 | + |
| 77 | + if (messagecount == MSG_ACCEPTED_PER_SESSION) { |
| 78 | + Blynk.virtualWrite(V3, "You Reached the daily limit"); |
| 79 | + Blynk.virtualWrite(V5, "You Reached the daily limit for this session and further inputs are neglected.\nYou can reset the device to start the new counting.\n\n"); |
| 80 | + } else { |
| 81 | + bool isFilled = false; |
| 82 | + char* messages[] = { message1, message2, message3 }; |
| 83 | + |
| 84 | + if (messagecount <= MSG_ACCEPTED_PER_SESSION) { |
| 85 | + for (int i = 0; i < TOTAL_MSG_ACCEPTED; i++) { |
| 86 | + if (!isFilled) { |
| 87 | + if (!strlen(messages[i])) { |
| 88 | + strncpy(messages[i], param.asStr(), MAX_MESSAGE_LENGTH); |
| 89 | + |
| 90 | + Serial.println(String(" Message ") + messagecount + String(" Received")); |
| 91 | + Blynk.virtualWrite(V2, String(" Message ") + messagecount + String(" Received")); //screen display |
| 92 | + Blynk.virtualWrite(V5, String(" Message ") + messagecount + String(" Received\n\n")); //terminal display |
| 93 | + isFilled = true; |
| 94 | + } |
| 95 | + } else { |
| 96 | + break; |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + if (!isFilled) { |
| 101 | + rotateMessages(param.asStr()); |
| 102 | + Serial.println(String(" Message ") + messagecount + String(" Received")); |
| 103 | + Blynk.virtualWrite(V2, String(" Message ") + messagecount + String(" Received")); // screen output |
| 104 | + Blynk.virtualWrite(V5, String(" Message ") + messagecount + String(" Received\n")); //terminal display |
| 105 | + } |
| 106 | + } |
| 107 | + } |
| 108 | +} |
| 109 | + |
| 110 | +// Reset the mesages |
| 111 | +BLYNK_WRITE(V7) { |
| 112 | + int reset = param.asInt(); |
| 113 | + |
| 114 | + if (reset == 1) { |
| 115 | + Serial.println("Reset Performed"); |
| 116 | + strncpy(message1, " ", MAX_MESSAGE_LENGTH); |
| 117 | + strncpy(message2, " ", MAX_MESSAGE_LENGTH); |
| 118 | + strncpy(message3, " ", MAX_MESSAGE_LENGTH); |
| 119 | + Blynk.virtualWrite(V8, " "); //clear the virtual display |
| 120 | + // Only reset count after the MSG_accepted for session is above the limit |
| 121 | + if (messagecount >= MSG_ACCEPTED_PER_SESSION) { |
| 122 | + messagecount = 0; |
| 123 | + Blynk.virtualWrite(V5, "Counting Reset\n\n"); |
| 124 | + } // Only reset count after the MSG_accepted for session is above the limit |
| 125 | + } |
| 126 | + Blynk.virtualWrite(V5, reset == 0 ? "Reset performed\n\n" : ""); //terminal display |
| 127 | + Blynk.virtualWrite(V2, reset == 0 ? "Reset performed\n\n" : ""); |
| 128 | +} |
| 129 | + |
| 130 | +struct animations { |
| 131 | + textEffect_t anim_in; //animation type |
| 132 | + textEffect_t anim_out; //animation type |
| 133 | + const char* textOut; //text to display |
| 134 | + uint16_t speed; //animation speed (multiplier for library default) |
| 135 | + uint16_t pause; //delay (multiplier * 500ms) |
| 136 | + textPosition_t just; //justify |
| 137 | +}; |
| 138 | + |
| 139 | +animations animList[] = { |
| 140 | + //{anim_in,anim_out,textout,speed,pause,justify} |
| 141 | + |
| 142 | + { PA_SCROLL_LEFT, PA_SCROLL_LEFT, message1, 3, 0, PA_LEFT }, |
| 143 | + { PA_SCROLL_LEFT, PA_SCROLL_LEFT, message2, 3, 0, PA_LEFT }, |
| 144 | + { PA_SCROLL_LEFT, PA_SCROLL_LEFT, message3, 3, 0, PA_LEFT }, |
| 145 | + // { PA_SCROLL_LEFT,PA_SCROLL_LEFT, "SC_LT",5,0,PA_LEFT}, |
| 146 | + // { PA_BLINDS,PA_GROW_DOWN, "BLINDs",2,2,PA_CENTER}, |
| 147 | + // { PA_SCROLL_DOWN,PA_SCROLL_DOWN_LEFT, "see",4,2,PA_LEFT}, |
| 148 | + // { PA_SCROLL_UP_RIGHT,PA_SCROLL_UP_RIGHT, "you",4,2,PA_RIGHT}, |
| 149 | + // { PA_SCROLL_DOWN_RIGHT,PA_SCROLL_DOWN_RIGHT, "soon",4,2,PA_CENTER} |
| 150 | + |
| 151 | +}; |
| 152 | + |
| 153 | +// this should be after animlist[] structure member only esle we get error as not declared animlist[] |
| 154 | +BLYNK_WRITE(V6) { |
| 155 | + int sliderValue = param.asInt(); |
| 156 | + // map the slider value to the desired animation speed range |
| 157 | + int minSliderValue = 1; |
| 158 | + int maxSliderValue = 10; |
| 159 | + int minAnimationSpeed = 1; |
| 160 | + int maxAnimationSpeed = 10; |
| 161 | + |
| 162 | + // calculate the animation speed based on the mapped slider value |
| 163 | + int animationSpeed = map(sliderValue, minSliderValue, maxSliderValue, minAnimationSpeed, maxAnimationSpeed); |
| 164 | + char animtext[20] = "Speed set as:\t"; |
| 165 | + Blynk.virtualWrite(V2, "Speed Updated"); |
| 166 | + // adjust the animation speed for all animations in the animList |
| 167 | + for (uint8_t i = 0; i < ARRAY_SIZE(animList); i++) { |
| 168 | + animList[i].speed = animationSpeed; |
| 169 | + } |
| 170 | +} |
| 171 | + |
| 172 | +void setup() { |
| 173 | + // Debug console |
| 174 | + Serial.begin(115200); |
| 175 | + |
| 176 | + //Blynk.begin(auth, ssid, pass); |
| 177 | + // You can also specify server: |
| 178 | + Blynk.begin(auth, ssid, pass, "blynk.cloud", 8080); |
| 179 | + //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080); |
| 180 | + Blynk.virtualWrite(V8, " "); //clear the virtual display |
| 181 | + Blynk.virtualWrite(V1, mode); // wifi or gsm |
| 182 | + Blynk.virtualWrite(V5, "Using WiFi\nConnected to Blynk...\n\n"); |
| 183 | + Blynk.virtualWrite(V5, "This Program is configured to dispaly only three recent messages\nYou can now enter the messages\n\n"); |
| 184 | + Blynk.virtualWrite(V2, "Blynk Started"); |
| 185 | + P.begin(); |
| 186 | + |
| 187 | + for (uint8_t i = 0; i < ARRAY_SIZE(animList); i++) { |
| 188 | + animList[i].speed *= P.getSpeed(); |
| 189 | + animList[i].pause *= 1000; |
| 190 | + } |
| 191 | +} |
| 192 | + |
| 193 | +uint8_t i = 0; //text effect index |
| 194 | + |
| 195 | +void loop() { |
| 196 | + Blynk.run(); // Run the Blynk library's internal tasks |
| 197 | + |
| 198 | + |
| 199 | + char* messages[] = { message1, message2, message3 }; // Array of message pointers |
| 200 | + // int numMessages = sizeof(messages) / sizeof(messages[0]); // Calculate the number of messages |
| 201 | + if (P.displayAnimate()) //animate and return true when an animation is completed |
| 202 | + { |
| 203 | + if (i == TOTAL_MSG_ACCEPTED) i = 0; //reset loop index |
| 204 | + //Dont display the message if the recieved new message is null value or a space and also avoid the repeated messages |
| 205 | + if (messages[i][0] != '\0' && messages[i][0] != ' ' ) { |
| 206 | + P.displayText(animList[i].textOut, animList[i].just, animList[i].speed, animList[i].pause, animList[i].anim_in, animList[i].anim_out); |
| 207 | + delay(delayValue_ms); |
| 208 | + Blynk.virtualWrite(V8, messages[i]); |
| 209 | + } |
| 210 | + |
| 211 | + i++; //then start next text effect |
| 212 | + } |
| 213 | +} |
| 214 | + |
| 215 | + |
| 216 | + |
| 217 | + |
| 218 | +// To optimize the provided program, you can consider the following suggestions: |
| 219 | + |
| 220 | +// Reduce memory usage: |
| 221 | + |
| 222 | +// Instead of using fixed-size character arrays for messages (message1, message2, message3), you can use dynamic memory allocation to save memory. For example, you can use String objects or dynamically allocated character arrays (using new and delete operators). |
| 223 | +// Instead of using a fixed-size array (animList[]) for animations, you can use a dynamic data structure like a linked list or vector to add or remove animations as needed. |
| 224 | +// Avoid using String class: |
| 225 | + |
| 226 | +// The String class in Arduino uses dynamic memory allocation, which can lead to memory fragmentation and instability. It's better to use character arrays (char[]) for storing and manipulating strings. |
| 227 | +// Avoid concatenating strings with the + operator in print statements. Instead, use snprintf or strcpy to copy strings into a single buffer and then print the buffer. |
| 228 | +// Optimize Blynk updates: |
| 229 | + |
| 230 | +// Instead of sending virtual writes for each message count update, you can update the value periodically or only when it changes significantly. |
| 231 | +// Consider reducing the number of virtual writes to the terminal display (V5) and using a buffer to accumulate multiple messages before sending them together. |
| 232 | +// Minimize code duplication: |
| 233 | + |
| 234 | +// You can avoid duplicating code for handling messages by using loops and arrays more effectively. For example, you can store the messages in an array and iterate over them instead of explicitly checking each message variable (message1, message2, message3). |
| 235 | +// Use PROGMEM for constant data: |
| 236 | + |
| 237 | +// If you have constant data that doesn't change during runtime (e.g., animation text), you can store it in program memory (PROGMEM) instead of RAM to save space. |
| 238 | +// Profile and optimize the animations: |
| 239 | + |
| 240 | +// Measure the execution time of the animation functions and optimize them if necessary. Look for any delays or bottlenecks that can be eliminated or reduced. |
| 241 | +// Consider using interrupts or timers: |
| 242 | + |
| 243 | +// If possible, use interrupts or timers instead of delay functions to allow for better multitasking and responsiveness in your program. |
| 244 | + |
| 245 | + |
| 246 | + |
| 247 | + |
0 commit comments