# Question
Title: Problem cleaning string read from serial buffer
I am trying to move a `stepper motor` when a specific command is send to `Arduino Mega 2560`. This command is read character by character and stored in a `string variable`. Whenever a new command is sent, an act should be performed. However, it is not happening and I believe that the problem is in reading the sent command. I tried clearing the character and string variables, but to no avail. The sketch should run a loop that moves the motor `clockwise` or `counterclockwise` according to the command sent, which can be `"crx*"` for clockwise or `"clx*"` for anticlockwise, where `"*"` is the reading stop criterion of the characters. Any suggestions what to do? The script:

```
void(* resetFunc) (void) = 0;//Reset turn

// Stepper Motor X
const int stepPinX = 2; //X.STEP
const int dirPinX = 5; // X.DIR
const int pinEnable = 8;

// String read
char c;
String readString; //main captured String

// Unit steps
double av_len = 1.029; //medium length
double interval;
int cnt_steps = 0;
const int num_d = 200;//parameterized step
int fact = int(num_d / av_len);
int unit_len = fact * 1;//unit length (1mm)

void setup()
{
  // Sets pins as Outputs
  pinMode(stepPinX, OUTPUT);
  pinMode(dirPinX, OUTPUT);
  pinMode(pinEnable, OUTPUT);

  digitalWrite(pinEnable, HIGH);//lock driver on cnc shield

  Serial.begin(115200);
  Serial.setTimeout(1);

  while (1) {

    while ( (Serial.available() == 0) )
    {

    }

    if (Serial.available())  {
      c = Serial.read();  //gets one byte from serial buffer
      //Serial.println(readString);
      if (c == '*') {
        Serial.println(readString);//test response
        if (readString == "crx") {
          cnt_steps = cnt_steps + 1;
          Serial.println(cnt_steps);
          digitalWrite(pinEnable, LOW);
          digitalWrite(dirPinX, HIGH);
          for (int x = 0; x < unit_len; x++) {
            digitalWrite(stepPinX, HIGH);
            delayMicroseconds(500);
            digitalWrite(stepPinX, LOW);
            delayMicroseconds(500);
          }

        }
        else if (readString == "clx") {
          cnt_steps += -1;
          Serial.println(cnt_steps);
          digitalWrite(pinEnable, LOW);
          digitalWrite(dirPinX, LOW);
          for (int x = 0; x < unit_len; x++) {
            digitalWrite(stepPinX, HIGH);
            delayMicroseconds(500);
            digitalWrite(stepPinX, LOW);
            delayMicroseconds(500);
          }
        }
         digitalWrite(pinEnable, HIGH);//lock driver on cnc shield
         c = (char)0;
         Serial.flush();
         readString = "";
         //resetFunc();
      }

      else {
        readString += c; //makes the string readString

      }
    }
  }
}

void loop() {

}

```

# Answer
> 1 votes
When sending text commands to an Arduino, it is common to define a “line-oriented protocol”: each command is transmitted as a single line, with the line ending signifying the end of the command. Common line endings are carriage return (CR = `'\r'` = `0x0d` = 13), line feed (LF = `'\n'` = `0x0a` = 10) and the sequence CR+LF.

The Arduino serial monitor is designed to support this convention by automatically appending a line ending when you press “Send”. This line ending can be configured to one of the following options:

* No line ending
* Newline (meaning “line feed”)
* Carriage return
* Both NL & CR (but CR is actually sent before LF)

In your case, you have chosen to use `'*'` as a command termination character. For this to work, you have to choose “No line ending” and add the “\*” explicitly to the command. Alternatively, you may consider changing your sketch so that it expects `'\r'` or `'\n'`, which is a more standard way of ending a command.

# Answer
> 0 votes
In addition to the good responses you have already received, I offer this.

For the Arduino, know the differences between String string and char arrays - there is much on this e.g., https://forum.arduino.cc/t/string-vs-string-vs-char-arrays-correct-approach/537468 . Many do not want to deal with the vagaries of String, but their use can be convenient.

Run this code:

```
String readstring = "xxx";

void setup() {
  Serial.begin(115200);
}

void loop() {
  if (Serial.available()) {
    readstring = Serial.readStringUntil('/n');
    Serial.print(readstring);
    Serial.println(" received");
    if (readstring.equals("crx")) {
      // move counter clockwise
      Serial.println("moving counter clockwise");
      // counterclockwise() <-- your function
    }
    else if (readstring.equals("clx") ) {
      // move clockwise
      Serial.println("moving clockwise");
      // clockwise() <-- your function
    }
    else {
      // bad command
      Serial.println("Bad command received - no action");
      // badcommand() <-- your function
    }
  }
}

```

If you add functions for the stepper, it may do what you want within a limited context and with using the Arduino serial monitor for input. Take a look at the output.

Note that the serial monitor is set to "no line ending". The terminating character '/n' is provide by your input in the serial monitor. It will do what you want, but again, many advise you stay away from String.

---
Tags: serial, string, buffer, char
---


title: Multiple client server over wifi

text:
# Question
Title: Multiple client server over wifi
Trying to setup a server on Arduino to support multiple clients, I am able to support one but I don't want to flush that client to make another connection.

```
#include <ESP8266WiFi.h>
const char* ssid = "your-ssid";
const char* password = "your-password";
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  delay(10);

  // prepare GPIO2
  pinMode(2, OUTPUT);
  digitalWrite(2, 0);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }

  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();

  // Match the request
  int val;
  if (req.indexOf("/gpio/0") != -1)
    val = 0;
  else if (req.indexOf("/gpio/1") != -1)
    val = 1;
  else {
    Serial.println("invalid request");
    client.stop();
    return;
  }

  // Set GPIO2 according to the request
  digitalWrite(2, val);

  client.flush();

  // Prepare the response
  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
  s += (val)?"high":"low";
  s += "</html>\n";

  // Send the response to the client
  client.print(s);
  delay(1);
  Serial.println("Client disonnected");

  // The client will actually be disconnected
  // when the function returns and 'client' object is detroyed
}

```

Using this code, the server handles only one client at a time, but I need to connect multiple clents simultaneously.

# Answer
You need to keep track of multiple `WiFiClient`s - declare an array of them, for example, and each time `server.available()` gives you a new one, store it in the array.

Then you need to make sure your code doesn't stick waiting for data from each item. You could service each WifiClient in turn: if it has data waiting (`client[i].available()` is true), read the data (`client[i].read()`) and store it. When you get a `\r` from a client, you know you have a whole line, and you can process it.

Here's a nearly-complete (but untested) example so you can see what I'm talking about. Naturally it's not the only way to do it.

```
#include <ESP8266WiFi.h>
const char* ssid = "your-ssid";
const char* password = "your-password";
#define MAX_CLIENTS 10
#define MAX_LINE_LENGTH 50
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);
WiFiClient *clients[MAX_CLIENTS] = { NULL };
char inputs[MAX_CLIENTS][MAX_LINE_LENGTH] = { 0 };

void setup() {
  Serial.begin(115200);
  delay(10);

  // prepare GPIO2
  pinMode(2, OUTPUT);
  digitalWrite(2, 0);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  // Check if a new client has connected
  WiFiClient newClient = server.available();
  if (client) {
    Serial.println("new client");
    // Find the first unused space
    for (int i=0 ; i<MAX_CLIENTS ; ++i) {
        if (NULL == clients[i]) {
            clients[i] = new WiFiClient(newClient);
            break;
        }
     }
  }

  // Check whether each client has some data
  for (int i=0 ; i<MAX_CLIENTS ; ++i) {
    // If the client is in use, and has some data...
    if (NULL != clients[i] && clients[i]->available() ) {
      // Read the data
      char newChar = clients[i]->read();

      // If we have the end of a string
      // (Using the test your code uses)
      if ('\r' == newChar) {
        // Blah blah, do whatever you want with inputs[i]

        // Empty the string for next time
        inputs[i][0] = NULL;

        // The flush that you had in your code - I'm not sure
        // why you want this, but here it is
        clients[i]->flush();

        // If you want to disconnect the client here, then do this:
        clients[i]->stop();
        delete clients[i];
        clients[i] = NULL;

      } else {
        // Add it to the string
        strcat(inputs[i], newChar);
        // IMPORTANT: Nothing stops this from overrunning the string and
        //            trashing your memory. You SHOULD guard against this.
        //            But I'm not going to do all your work for you :-)
      }
    }
  }

}

```
> 7 votes

# Answer
Here , I have used array of WiFiClient . The reason is array pointer will hold previous plus latest WiFiClients (emoteIP and remotePort ) and user will be able to choose which WIFiClient to be used for communication.

We can store IPAddress , Port as well as whole WiFiClient object in an array

```
 //===========================================
       WebServer  Wserver(80);

       WiFiClient Wclient;

       WiFiClient *Wificlients[10] = { NULL };

       int  Clientindex=-1;

       Wclient = Wserver.client(); // or  server.avilable() if WiFiServer

       Wificlients[Clientindex++]=new WiFiClient(Wclient);

       int   cntloggedinclient=0;
       int kk=0;

       while(Wificlients[kk] != NULL)
           {
               cntloggedinclient++;  // Total clients count
               kk++;
           }

         // Multicasting bytes to all connected clients.
         int kkk =0;
         while(kkk<cntloggedinclient)
         {
           Wificlients[kkk]->write((unsigned char*) &newbuff,len);
           kkk++;
         }

```
> 0 votes

# Answer
I have a solution using RTOS Tasks, I think this is the best way to manage multiple clients at same time. I test this code in ESP32 dev module.

```
#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE 0
#else
#define ARDUINO_RUNNING_CORE 1
#endif
#include <WiFi.h>

const char* ssid = "[YOUR-NETWORK-SSID]";
const char* password = "[YOUR-SSID-PASSWORD]";

void TaskClientSocket( void *pvParameters );

WiFiServer wifiServer(80);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(1000);
  WiFi.begin(ssid,password);
  Serial.println("Connecting to Wifi...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("Connected to WiFi network");
  Serial.println(WiFi.localIP());

  wifiServer.begin();
}

void loop() {
  WiFiClient client = wifiServer.available();
  if( client){
    Serial.println("New Client Connected...");
    xTaskCreatePinnedToCore(
    TaskClientSocket
    ,  "TaskClientSocket"
    ,  4098
    ,  &client
    ,  2
    ,  NULL
    ,  ARDUINO_RUNNING_CORE);
  }
}

void TaskClientSocket( void *pvParameters )
{
    WiFiClient clientHandle = *((WiFiClient*)pvParameters);
    for (;;)
    {
      while(clientHandle.connected()){
        while(clientHandle.available()>0){
          char c = clientHandle.read();
          clientHandle.write(c);
        }
        vTaskDelay(100);
      }
      clientHandle.stop();
      Serial.println("Client disconnected");
      vTaskDelete(NULL);
    }
}

```
> -1 votes

---
Tags: arduino-ide, esp8266, web-server, tcpip
---


# Question
Title: TMRpcm not compatible incompatible with current board
My goal is to play sounds with my Arduino Nano Every. I tried the example sketch that comes with the library but I get the error:

```
**WARNING: library TMRpcm-master claims to run on avr architecture(s) and may be incompatible with your current board which runs on megaavr architecture(s).**

```

Is there such a big difference between the Nano and Nano every?

# Answer
I opened a issue on GitHub and the result is: tmrpcm only runs on avr architecture so it is incompatible with megaavr architecture(s).
> 1 votes

---
Tags: arduino-nano, tmrpcm, arduino-nano-every
---


# Question
Title: Reply from the SIM800l module is being cut short
I have a sim800l module connected to the Rpi pico hardware UART

```
/*
SIM800       RPi Pico
5v           *External 2A 5v supply*
GND          GND
VDD          3v3
TXD          GP1
RXD          GP0
*/

void setup()
{
  Serial.begin(115200);

  while (!Serial)
    ;

  Serial1.begin(9600);

  Serial.print("Initializing");
  delay(1000);
  Serial.print(".");
  delay(1000);
  Serial.print(".");
  delay(1000);
  Serial.println(".");

  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  Serial1.println("AT"); //Once the handshake test is successful, it will back to OK
  updateSerial();
  delay(3000);

  Serial1.println("ATI"); //Returns the module name and revision.
  updateSerial();
  delay(3000);

  Serial1.println("AT+CCID"); //Read SIM information to confirm whether the SIM is plugged
  updateSerial();
  delay(3000);

  Serial1.println("AT+COPS?"); //Checks which network you are connected to
  updateSerial();
  delay(3000);

  Serial1.println("AT+COPS=?"); //Returns the list of operators present in the network.
  updateSerial();
  delay(3000);

}

void loop()
{
  updateSerial();
}

void updateSerial()
{
  delay(200);
  while (Serial.available())
  {
    Serial1.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while (Serial1.available())
  {
    Serial.write(Serial1.read());//Forward what Software Serial received to Serial Port
  }

}

```

terminal response

```
AT
OK
ATI
SIM800 R14.18

OK
AT+CCID
XXXXXXXXXXXXXXXXXXXX
AT+COPS?
+COPS: 0,0,"Vodaa TelAT+COPS=?
+COPS: (2,"Vodaa Telecom","Ver

```

From what i know so far the SIM800L always ends its response with an "OK" but there are some commands that are cut short and not end with OK. such as AT+CDID and AT+COPS. I do not know if the problem is with the pico or with sim800l. The sim800l seems to be working fine so i suspect its with the pico but if so, it might be a problem with the internal libraries which is beyond me. To supoort that theory the number of characters that is being cut is about 20 characters, so it might be a setting i have to adjust

# Answer
> 0 votes
Took me quite a while, but upon reading the pico's documentation

> The size of the receive FIFO may also be adjusted from the default 32 bytes by using the setFIFOSize call prior to calling begin()
>
> ```
> Serial1.setFIFOSize(128);
> Serial1.begin(baud);
>
> ```

settinng it to a much higher value like 256 solves the problem

---
Tags: uart, sim800, raspberrypi-pico
---


title: ESP8266 RTC memory (for bootcount)

text:
# Question
Title: ESP8266 RTC memory (for bootcount)
I'm using an ESP8266 with deep sleep + wake up when `RST` pin goes low.

```
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266HTTPClient.h>
WiFiClient client;
HTTPClient http;
RTC_DATA_ATTR int bootcount = 0;

void setup() {
    bootcount ++;
    WiFi.begin("MySSID", "password");
    while (WiFi.status() != WL_CONNECTED) {
        delay(20);
    }
    // here I send "bootcount" with HTTP request
    ESP.deepSleep(0);
}
void loop() {
}

```

Here `RTC_DATA_ATTR int bootcount = 0;` fails with `RTC_DATA_ATTR` unknown.

**How to get the number of times the ESP8266 has woke up from deep sleep?**

# Answer
The ESP8266 RTC has 512 bytes of RAM that persist across restarts but not during power outages. While this RAM isn't persistent across power outages it also doesn't have the write limitations that flash memory has, making it appropriate for frequent writes which don't need to survive power loss.

The ESP32's compiler and software framework make it easy to access similar memory on it using the `RTC_DATA_ATTR` attribute; unfortunately as you found and @Juraj pointed out, the ESP8266's doesn't.

Thankfully the Arduino core for the ESP8266 includes support for reading and writing this area of memory using methods in the `ESP` object.

`ESP.rtcUserMemoryRead()` reads RTC memory and `ESP.rtcUserMemoryWrite()` writes RTC memory. In your case you could do something like this:

```
void setup() {
  uint32_t bootcount;

  if(!ESP.rtcUserMemoryRead(0, &bootcount, sizeof(bootcount))) {
    Serial.println("RTC read failed!");
    while(1)
      yield();
  }

  bootcount++;

  if(!ESP.rtcUserMemoryWrite(0, &bootcount, sizeof(bootcount))) {
    Serial.println("RTC write failed!");
    while(1)
      yield();
  }

  Serial.begin(115200);
  Serial.print("boot count is ");
  Serial.println(bootcount);
}

void loop() {
}

```

Not quite as convenient as the `RTC_DATA_ATTR` attribute but it still gets the job done.

I changed the type of `bootcount` from your example to `uint32_t` because it should never be negative, and the size of `uint32_t` is independent of the size of `int`.

Because the Arduino core is open source, you can read the implementation of these functions if you want to know how they work.
> 5 votes

---
Tags: esp8266, sleep
---


# Question
Title: Set control register to low in ds3231 rtc
I have been using ds3231 rtc module for keep tracking and make alarm along with backup battery. when I used it for first time it worked fine. but now it doesn't keep track my time when the power lose it from main power but I have checked that my battrey is in safe. So I search in lot of forums they said EOSC bit was set high that would be stoped the clock as it stops the internal oscillator. also want to set it into low then only rtc keep track of the time

but in another some forums they instructed that put this following code for set it to low

```
DS3231 RTC;

  Wire.beginTransmission(0x68);
  Wire.write(0xF);                            // Address the Status register
  Wire.write(0x00);                           //  Zero the Status register
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(0xE);                            // Address the Status register
  Wire.write(0x00);                           //  Zero the Status register
  Wire.endTransmission();

  RTC.setA2Time( ADay, AHour, AMin, 0x00, true, false, false);
  delay(100);
  RTC.turnOnAlarm( 2 );

```

in another place showed the following code

```
// clear /EOSC bit to ensure that the clock runs on battery power
  Wire.beginTransmission(0x68); // address DS3231
  Wire.write(0x0E); // select register
  Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
  Wire.endTransmission();

```

but now problem is that where should I want to place this code and how to past it in proper manner for keep tracking the time when ds3231 loses power too? please any know about this problem because I finded so many people are strugling with this issue when they come forward to use this ds3231 rtc module. if any body know about how to solve this issue plese consider to share your idea this will definately help full for evryone because there is no one properly answer for this issue

# Answer
From the DS3231 data sheet:

**Control Register (0Eh)**

Bit 7: Enable Oscillator (EOSC). When set to logic 0, the oscillator is started. When set to logic 1, the oscillator is stopped when the DS3231 switches to VBAT. This bit is clear (logic 0) when power is first applied. When the DS3231 is powered by VCC, the oscillator is always on regardless of the status of the EOSC bit. When EOSC is disabled, all register data is static.

**Status Register (0Fh)**

Bit 7: Oscillator Stop Flag (OSF). A logic 1 in this bit indicates that the oscillator either is stopped or was stopped for some period and may be used to judge the validity of the timekeeping data. This bit is set to logic 1 any time that the oscillator stops. The following are examples of conditions that can cause the OSF bit to be set:

1. The first time power is applied.
2. The voltages present on both VCC and VBAT are insufficient to support oscillation.
3. The EOSC bit is turned off in battery-backed mode.
4. External influences on the crystal (i.e., noise, leakage,etc.). This bit remains at logic 1 until written to logic 0.

I dug out an old D3231 board. It had a battery in it but was last set ~3 years ago and I am not sure how old the battery was when I first put it in the board. The battery cannot keep the clock running. When I attached it to an Arduino UNO and booted up, the clock’s registers read as follows (just pay attention to the time and the EOSC bit and the OSF flag):

CLOCK: 00:01:15 (24h clock) Sunday, 01/01/2000 Temperature=21C Aging offset=0

Alarm #1: 00:00:00 (24h clock) DY/DT=18\[DoM mode\] Alarm selection: when date, hours, minutes and seconds match

Alarm #2: 00:00 (24h clock) DY/DT=20\[DoM mode\] Alarm selection: when date, hours, minutes match

CONTROL byte=00011100 /EOSC is ON /BBSQW is Disabled /CONV is clear /INTCN mode is Match /Alarm 1 is Disabled /Alarm 2 is Disabled

STATUS byte=10000000 /OSF is ON /EN32KHZ Disabled /BSY is OFF /A1F is OFF /A2F is OFF

The clock is now running because with VCC supplied by the Arduino, the oscillator will always run. When I read the clock, I can see the time advancing, but it started from 00:00:00

Now, I remove power and after a minute or so, power up the UNO and the clock, and read the clock. It is again running, but the time had not advanced – it simply restarted from 00:00:00. EOSC is ON. OSF is ON.

With no VBAT, the time was not preserved.

A fresh battery is inserted and I power up. The clock is again running, again, restarted at 00:00:00. EOSC is ON. OSF is ON.

After a couple of minutes, I power down (with the fresh battery still in the clock). When I boot up and read the clock, it is running AND it kept running on battery power, so the current time is accurate. EOSC is ON. OSF is ON.

EOSC was always enabled (read as 0) – that is the POR value. Unless your program explicitly sets the bit to 1, EOSC will reliably be enabled. If you do disable EOSC (set to 1), the oscillator will NOT run off of the battery backup (VCC off and VBAT on). With EOSC disabled, and if there is enough juice in the battery, it will hold the time (and other registers) when VCC is switched off and VBAT is on. When VCC is on, the oscillator will always run.

But, what about the OSF flag?

Reading the data sheet, you can see that the OSF flag gets set when the oscillator stops, which can occur from a number of conditions.

It is designed so that the software can legitimately suspect that the time is not accurate, But, OSF is set as the POR value.

**You need to enable EOSC AND CLEAR OSF**, every time you do a clean power up and every time OSF got set because you unplugged (no VCC) and changed batteries. Also, remember, that with VCC, the oscillator will run regardless of the state of the EOSC bit.

Do not ignore OSF, it is an important flag and it should not be getting set regularly. In fact, once you insert a battery and clear OSF, it should not be set again until the battery drains. If it is getting set regularly, you have problems elsewhere.

Some software reads OSF and if it is set, the software will balk and tell you as much, as it should. Since OSF is set on POR, it will be set whenever you remove VCC and VBAT and then power up again.

**You need to explicitly clear OSF AND know why it got set.**

This code snippet, enables EOSC AND clears OSF.

```
 // enable EOSC and clear OSF flag
 // *** The other bits in these two registers are writtten
 // with POR Values or '0' if POR value=X.
  Wire.beginTransmission(0x68); // address DS3231
  Wire.write(0x0E); // select CONTROL register
  Wire.write(0b000011100); // write register (bit 7 is EOSC)
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(0x0F); // select STATUS register
  Wire.write(0b00001000); // write register (bit 7 is OSF)
  Wire.endTransmission();

```

Hope it helps.
> 1 votes

# Answer
I also have a DS3231 RTC in my robot project. Here's my complete setup code. This can be placed anywhere in setup(): I don't think you have to mess with individual registers to get what you want.

```
    if (rtc.begin()) //02/19/19 this now returns FALSE if RTC doesn't respond
    {
        Serial.println("Found RTC...");
        delay(100);
        bRTCLostPower = rtc.lostPower(); //added 10/17/18
        mySerial.printf("rtc.lostPower() reports %d\n", bRTCLostPower);

        if (rtc.lostPower())
        {
            Serial.println("RTC lost power.  Setting RTC to last compile time");
            rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));// sets RTC to last compile date/time
        }

#ifdef FORCE_RTC_TO_LAST_COMPILE_TIME
        Serial.println("Forcing RTC to last compile time");
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));// sets RTC to last compile date/time
#endif

        DateTime now = rtc.now();
        char buffer[100];
        memset(buffer, '\0', 100);
        mySerial.printf("Retrieving Date/Time from RTC with rtc.now() =  %ld\n", now.unixtime());
        GetDayDateTimeStringFromDateTime(now, buffer);
        Serial.print("Date/Time: "); Serial.println(buffer);
        RTC_Avail = true;
    }
    else
    {
        Serial.println("Couldn't find RTC. Real-time clock functions won't be available");
        RTC_Avail = false; //use this instead
    }

    if (RTC_Avail && rtc.lostPower())
    {
        DateTime Comp_dt = DateTime(F(__DATE__), F(__TIME__)); //__DATE__ & __TIME__ are environment variables)
        uint8_t mydayofweek = Comp_dt.dayOfTheWeek();  //returns 0 for Sunday, 6 for Saturday dayOfTheWeek
        int mymonth = Comp_dt.month();
        int myday = Comp_dt.day();
        int myyear = Comp_dt.year();
        int myhour = Comp_dt.hour();
        int mymin = Comp_dt.minute();
        int mysec = Comp_dt.second();
        long unixtime = Comp_dt.unixtime();
        char* dayofweek = (char*)daysOfTheWeek[mydayofweek];

        Serial.print("day of week value = "); Serial.println(mydayofweek);
        Serial.print("day of week value = "); Serial.println(Comp_dt.dayOfTheWeek());

        mySerial.printf("RTC lost power - setting to datetime of last compile %ld (%s %4d/%02d/%02d at %02d:%02d:%02d)\n",
            unixtime, dayofweek, myyear, mymonth, myday, myhour, mymin, mysec);

        rtc.adjust(Comp_dt);
    }

```
> -1 votes

---
Tags: arduino-uno, arduino-ide, power, rtc, ds3231-alarms
---


# Question
Title: Single Method for 2 Ultrasonic Sensor is not working as expected
So I have created a method to read and return Ultrasonic Sensor Data. I have 2 Ultrasonic Sensors.

Below is my code.

```
    // Ultrasonic Pins
    #define T1 2
    #define E2 4
    #define E1 3
    #define T2 5
    // Motor Pins
    #define M1 7
    #define M2 8
    #define M3 9
    #define M4 10
    // Motor Movements Definition
    enum MOTOR
    {
        FORWARD,
        BACKWARD,
        LEFT,
        RIGHT,
        STOP
    };

    long duration1, distance1, duration2, distance2;

    void setup()
    {
        Serial.begin(9600);
        pinMode(E1, INPUT);
        pinMode(E2, INPUT);
        pinMode(T1, OUTPUT);
        pinMode(T2, OUTPUT);
        pinMode(M1, OUTPUT);
        pinMode(M2, OUTPUT);
        pinMode(M3, OUTPUT);
        pinMode(M4, OUTPUT);
        Motor(STOP);
    }

    void loop()
    {

        // If Both Sensors detect object then go in backward Direction
        while (DetectObject(T1,E1,1) < 10 && DetectObject(T2,E2,2) < 10)
        {
            Serial.println("Backward");
            Motor(BACKWARD);
            delay(200);
            Motor(STOP);
            delay(50);
        }
        // If Left Sensor detect object then go in Right Direction
        while (DetectObject(T1,E1,1) < 10 && DetectObject(T2,E2,2) > 10)
        {
            Serial.println("Right");
            Motor(RIGHT);
            delay(200);
            Motor(STOP);
            delay(50);
        }
        // If Right Sensor detect object then go in Left Direction
        while (DetectObject(T1,E1,1) > 10 && DetectObject(T2,E2,2) < 10)
        {
            Serial.println("Left");
            Motor(LEFT);
            delay(200);
            Motor(STOP);
            delay(50);
        }
        // If Both Sensors detect no object then go in Forward Direction
        while (DetectObject(T1,E1,1) > 10 && DetectObject(T2,E2,2) > 10)
        {
            Serial.println("Forward");
            Motor(FORWARD);
            delay(200);
            Motor(STOP);
            delay(50);
        }
    }

    void Motor(MOTOR motor)
    {
        switch (motor)
        {
        case STOP:
            digitalWrite(M1, LOW);
            digitalWrite(M2, LOW);
            digitalWrite(M3, LOW);
            digitalWrite(M4, LOW);
            break;
        case FORWARD:
            digitalWrite(M1, HIGH);
            digitalWrite(M2, LOW);
            digitalWrite(M3, HIGH);
            digitalWrite(M4, LOW);
            break;
        case BACKWARD:
            digitalWrite(M1, LOW);
            digitalWrite(M2, HIGH);
            digitalWrite(M3, LOW);
            digitalWrite(M4, HIGH);
            break;
        case LEFT:
            digitalWrite(M1, HIGH);
            digitalWrite(M2, LOW);
            digitalWrite(M3, LOW);
            digitalWrite(M4, HIGH);
            break;
        case RIGHT:
            digitalWrite(M1, LOW);
            digitalWrite(M2, HIGH);
            digitalWrite(M3, HIGH);
            digitalWrite(M4, LOW);
            break;
        default:
            break;
        }
        delay(100);
    }

    long DetectObject(uint8_t trigPin, uint8_t echoPin, int sensorNo)
    {
        digitalWrite(trigPin, LOW);
        delayMicroseconds(2);
        digitalWrite(trigPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(trigPin, LOW);
        Serial.print("Distance Sensor");
        Serial.print(sensorNo);
        Serial.print(": ");
        Serial.print(pulseIn(echoPin, HIGH) * 0.034 / 2);
        Serial.println(" cm");
        return pulseIn(echoPin, HIGH) * 0.034 / 2;
    }

```

I am getting continuously getting `Backward` in the Serial monitor.

Output of Serial Monitor -

```
Distance Sensor1: 20 cm
Distance Sensor2: 15 cm
Backward
Distance Sensor1: 17 cm
Distance Sensor2: 21 cm
Backward
Distance Sensor1: 24 cm
Distance Sensor2: 9 cm
Backward

```

But when I created 2 different methods for each Ultrasonic Sensor. It is working fine.

I want to have a single method for N number of Ultrasonic Sensors.

Thanks in Advance!

# Answer
> 0 votes
The problem lies in the function, that does the ultrasonic detection. First I would suggest to not do Serial printing between the trigger pulse and `pulseIn()`, since the Serial transmission might take longer (for example when the buffer is full) and then your reading is garbage. Execute `pulseIn()` directly after the trigger pulse part and save the result in a local variable, which you can later print and return. If you do that, your problem is also solved.

For understanding what actually happens with your code, I annotated the function with some comments:

```
long DetectObject(uint8_t trigPin, uint8_t echoPin, int sensorNo)
    {
        // Create Trigger pulse
        digitalWrite(trigPin, LOW);
        delayMicroseconds(2);
        digitalWrite(trigPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(trigPin, LOW);

        // Do some printing
        Serial.print("Distance Sensor");
        Serial.print(sensorNo);
        Serial.print(": ");

        // Read a pulse and print it directly to Serial
        Serial.print(pulseIn(echoPin, HIGH) * 0.034 / 2);
        Serial.println(" cm");

        // Read ANOTHER pulse and return it
        return pulseIn(echoPin, HIGH) * 0.034 / 2;
    }

```

As you can see, you are trying to read 2 pulses. But there is only one echo pulse. That one pulse is read by the first execution of `pulseIn()` and you print the result to Serial, so in the Serial Monitor you are seeing the correct value.

After that you are executing `pulseIn()` again and returning the result. `pulseIn()` will wait for a pulse to begin (so it can start counting the time). But there is no second pulse on the echo line, so `pulseIn()` will exit after a timeout (by default 1s). On timeout this function returns zero. So every time you execute this function, it will return zero.

If you then look at the logic in `loop()`, you can easily see why you are only getting backwards. The code is stuck in the first while loop, because the value returned from the function is always zero, which is smaller than 10.

Here is a pseudo code version of how your function really should work:

```
execute trigger pulse
execute pulseIn function and save result in local variable
print whatever you want to Serial
return the value of the local variable

```

---
Tags: arduino-ide, arduino-nano, motor, code-review, ultrasonics
---


title: Confusion regarding PID library?

text:
# Question
Title: Confusion regarding PID library?
PID library is available(built in) in standard installation of arduino IDE or do we have to download it additionaly after installing our IDE?

How can i check which of libraries are available in my standard installation?

# Answer
> 2 votes
Open the Library Manager and search for the library you want. You will see a list of libraries matching your query. Under the name of each of those libraries, you will see a line showing the author and the version number.

* if this lines stats with “Built-in”, then it is a library that comes with the standard installation of the IDE
* if the line ends with “INSTALLED”, then this library is installed in your system.

---
Tags: library, pid
---


# Question
Title: Error resolving FQBN (Fully Qualified Board Name)
In Arduino IDE, I get this error "Error resolving FQBN: getting", when compiling a sketch. Can anyone help me get around this problem?

I am using the Arduino IDE. I have installed the M5Stack official 2.0.5-1.0 boards in Board Manager and the STAMP-PICO 0.0.2 library in Library Manager.

I get the following Compile error with ALL sketches, even the STAMP-PICO Basics IO example sketch.

"Error resolving FQBN: getting Error compiling for board STAMP-PICO."

Strangely ... in Arduino IDE v2.0.3, on the same computer using the same libraries and boards, the sketch compiles ok.

Sounds like something specific to Arduino IDE v1

# Answer
> 3 votes
OK - I resolved the issue, myself.

The Boards Manager installations became confused, probably because I was using both Arduino 1.8.19 and Arduino IDE 2.0.3 on the same computer.

Somehow, the folder ~/Library/Arduino15/packages/m5stack/hardware/esp32/ contained more than one version of the esp32 board libraries, v2.0.5 as well as v2.0.5-1.0 and c2.0.5+1.0.

My fix involved uninstalling the M5 esp32 board library altogether and making sure that all sub-folder versions had been deleted too. Then, reinstalling the latest board version and restarting the Arduino IDE app.

---
Tags: m5stack
---


# Question
Title: i need help on how to use busy pin in df player to arduino
i need help on how to use busy pin in df player to arduino.... while playing one sound or df player is busy, i don't want to trigger df player by ultrasound sensors to play another song. here is my code without busy pin use in df player

```
#include "Arduino.h"
#include "SoftwareSerial.h"

#include "DFRobotDFPlayerMini.h"

const byte SENSOR_COUNT = 5;
byte triggerPins[SENSOR_COUNT] = {2,4,6,8,10};
byte echoPins[SENSOR_COUNT]    = {3,5,7,9,11};

SoftwareSerial mySoftwareSerial(12, 13); // RX, TX

DFRobotDFPlayerMini myDFPlayer;

void printDetail(uint8_t type, int value);

void setup()
{
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);

  for( byte i=0; i<SENSOR_COUNT; i++ )
  {
    pinMode(triggerPins[i], OUTPUT);
    pinMode(echoPins[i], INPUT);
  }

  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true);
  }
  Serial.println(F("DFPlayer Mini online."));

  myDFPlayer.volume(10);  //Set volume value. From 0 to 30

}

int currentSound = -1;
void loop()
{

  for( byte i=0; i<SENSOR_COUNT; i++ ) // loop through all distance sensors
  {
    if( detectPresence(i) ) // check if there is an object near it
    {
      if(currentSound!=i) // check that it's a different sensor than the one that was last triggered
      {
        Serial.print("play song number ");
        Serial.println(i);
        myDFPlayer.play(i+1); // play song nr `i+1`
      }
      currentSound = i;
    }
  }

  if (myDFPlayer.available()) {
    printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
  }

}

// detectPresence will return TRUE if there is an object close to it.
bool detectPresence(byte sensorNr)
{
  if( sensorNr>=SENSOR_COUNT )
    return false;
  long duration, distance;
  //digitalWrite(triggerPins[sensorNr], LOW);  // Added this line
  //delayMicroseconds(10); // Added this line
  digitalWrite(triggerPins[sensorNr], HIGH);
  delayMicroseconds(15); // Added this line
  digitalWrite(triggerPins[sensorNr], LOW);
  duration = pulseIn(echoPins[sensorNr], HIGH);
  distance = duration/58;

  return distance<30;// choose your own value here, from which distance it should trigger a sound
}

void printDetail(uint8_t type, int value){

  switch (type) {
    case TimeOut:
      Serial.println(F("Time Out!"));
      break;
    case WrongStack:
      Serial.println(F("Stack Wrong!"));
      break;
    case DFPlayerCardInserted:
      Serial.println(F("Card Inserted!"));
      break;
    case DFPlayerCardRemoved:
      Serial.println(F("Card Removed!"));
      break;
    case DFPlayerCardOnline:
      Serial.println(F("Card Online!"));
      break;
    case DFPlayerPlayFinished:
      Serial.print(F("Number:"));
      Serial.print(value);
      Serial.println(F(" Play Finished!"));
      break;
    case DFPlayerError:
      Serial.print(F("DFPlayerError:"));
      switch (value) {
        case Busy:
          Serial.println(F("Card not found"));
          break;
        case Sleeping:
          Serial.println(F("Sleeping"));
          break;
        case SerialWrongStack:
          Serial.println(F("Get Wrong Stack"));
          break;
        case CheckSumNotMatch:
          Serial.println(F("Check Sum Not Match"));
          break;
        case FileIndexOut:
          Serial.println(F("File Index Out of Bound"));
          break;
        case FileMismatch:
          Serial.println(F("Cannot Find File"));
          break;
        case Advertise:
          Serial.println(F("In Advertise"));
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }
}

```

# Answer
The busy pin is just a pin, that gets driven LOW, when a song is playing, and HIGH when nothing is playing. So connect it to a free digital IO pin on your Arduino and set that pin to input with:

```
pinMode(busy_pin, INPUT);

```

(Note: You yourself need to define `busy_pin`, since I don't know where you will connect it). Then just read this pin in the if statement together with `detectPresence(i)`:

```
if(!digitalRead(busy_pin) && detectPresence(i))

```

The `!` is to make the expression true, when `digitalRead(busy_pin)` returns 0 (LOW). This way the code will not even check for presence, when there is currently a song playing.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: control 12v motor with NPN transistor via arduino
* i want to control this **12v** motor via arduino:

Power source is 12v 5A

motor will work 5 seconds in every 5 minutes and will be activated throught arduino mega

i will try to use **bd679a darlington transistor**:

* Collector - Base Voltage (Vcbo) 80 V
* Collector - Emitter Voltage (Vceo) 80 V
* Collector Current (Ic) 4 A
* Power Dissipation (Pd) \[Tcase≤25°C\] 40 W
* Transition Frequency (fТ) 10 MHz
* Min. DC current gain (β) 750
* Integrated diode Yes Case TO-126 Package type -14h

**Do i need to add diode(and will that drop voltage ) ?**

**also do i need any ressistors and why?**

# Answer
You are missing 2 things:

* You should add a resistor between the Arduino digital IO pin and the base of the transistor. Bipolar transistors are current amplifiers. Normally for driving motors with a microcontroller you want the transistor to operate in saturation anyway, so there is no need to fine tune the resistor. It is there for protecting the output pin of the Arduino from over current. The calculation is easy: Resistance is voltage divided by current `R = U / I`. The voltage is 5V for an Arduino Mega (output voltage of the digital IO pins is equal to the operating voltage of the Mega, thus 5V). The current here is the max current, that the output pin can withstand (you find such information in the datasheet of the microcontroller). It is 20mA for continuous load.

So `R = 5V / 20mA = 250 Ohm`. Thus you need a resistor with at least 250 Ohm. 330 Ohm is normally readily available, so often people use one of these.

You also asked about how many wants it should withstand. This is also easy to calculate: Power (in Watts) is voltage multiplied by current. So `P = U * I = 5V * 20mA = 0.1W`. So in this configuration the resistor will not ever need to withstand more than 0.1W. So 1/4W is enough.
* When driving motors you should include a flyback diode. This is a diode in reverse direction connected across the terminals of the motor. A motor is an inductive load (since it basically consists of some coils and magnets). Driving it with a varying voltage (like you need for controlling the motors speed or just to start and stop the motor) will induce reverse voltage spikes. These might damage your transistor and/or the Arduino. With the flyback diode connnected these voltage spikes can safely dissipate through that diode and not causing any harm.

So the circuit looks like this:

simulate this circuit – Schematic created using CircuitLab
> 1 votes

---
Tags: arduino-mega, motor
---


# Question
Title: Can a three wire Electrical conductivity sensor (Sensorex CS 150) be used directly with arduino?
I am having an electrical conductivity sensor (Sensorex CS150 with three tinned wires Red, Black and white https://sensorex.com/product/sensorex-cs150-12-mm-graphite-contacting-conductivity-sensor/ ). I want to measure EC of nutrient soultion used in aquaponics. I have searched on internet for connection setup and everywhere sensor (with BNC connector) is connected to arduino via expansion board. Do I require this type of expansion board or can I directly connect sensor to analog pin of arduino.

# Answer
EC electrodes is an active sensor that requires an excitation voltage to be applied to get the result. When A DC voltage is apply to the two conductors, it caused iron to be flow from one conductor to another, causing polarisation and chemical reaction. Therefore you can't use it directly with Arduino.

To measure EC you need a Wien bridge oscillator which is used to generate an alternative current(AC) waveform for the excitation of the EC electrode. In order to avoid polarization, an alternative current (AC) typically ranging from 1kHz to 20kHz is used to provide the exitation of the electrode. The AC current is read and converted back to a DC voltage as the measurement result.

You also need a precision amplifier in order to get a meaningful measurement.

The EC value is also subject to temperature changes, so it may also requires to measure the temperature of the liquid and adjust the result for temperature compensation.

I have an product review article where it describe how EC measurement works and what is required (both hardware and software) to measure EC, you might want to further read to understand more.

Other reference:

Conductive of a solution - Andy Connelly.

Conductivity Measurement Theory Guide -.

One-chip conductivity meter monitors salt concentration - Michael Ahmon Electronics/Sept 15, 1977.
> 2 votes

# Answer
Product Manual

Seem to be a simple conductivity measurement so applying a voltage direct from the Arduino via a suitable resistor and using an analog input to measure the voltage drop should work OK. You may need to experiment with the resistor value to get a good range of readings depending on the conductivity of the solution you are measuring
> 0 votes

---
Tags: arduino-uno, sensors, electronics
---


# Question
Title: How do I stop my servo from repeating the loop and perform the rest of the functions?
The project has a makeshift meter (via a half circle cutout and a servo motor operated lever). On program start (button 2), the lever will move to the left hand side at the 9 o'clock position. Once in place, after a short delay, the program will accept input from the button 1 and keep a count while moving the lever toward the 3 o’clock position stopping at at 10-2 w 2 sec delay. When it reaches the position, it stops the count and remembers it.

Repeat same thing but with buttons 4 and 5 respectively. Really important that the count is saved for both buttons 1 and 5.

Pressing button 3 will measure the inputs of button 5 and display them on the meter as a ratio of button 5 presses over button 1 + button 5 presses. If it leans right, that means you had more presses in the first stage than second (for ease of understanding I’ll probably have instructions that say to start with right hand so that leaning right means right hand dominance and left is left handed). Below is a picture of my set up.

\*I numbered the buttons 1-5 left to right not by the pin number.

The problem I have is that after button 2 or 4 get pushed the servo just keeps moving to the seven positions I have set as a timer over and over.

```
#include <Servo.h>

const int button1 = 2;   // button 1 pin/left hand main pin
const int button2 = 3;   // button 2 pin/left start pin
const int button3 = 4;   // button 3 pin/right hand main pin
const int button4 = 5;   // button 4 pin/right start pin
const int button5 = 6;   // button 5 pin/results pin
const int servoPin = 9;  // servo motor pin

int count1 = 0;          // counter for button 1
int count2 = 0;          // counter for button 5

Servo servo;             // servo motor object

void setup() {
  // set button pins as inputs
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  pinMode(button4, INPUT);
  pinMode(button5, INPUT);

  servo.attach(servoPin); // attach servo motor to pin
}

void loop() {
  if (digitalRead(button2) == HIGH) {  // if button 2 is pressed
    // move servo motor to 9 o'clock position
    servo.write(180);
    delay(500);  // wait for servo to reach position

    // start accepting input from button 1
    while (digitalRead(button1) == LOW) {
      count1++;  // increment counter
      // move servo motor to 3 o'clock position
      servo.write(180);
      delay(2000);  // wait for servo to reach position
      servo.write(150);
      delay(2000);  // wait for servo to reach position
      servo.write(120);
      delay(2000);  // wait for servo to reach position
      servo.write(90);
      delay(2000);  // wait for servo to reach position
      servo.write(60);
      delay(2000);  // wait for servo to reach position
      servo.write(30);
      delay(2000);  // wait for servo to reach position
      servo.write(0);
      delay(2000);  // wait for servo to reach position

    }

    // repeat the same process for button 4
    while (digitalRead(button4) == LOW) {
      count2++;  // increment counter
      // move servo motor to 3 o'clock position
      servo.write(180);
      delay(2000);  // wait for servo to reach position
      servo.write(150);
      delay(2000);  // wait for servo to reach position
      servo.write(120);
      delay(2000);  // wait for servo to reach position
      servo.write(90);
      delay(2000);  // wait for servo to reach position
      servo.write(60);
      delay(2000);  // wait for servo to reach position
      servo.write(30);
      delay(2000);  // wait for servo to reach position
      servo.write(0);
      delay(2000);  // wait for servo to reach position
    }
  }

  if (digitalRead(button3) == LOW) {  // if button 3 is pressed
    // calculate ratio of button 4 presses to total button presses
    float ratio = (float)count2 / (count1 + count2);

    // Display ratio on meter
    servo.write(90 + (int)(ratio * 90));
  }
}

```

# Answer
> 0 votes
You have pulldown resistors on all your buttons, so all of your input pins are LOW when nobody is touching the buttons. When you press a button, the input goes HIGH. In your code, when you do

```
  if (digitalRead(button2) == HIGH) {  // if button 2 is pressed

```

it enters the if block, if the button is pressed, because the button2 input is high when the button is pressed. Then you move the servo to position 180 and wait a bit. The next line

```
    while (digitalRead(button1) == LOW) {

```

enters the while loop if the input pin is low. The input pin is that, when the button is NOT pressed, because of the pulldown resistor and that is why the servo starts moving when button2 is pressed, unless button1 is also pressed when you press button2. To stop that, change the LOW to HIGH in the while loop condition. Then it will only enter the while loop when the button is pressed and skip it if it is not pressed..

As suggested by the busybee, you might benefit from studying state machines.

---
Tags: arduino-uno
---


# Question
Title: Why am I receiving this Error: Debug exception reason: Stack canary watchpoint triggered (task1) in ESP32 using a FreeRTOS program?
I'm getting this error by running a FreeRTOS program on my ESP32 using arduino ide, I don't understand why this happens because this same program works on an arduino Uno with no errors:

```
Guru Meditation Error: Core  0 panic'ed (Unhandled debug exception).
Debug exception reason: Stack canary watchpoint triggered (task1)
Core  0 register dump:
PC      : 0x40088a4f  PS      : 0x00060636  A0      : 0x800d3155  A1      : 0x3ffb9130
A2      : 0x3ffb8eb4  A3      : 0xffffffff  A4      : 0x00060620  A5      : 0x00060623
A6      : 0x00060623  A7      : 0x00000001  A8      : 0x00000001  A9      : 0x00000000
A10     : 0x00060623  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x00000000
A14     : 0x007bee88  A15     : 0x003fffff  SAR     : 0x00000000  EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000

```

This is the code I'm using:

```
//#include <Arduino_FreeRTOS.h>
//Overload happens if xTaskGetTickCount – lastTickCount (the first parm to vTaskDelayUntil) is >= period in ticks

void task1(void *pvParameters);
void task2(void *pvParameters);
void task3(void *pvParameters);

void setup() {

  Serial.begin(115200);

  //Create tasks
//xTaskCreate(Task function, Task name, , Task parameter, Task priority, );
  Serial.println("111111");
  xTaskCreate(task1, "task1", 512, NULL, 1, NULL);
  Serial.println("222222");
  xTaskCreate(task2, "task2", 512, NULL, 2, NULL);
  xTaskCreate(task3, "task3", 512, NULL, 3, NULL);
  //vTaskStartScheduler();

}

void loop() {}

void task1(void *pvParameters) {

  (void) pvParameters;
  TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

  waketime = xTaskGetTickCount();

  while(1){

    Serial.println('M'); //This happens almost immediately, so we need to add an artificial delay, a  to simulate a task running for a few ms, it only serves as a notification that the task started
    vTaskDelay(10);
    if(xTaskGetTickCount() - waketime >= period)
      Serial.println("Overload in task 1");

    vTaskDelayUntil(&waketime, period);

  }

}

void task2(void *pvParameters) {

  (void) pvParameters;
  TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

  waketime = xTaskGetTickCount();

  while(1) {

    Serial.println('E'); //This happens almost immediately, so we need to add an artificial delay, a  to simulate a task running for a few ms, it only serves as a notification that the task started
    vTaskDelay(10);
    if(xTaskGetTickCount() - waketime >= period) Serial.println("Overload in task 2");
    vTaskDelayUntil(&waketime, period);

  }

}

void task3(void *pvParameters) {

  (void) pvParameters;
  TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

  waketime = xTaskGetTickCount();

  while(1) {

    Serial.println('S'); //This happens almost immediately, so we need to add an artificial delay, a  to simulate a task running for a few ms, it only serves as a notification that the task started
    vTaskDelay(10);
    if(xTaskGetTickCount() - waketime >= period) Serial.println("Overload in task 3");
    vTaskDelayUntil(&waketime, period);

  }

}

```

I tried increasing the task stack memory in xtaskcreate and the same error occurs, although when I increased it to 1024 nothing shows up in the serial monitor. This same program works flawlessly on arduino uno and raspberry pi pico. I also tried changing the tasks' period and their execution time, which is the delay, and it still doesn't work

# Answer
> 0 votes
> although when I increased it to 1024 nothing shows up in the serial monitor.

Doing nothing to your code except using 4096 for stack size causes it to print things on serial.

```
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13864
load:0x40080400,len:3608
entry 0x400805f0
111111
222222M

E
S
S
E
M
S
ME

```

I won't tell you that it's correct, but it seems fairly clear that you haven't given it enough stack to work with.

With my current setup

```
Serial.println(configMINIMAL_STACK_SIZE);

```

is printing 828. I don't know how exactly how to interpret that number. But unless I found otherwise, I could default to considering it the requirement to start a task that uses no stack of it own (no local variables, no calling). The memories of the esp32 seem large enough that no matter how you're using them it doesn't make sense to go so minimal for a handful to tasks. I chose 4096 somewhat arbitrarily. I'm not suggesting is a good value.

---
Tags: arduino-ide, esp32
---


# Question
Title: DS3231 Clock project shows right date but wrong day
Heeya Guys! Today I created a project with the help of instructables site. I followed the on screen steps and everything. Uploaded the sketch and it works like a charm, but there's one problem.

Everything works correctly but not the "Day", i.e as of today its Friday, 9 April 2021, the clock shows the correct time and date but it tells that today is "Tuesday" in place of Friday. I don't know why this is happening. Any help would be appreciated :) Here's the code that I'm using:

```
/*Arduino Clock by AnthoTRONICS
* Last edit: March 22,2019
*/
// Libraries you'll need (Same as the ones in the guide:
// TAKE NOTE OF THE VERSIONS!!!

// MD Parola 3.0.1: https://github.com/MajicDesigns/MD_Parola // click the link to download the library
// MD_MAX72XX 3.0.2: https://github.com/MajicDesigns/MD_MAX72XX //click the link to download the library
// DS3231 1.0.2: https://github.com/NorthernWidget/DS3231 // click the link to download

/*CODE:*/
// Header file includes
// These are for the matrix
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include "Font_Data.h"

//These are for the clock
#include <DS3231.h>
#include <Wire.h>
DS3231 Clock;

bool Century=false;
bool h12;
bool PM;
byte  dd,mm,yyy;
uint16_t  h, m, s;

#define MAX_DEVICES 4 // Set the number of devices
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE,CS_PIN, MAX_DEVICES);

#define SPEED_TIME 75 // speed of the transition
#define PAUSE_TIME  0

#define MAX_MESG  20

// Global variables
char szTime[9];    // mm:ss\0
char szMesg[MAX_MESG+1] = "";

uint8_t degC[] = { 6, 3, 3, 56, 68, 68, 68 }; // Deg C
uint8_t degF[] = { 6, 3, 3, 124, 20, 20, 4 }; // Deg F

char *mon2str(uint8_t mon, char *psz, uint8_t len)

// Get a label from PROGMEM into a char array
{
  static const __FlashStringHelper* str[] =
  {
    F("Jan"), F("Feb"), F("Mar"), F("Apr"),
    F("May"), F("Jun"), F("Jul"), F("Aug"),
    F("Sep"), F("Oct"), F("Nov"), F("Dec")
  };

  strncpy_P(psz, (const char PROGMEM *)str[mon-1], len);
  psz[len] = '\0';

  return(psz);
}

char *dow2str(uint8_t code, char *psz, uint8_t len)
{
  static const __FlashStringHelper*  str[] =
  {
  F("Sunday"), F("Monday"), F("Tuesday"),
  F("Wednesday"), F("Thursday"), F("Friday"),
  F("Saturday"), F("Sunday")
  };

  strncpy_P(psz, (const char PROGMEM *)str[code-1], len);
  psz[len] = '\0';

  return(psz);
}
// Time Setup: Code for reading clock time
void getTime(char *psz, bool f = true)
{
  s = Clock.getSecond();
  m = Clock.getMinute();
  h =Clock.getHour(h12,PM); //24hr Format
  sprintf(psz, "%02d%c%02d", h, (f ? ':' : ' '), m);
  //12hr Format
  //uncomment if you want the clock to be in 12hr Format
  /*if (Clock.getHour(h12,PM)>=13 || Clock.getHour(h12,PM)==0)
  {
    h = Clock.getHour(h12,PM) - 12;
  }
  else
  {
    h = Clock.getHour(h12,PM);
  }*/

}

void getDate(char *psz)
// Date Setup: Code for reading clock date
{
   char  szBuf[10];

   dd=Clock.getDate();
   mm=Clock.getMonth(Century); //12
   yyy=Clock.getYear();
   sprintf(psz, "%d %s %04d",dd , mon2str(mm, szBuf, sizeof(szBuf)-1),(yyy + 2000));
 //strcpy(szMesg, "29 Feb 2016");
}

void setup(void)
{
  P.begin(2);
  P.setInvert(false); //we don't want to invert anything so it is set to false
  Wire.begin();

  P.setZone(0,  MAX_DEVICES-4, MAX_DEVICES-1);

  P.setZone(1, MAX_DEVICES-4, MAX_DEVICES-1);
  P.displayZoneText(1, szTime, PA_CENTER, SPEED_TIME, PAUSE_TIME, PA_PRINT, PA_NO_EFFECT);

  P.displayZoneText(0, szMesg, PA_CENTER, SPEED_TIME, 0,PA_PRINT , PA_NO_EFFECT);

  P.addChar('$', degC);
  P.addChar('&', degF);

}

void loop(void)
{
  static uint32_t lastTime = 0; // millis() memory
  static uint8_t  display = 0;  // current display mode
  static bool flasher = false;  // seconds passing flasher

  P.displayAnimate();

   if (P.getZoneStatus(0))
  {
    switch (display)
    {
      case 0:    // Temperature deg C
      P.setPause(0,1000);
      //P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_UP);
      P.setTextEffect(0, PA_MESH, PA_BLINDS);
      display++;
      dtostrf(Clock.getTemperature(), 3, 1, szMesg);
      strcat(szMesg, "$");
      //strcat(szMesg, "26.5$");

        break;

      case 1: // Temperature deg F
        //P.setTextEffect(0, PA_SCROLL_UP, PA_SCROLL_LEFT);
        P.setTextEffect(0, PA_OPENING, PA_GROW_DOWN);
        display++;
        dtostrf((1.8 *Clock.getTemperature() )+32, 3, 1, szMesg);
        strcat(szMesg, "&");

   // strcpy(szMesg, "71.6&");

        break;

      case 2: // Clock

     P.setFont(0, numeric7Seg);
     P.setTextEffect(0, PA_PRINT, PA_NO_EFFECT);
     //Sleep Mode
     //Uncomment to enable Sleep Mode and adjust the hours to your needs
     /*if (h==12 || h<8)//Time intervals (in this case, from 12AM to 8AM)
     {
      P.setIntensity(0); //Set display brightness to lowest setting
     }
     else
     {
      P.setIntensity(6); //Set display brightness to 6 (15 is the brighest)
     }*/
     P.setPause(0,0);

     if (millis() - lastTime >= 1000)
    {
    lastTime = millis();
    getTime(szMesg, flasher);
    flasher = !flasher;
    }
    if(s==00&& s<=30){
    display++;
    P.setTextEffect(0, PA_PRINT, PA_SCROLL_UP);
    }

    //  strcpy(szMesg, "36 % RH");

        break;

      case 3: // day of week

        P.setFont(0,nullptr);
        P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
        display++;
        dow2str(Clock.getDoW()+1, szMesg, MAX_MESG); // Added +1 to get correct DoW

       //dow2str(5, szMesg, MAX_MESG);
        break;
      default:  // Calendar

        P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
        display = 0;
        getDate(szMesg);
        break;
    }

    P.displayReset(0);
  }

}

```

# Answer
The library seems to be addressing device register 3. According to the DS3231 datasheet this register has valid values 1-7, with 1 being Sunday.

You have:

```
dow2str(Clock.getDoW()+1, szMesg, MAX_MESG);

```

1-7 becomes 2-8. And then, how `dow2str`:

```
strncpy_P(psz, (const char PROGMEM *)str[code-1], len);

```

2-8, become array indices 1-7.

Your array is:

```
  static const __FlashStringHelper*  str[] =
  {
  F("Sunday"), F("Monday"), F("Tuesday"),
  F("Wednesday"), F("Thursday"), F("Friday"),
  F("Saturday"), F("Sunday")
  };

```

The indices here start at 0, so everything is off-by-one. But, I don't know how you get Tuesday out of Friday. If you cut your code down to something smaller that is testable without the display code, just using `Serial`, you'll probably get better answers.
> 1 votes

# Answer
I did this project and my weekday was off by 1, always a day earlier I fixed this by removing the Sunday at the beginning of the list and moving it to the end why you had two Sunday entries I do not know. That fixed my issue. I do not know why yours is showing Tuesday for Friday though.

char \*dow2str(uint8\_t code, char *psz, uint8\_t len) { static const \__FlashStringHelper* str\[\] = { F("Monday"), F("Tuesday"), F("Wednesday"), F("Thursday"), F("Friday"), F("Saturday"),F("Sunday") }
> 0 votes

---
Tags: max7219, ds3231-alarms, led-matrix
---


# Question
Title: Raspberry Pi, Teensy and Arduino's on i2c
I just got into an interesting mess.

I have 3 Arduino's (Pro Mini's) and 2x Teensy's (3.1's) connected via I2C to a Raspberry Pi Master. The 2x Teensy's I2C data lines are connected via OctoBoards but that doesn't really matter since the OctoBoard maps the I2C Pin's of the Teensy to itself. I have 4k7 pullup resistors for SDA/SLC close to the master (also tried on the end - with no effect).

The Arduino's alone are super solid - no issues other than the occasionally I2C lockup when writing data.

The I2C interface has been running for over 3h with no problems.

Now as soon I add a Teensy to it, the bus locks-up and I need to completely shut down everything. Only thing I got to work was direct connection from RPI -\> Teensy and even then there were sporadic detection issues.

I tried the Wire lib as well the IC2\_T3 lib with no difference. Also tried with 4 different Teensy's with no difference.

Are the Teensy's not compatible with RPI?

# Answer
I do not have experience with your exact setup, but I once had a similar problem. I had a pi as I2C master, a battery module that used I2C to communicate battery status and two servo controllers attached. The servo controllers alone worked and the battery module alone worked, but all three attached to the pi didn't work and there was no collision in I2C addresses (have you checked that btw?). It turns out, that both servomodules and the battery module had I2C pullup resistors attached, so the end result was 3x4k7 in parallel, which is around 1566 ohm. The solution was to remove the pullup resistors from the servo controllers.

So the question is, have you by any chance enabled pullup resistors on any of the arduinos/teensys/pi in addition to your own resistors, resulting in wrong pullup resistor value?
> 1 votes

---
Tags: i2c, arduino-pro-mini, teensy
---


# Question
Title: 4x3 keypad not providing any output and the output it does provide is incorrect
I am trying to figure out how to use a 4x3 keypad and just want to receive the key numbers I select on the serial monitor. The problem I am getting is that some of the keys I type don't give me any output and then the keys that do provide output do not match their corresponding number. For example key 1 does not provide any output, whereas keys 3 and 4 give an output of 4 and 9 respectively. I have attached pictures of how the keypad is connected

The code that I am using is below:

```
#include <Keypad.h>

// Constants for row and column sizes
const byte ROWS = 4;
const byte COLS = 3;

// Array to represent keys on keypad
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

// Connections to Arduino
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3};

// Create keypad object
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup() {
  // Setup serial monitor
  Serial.begin(9600);
}

void loop() {
  // Get key value if pressed
  char customKey = customKeypad.getKey();

  if (customKey) {
    // Print key value to serial monitor
    Serial.println(customKey);}
}

```

I just need help identifying where I am going wrong and how I can fix the problem I am having. Thanks.

# Answer
I determined where I was going wrong. The keypad has a different wiring compared to the traditional way of doing it. I found this this article helpful. The changes made to the code are as follows:

```
byte rowPins[ROWS] = {8, 3, 4, 6};
byte colPins[COLS] = {7, 9, 5};

```

As can be seen, the rows and columns pins need to be changed.
> 2 votes

---
Tags: arduino-uno, programming, wires, keypad
---


# Question
Title: Pls help with this prompt. I've been struggling last 2 days with this and its due tomorrow
"Use an Arduino, two potentiometers, and an alarm. Make one of the potentiometers act like a volume control, and make the other potentiometer control the tone that the alarm makes." I added what I have so far. I'm not sure how to control the volume

# Answer
Use the other potentiometer as a variable resistor. Instead of connecting to pins 1 and 3 (to control tone), Use the 2nd pin of the potentiometer to make a voltage divider. From the 3rd pin go to a + on a buzzer. I don't see the reason to have the circuit connected the way you have. if you want to control the tone with potentiometer, connect it to stable 5v, and connect the second pin with any analog pins that is configured as input. Then, use map function, and map the voltage, accordingly to the tone you'd like to use.
> 2 votes

---
Tags: potentiometer, buzzer
---


title: Arduino 75kHz output frequency setup

text:
# Question
Title: Arduino 75kHz output frequency setup
i don't know how to manipulate arduino uno or mega registers and timers to be close to 75kHz output frequency. Could you help please ?

# Answer
First you have to compute, from your desired frequency, the number of CPU cycles per period of the signal:

F\_CPU / 75 kHz = 16,000 kHz / 75 kHz ≈ 213.33

Since the timers can only count up to an integer, the closest you can get is 213 CPU cycles. The frequency you get will then be

F\_CPU / 213 = 16,000 kHz / 213 ≈ 75.12 kHz

Now you can configure a timer. I find that the easiest is to use a so called “fast PWM” mode. Choose one of those modes where the TOP value can be set with a register, and set it to one unit less than the desired period: the timer will then repeatedly count from 0 to 212.

Here is an example using channel A of Timer 1 on an Arduino Uno. The output is on digital pin 9 = OC1A = PB1:

```
// Configure Timer 1 for PWM @ 75.12 kHz.
DDRB  |= PB1;         // set OC1A = PB1 as output
TCCR1A = 0;           // clear the settings of the Arduino core
TCCR1B = 0;           // ...ditto
TCNT1  = 0;           // clear the timer
TCCR1A = _BV(COM1A1)  // non-inverting PWM on OC1A
       | _BV(WGM11);  // mode 14: fast PWM, TOP = ICR1
TCCR1B = _BV(WGM12)   // ...ditto
       | _BV(WGM13)   // ...ditto
       | _BV(CS10);   // clock at F_CPU
ICR1   = 213 - 1;     // period = 213 CPU cycles = 13.3125 us
OCR1A  = 213/2 - 1;   // duty cycle ~ 50%

```

You can easily adapt this to any timer on the Uno or Mega. Just avoid Timer 0 if you are going to use the Arduino timekeeping functions.
> 3 votes

# Answer
I think the answer given by Edgar Bonet is the right one, all things considered, and I up-voted it for that reason.

For S&G, I want to add the following:

1. The **easiest** way is to simply use the tone(GPIO,Frequency); command - and there are caveats. **BUT**, the frequency argument is an unsigned int so the fastest frequency is 65535Hz - it will do you no good for 75kHz.

Using a frequency counter and an UNO (crystal), tone(10,65535); the output was 65556/8 Hz. On a Pro Mini 5V (ceramic resonator as I recall), it was 65540 Hz.

2. Again, for S&G, I tried this code (and adjusted the number of NOPs) to get as close as I could to 75kHz:

void setup() { pinMode(10, OUTPUT); }

```
void loop() {
here:
  digitalWrite(10, HIGH);
  delayMicroseconds(3);
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  digitalWrite(10, LOW);
  delayMicroseconds(3);
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  goto here;
}

```

The output on the UNO was 75004/6 Hz - not too bad. On the Pro Mini, the best I could do was 74986 Hz.

Of course, we are talking about square waves.
> 0 votes

---
Tags: pwm, frequency
---


# Question
Title: How I can use more than 64 analog in arduino
Hi dears I want help I’m in begging in programming. I want use more than 64 analog pin for ldr photoresistor in single reading. Because I can’t use digital pin 0-1. Any methods I can use ,,,, And How??

# Answer
> 1 votes
You basically have 2 ways to do this:

* You can use multiplexer chips, which are capable of carrying analog signals. Then you can connect the multiplexers to an analog input and the inputs of the multiplexers to the LDRs. Each multiplexer gets controlled over multiple digital pins (depending on the exact chips; it may be good to find one with a serial interface like I2C) and connects the analog input with one of the LDRs. Which one depends on the control inputs.
* You can use external ADCs (Analog Digital Converters, like the one in the Arduino). These are normally controlled over a serial interface (like I2C) and give you multiple analog inputs at once. For example this board from adafruit, which gives you 16 analog inputs and is controlled over only 2 lines (I2C, A4 and A5 on an Arduino Uno/Nano). This is probably a simpler way, though for a higher cost. If you want to to cheaper than the linked board, you may wanna use blank ADC chips instead of a breakout board.

# Answer
> 1 votes
I've just built a board that allows an Arduino to access 192 analog inputs - one at a time of course. More is possible. It uses 4067 16 x 1 analog mux chips. A single 8 bit port controls it. Need a schematic?

---
Tags: programming
---


# Question
Title: I need help with creating a menu using u8g2 library
I want to make a project with a (Nokia 5110) display using u8g2 library. Here I have the code for my program:

```
#include <Arduino.h>
#include <U8g2lib.h>
#include <TM1637Display.h>
#include <EEPROM.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

#define LED_PIN 5
#define BUTTON_PIN 6
#define BUZZ_PIN 7
#define BUTTON_L 2
#define BUTTON_R 3
#define BUTTON_START 4

//48x84 disp.
U8G2_PCD8544_84X48_F_4W_SW_SPI u8g2(U8G2_R2, 13, 11, 10, 12, 8); //rotate, clk, DIN, CE, DC, RST //

byte lastButtonState = 0;
byte ledState;
float cpu_gauge = 0.0;
char buffer[40];
int move = 7;
float cpu_gauge_step = 0.5;
byte eeprom_led;

void set_led(){
  if( digitalRead(LED_PIN) == 1 ) ledState = 1;
      if( digitalRead(LED_PIN) == 0 ) ledState = 0;}

void backlight(){
byte buttonState = digitalRead(BUTTON_PIN);  //monitor button state
  if (buttonState != lastButtonState) {  //check if not equal
    lastButtonState = buttonState;       //if prev. true, make equal
      if (buttonState == HIGH) {
        ledState = (ledState == HIGH) ? LOW : HIGH;
          digitalWrite(LED_PIN, ledState);    }}}

void status_bar(){
  if (cpu_gauge > cpu_gauge_step*1) u8g2.drawBox(2,13,6,8); //x, y , size in x, size in y
    if (cpu_gauge > cpu_gauge_step*2) u8g2.drawBox(2 + 1*move,13,6,8);
      if (cpu_gauge > cpu_gauge_step*3) u8g2.drawBox(2 + 2*move,13,6,8);
        if (cpu_gauge > cpu_gauge_step*4) u8g2.drawBox(2 + 3*move,13,6,8);
          if (cpu_gauge > cpu_gauge_step*5) u8g2.drawBox(2 + 4*move,13,6,8);
            if (cpu_gauge > cpu_gauge_step*6) u8g2.drawBox(2 + 5*move,13,6,8);
              if (cpu_gauge > cpu_gauge_step*7) u8g2.drawBox(2 + 6*move,13,6,8);
                if (cpu_gauge > cpu_gauge_step*8) u8g2.drawBox(2 + 7*move,13,6,8);
                  if (cpu_gauge > cpu_gauge_step*9) u8g2.drawBox(2 + 8*move,13,6,8);
                    if (cpu_gauge >= cpu_gauge_step*10) u8g2.drawBox(2 + 9*move,13,6,8);
}

void setup(void) {
  pinMode(LED_PIN, OUTPUT);
    pinMode(BUTTON_PIN, INPUT);
      pinMode(BUZZ_PIN, OUTPUT);
       pinMode(BUTTON_L, INPUT);
        pinMode(BUTTON_R, INPUT);
          pinMode(A7, INPUT);
            pinMode(BUTTON_START, INPUT);
              eeprom_led = EEPROM.read(0);
                digitalWrite(LED_PIN, eeprom_led);
                  set_led(); //sets the led state to 1 or 0 depending on digital write
            Serial.begin(9600);
            u8g2.begin();

}

void loop(void) {

    EEPROM.update(0,ledState);
    /*pomiar = EEPROM[ 0 ];
    delay(2500);//
    Serial.println(pomiar);//
    Serial.println(cpu_gauge);
    int pomiar = digitalRead(BUTTON_START);
    Serial.println(pomiar);*/

  backlight();
  cpu_gauge = analogRead(A7) * (5.0/1022);

  u8g2.firstPage();
  do {
  u8g2.drawRFrame(0,12,74,10,3); //pos X,Y  length, width, corner
  status_bar();

  u8g2.setFont(u8g2_font_busdisplay8x5_tr);
    u8g2.setCursor(0,8);
      char pomiar_str[5];
        dtostrf(cpu_gauge,0,2, pomiar_str);
          sprintf(buffer, "LOAD: %sV", pomiar_str);
            u8g2.print(buffer);

  u8g2.setCursor(0,36);
    u8g2.print("bckgrnd_tsks:");
      u8g2.setCursor(48,48);
        sprintf(buffer, "led: %d", ledState);
          u8g2.print(buffer);
            u8g2.drawStr(0,48,"buzz:");

  if (cpu_gauge > 4.80){
    digitalWrite(7,1);
      u8g2.setCursor(0,48);
        u8g2.setFont(u8g2_font_busdisplay8x5_tr);
          u8g2.setFont(u8g2_font_open_iconic_play_1x_t);
          u8g2.drawGlyph(27, 48, 0x0040);}
  else
    digitalWrite(7,0);

  } while ( u8g2.nextPage() );}

```

I have succesfully made a program, that:

-Has a pushbutton, to turn off, and on the backlight with each press
-Writes to the EEPROM the state of the LED, and reads it at startup
-Displays an analogRead value, from the potentiometer and also displays a progress bar of the given value
-Displays the state of the backlight
-Turns on the buzzer, if the analogRead value exceedes some value
-Displays an indicator, if the buzzer is turned on

Now, let's assume that what this program does, is called option "A", and A in this example works all the time, because there is nothing else. I want to create a menu, that would have option A, B, C, D. Assume that formatting and pushbutton actions, doesn't matter for now.

A: Is what was described before.
B: Clock. Just display a clock.
C: Stopwatch.
D: Setting the time.

I see two ways of creating such menu.

1: Is to build a selectable/scrollable menu that would have labels, and by choosing, and pressing a button, we would enter desired function.
2: Ditch the selectable menu. One pushbutton will switch from option A to D. Something like a casio watch.

I'd prefer the second option, I think it'll be easier to do

What I don't understand, is the U8G2 reference manual. I don't really understand the concept of the buffer, sendBuffer, userInterfaceSelectionList, and some more stuff, that I can't name for now.

My understanding is, that i have to make some array, of functions. Like:

```
Array [] = {default_display();, clock();, stopwatch();, setting();)

```

And with a button, I'd go thru this array like so:

```
Array = 0;
 If (digitalRead(some_button_pin) == High){
  Array + 1;}
If (Array > 3){
 Array = 0;}

```

And in those funtions, it would have implemented options, like the backlight turned on, or something else, whatever,

Now I don't know if that makes any sense. If it's transferable into code. I don't know if I need to clear the display, and how do I do that only once before entering the option. How do I make it, so that all the variables related to clock, the stopwatch still work even if I'm not displaying it. I'm honestly lost, and I just need guidance with this, becuase I have only had C for 1 semester at Electrical Engineering. I'm not a programist, but I really want to make it work, but it just isn't explained in the way like I don't know, pulldown resistors, where you can make some assumptions, and with them explain how something works. No, it looks like this:

```
void u8g2_SetBufferPtr(u8g2_t *u8g2, uint8_t *buf)

```

And yeah, I just don't know how do I go around it, how do I navigate in it. Thank you for any help.

# Answer
> 0 votes
I have figured it out. First thing that has to be said. If you're used to creating function definitions before the setup, you can't do that with u8g2 library. You can create function definitions after calling u8g2.begin in setup. Now there are two ways how you can do it, in the "Casio watch" fashion, but first create a varaible that will read how many times you've clicked, and store that somewhere, and add a condition, that will revert it to 1 after some amount of clicks. 1st way: Create a switch case, where the variable will be your switch, and in the cases (x to n) write what you want, graphics, text, whatever. Now the problem that I've had, is that when I've pasted the same code, and changed only some minor text, the whole thing glitched. It went through 1 and 2, normally, and then everything from case 3 and 4 was merged toghether, and case 4 was empty, and so was the screen. I couldn't fix it, so I came up with the second approach. Create as many IF conditions, as you have menu option. So it goes like this: If (menu\_counter == 1){ //your input to the screen// } And so for the rest. As far as I have tested this, it works, even if the code is the same for both IF statements. Now I'd have to implement the menu selection list on top. Leaving the answer to my own question, hopefully someone will find it useful.

---
Tags: lcd, library, spi, u8glib
---


title: Analog Microphone values not changing

text:
# Question
Title: Analog Microphone values not changing
I just bought a microphone for my Ardoino Nano 33 BLE. The mic can use both Analog and Digital input. Here is the mic and how it's connected.

Here is the code where I read the input

```
int sensorPin = A5; // select the input pin for the potentiometer
int sensorValue = 0;
void setup ()
{
 Serial.begin (9600);
}
void loop ()
{
 sensorValue = analogRead (sensorPin);
 delay (500);
 Serial.println (sensorValue, DEC);
}

```

I've followed an example by the manufacturer and the reads are going random between 0 and 5 sometimes a little higher. It states in the example that it should go up to 1023.

Is something wrong, can I have connected something wrong that would make this? Also when I give 5v nothing happens on the Mic but if I connect 3.3v the mic turns on 2 red led lights and gives me a value around 80 but doesnt respond to any sounds.

# Answer
> 3 votes
/\* edited to specifically provide a potential solution as commented by @jstola \*/

You have posted a picture of a ubiquitous sound detection sensor - typically a Keyes KY-037.

It is based on an LM393 dual comparator.

The board has a digital output \[marked DO\] and **an analog output marked AO**. It also has + and G (Ground) connections.

I dug mine out and attached it to a Nano 33 BLT.

Notice that I have + connected to 3.3v, G connected to ground and AO connected to A5.

A little trick is to connect just power and ground and turn the potentiometer until L2 (that's the LED nearest the pot) turns off. If you make some noise, you will see L2 flash briefly. This sets the digital output threshold and works well for testing the analog out.

Then I ran this simple program (very similar to yours)

```
void setup() {
  pinMode(A5,INPUT); // not absolutely needed in this case
  Serial.begin(9600);
}
void loop() {
  Serial.println(analogRead(A5));
}

```

Opened the Arduino IDE serial plotter (shift+ctr+L) and watched the waveform change when I snapped my fingers - see the spikes?.

So what is the solution to your problem that is does not work?

A couple of possibilities.

1. You have a different board.

Does your board look just like the one I posted or does it look different? If it is a different board then what you posted, that is another matter.

Assuming it is the same board (or at least the same generic board), it is possible that:

2. You don't have the connections correct. Double check that.
3. You don't have the pot set near the mid point - follow the direction for that and observe that the LED can be turned off. That is a multi-turn pot and if you hear a little 'click', you went too far in that direction - move it the other way and see if you can get that LED to just turn off.
4. Failing any of those, your board could be toast

# Answer
> 0 votes
Welcome! This is generic in nature because you did not provide any links to the hardware items so everything is a pure SWAG.

I cannot properly answer your question without knowing what board you have, there are several that look similar in red and other colors. Maybe the following will help you determine what you have. Look at the specifications closely.

Your statement "The mic can use both Analog and Digital input." The mic is analog by nature but can be converted to a digital signal with an op-amp or comparator circuit as many of these modules have done.

It appears to me that your board will give you a logic 1 or zero, not an analog output. The pot on those generally sets the reference voltage for the comparator (may be an op amp) function, If it is a dual op amp the other half is an amp for the microphone. If there is an analog output the microphone signal needs to be amplified as the microphone output is only a few millivolts and the A/D needs volts.

---
Tags: arduino-nano, sensors, sound
---


title: A few Bitshifting questions!

text:
# Question
Title: A few Bitshifting questions!
So `int` in Arduino is 2 bytes, which could technically hold up to a value of 65535. However, the MSB is used as a sign bit, so now we have -32,768 to 32,767. So it's a *signed integer*, easy stuff. While I was messing around with bitshifting I ran across something interesting. If I do the following code:

```
int a = 1023 << 6;  // 1023 = 0b0000001111111111
Serial.println(a, BIN);

```

it returns a ridiculous number, 11111111111111111111111111000000, which is 4 bytes. I know this is some error with bit shifting into the signed bit, because if I do

```
int a = 1023 << 5;  // equals 111111111100000 as expected

```

It works just fine. **Question 1:** What is happening here? Where is that number coming from?

So I got smart (so I thought) and was like okay, if I need more bytes, then I'll just use `long`. So I tried the following code:

```
long a = 1023 << 6;
Serial.println(a, BIN);

```

I figured I'd have 3 "extra" bytes to shift my number into. However, the same number is returned. **Question 2:** What is happening?

**Question 3:** What is the order of operations with bitshifting?

```
Wire.write(CMD_VDR | PD_NPD | voltageLevel >> 6);

```

This code I wrote produces the correct result. However, what is the order of operations? Is it just left to right? Putting `voltageLevel >> 6` in parenthesis does not change the output. *It's working fine but I want to know why!*

Thanks!

# Answer
timemage provided an excellent answer to your first question (upvoted!). Let me try to answer the subsequent ones:

> ```
> long a = 1023 << 6;
>
> ```

Here you are evaluating `1023 << 6`, then assigning the result to a `long`. It is important to realize that the C++ rules for evaluating an expression do not depend on what you are going to do later with the result. Given that `1023` is an `int` constant, the expression has the type `int` and is evaluated as such. The result is then undefined behavior, which just happens, because you are unlucky, to give the expected value, i.e. −64.

Assigning −64 to a `long` converts the type while preserving the value. This is sign extension at work. As explained by timemage, `println(long, int)` casts the value to `unsigned long`, hence the result you see.

> What is the order of operations
> \[in the expression `CMD_VDR | PD_NPD | voltageLevel >> 6`\]?

The shift has higher precedence than the bitwise OR. The expression is thus equivalent to

```
CMD_VDR | PD_NPD | (voltageLevel >> 6)

```

C.f. C++ Operator Precedence.
> 3 votes

# Answer
> So `int` in Arduino is 2 bytes

This is not true in the general case, for what it's worth. It is true of the AVR based Arduinos though, which I'll assume are in use below.

Strictly speaking, when you do `int a = 1023 << 6;` with a 16-bit integer, all bets are off, because you're already in undefined behaviour. 1023 is type `int` right hand side is expected to be of type `int` and trying to store something that won't actually fit in a signed integer is undefined.

But for the moment, lets just say it does roughly what you expect with the bit pattern, like it would for an unsigned type. You've produced the bit representation for a signed 16-bit integer with the value -64.

You're calling the `println(int, int)` here. It's in turn calling `println(long, int)` here. It is only handling `signed`ness for base 10. So, you are just forwarding your -64 value to `printNumber` here, which handle `unsigned long` values (which may have been prefixed by `-` for base 10).

So you are converting a -64 into an `unsigned long`. Conversion to unsigned types reduce modulo their maximum value plus 1. The 32-bit `unsigned long` maximum is 0xFFFFFFFF, with one added you get 0x100000000. In other words, you're ultimately printing 0x100000000 - 64, which is the number you're seeing.

`1023 << 5` does not overflow the 16-bit signed int. Does not result in a negative number (again if we're being charitable about undefined behavior) and so you see different result.
> 2 votes

---
Tags: c++
---