message:
Mqtt not subscribe on topic that's converted from String to char array

I am still not sure what should be the exact Title for this question, because I don't know where the problem is.

I am using `#include <MQTTClient.h>` mqtt library to subscribe on a topic.
This topic is created dynamically depending on the name of the device. Currently I am testing with device name `myDeviceAbc`.

    String baseTopic  = "arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing";
    String espInTopicStr  = baseTopic + "/" + config.machineName + "/espIn"; //config.machineName is a string "myDeviceAbc"

    const char* espInTopic  = "";
    espInTopic = espInTopicStr.c_str();

    const char* hardCodedTopic = "arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing/myDeviceAbc/espIn";

    int rc = client.subscribe(espInTopic, MQTT::QOS0, messageArrived);
    if (rc != 0) {
      Serial.print("rc from MQTT subscribe is ");
      Serial.println(rc);
      return;
    }
    Serial.println("MQTT subscribed");

    Serial.print("size of hardcoded topic: ");
    Serial.println(strlen(hardCodedTopic));
    Serial.print("size of actual topic: ");
    Serial.println(strlen(espInTopic));

    Serial.print("hardCodedTopic >>>");
    Serial.print(hardCodedTopic);
    Serial.print("<<<");
    Serial.println(".");

    Serial.println("---");

    Serial.print("espInTopic topic >>>");
    Serial.print(espInTopic);
    Serial.print("<<<");
    Serial.println(".");

I have defined two variables for same topic
```arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing/myDeviceAbc/espIn```
. one is hardcoded `hardCodedTopic` and other is created dynamically `espInTopic`.

when I subscribe on `espInTopic`, I get `MQTT subscribed` message on serial console BUT nothing is received on this topic when I publish from AWS portal.
but when I subscribe on `hardCodedTopic` I then receive all published messages. I cannot figure out what is the issue. I checked the mqttClient subscribe method inside the library header file, which is defined like this

    int subscribe(const char* topicFilter, enum QoS qos, messageHandler mh);

    /** MQTT Unsubscribe - send an MQTT unsubscribe packet and wait for the unsuback
     *  @param topicFilter - a topic pattern which can include wildcards
     *  @return success code -
     */
    int unsubscribe(const char* topicFilter);

It does takes const char* as topic name. I though maybe due to conversion from String to char array, there might be some unknown characters appended in the char array `espInTopic`, but I also checked the size and content of both topics which is exactly the same.

    size of hardcoded topic: 52
    size of actual topic: 52
    hardCodedTopic >>>arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing/myDeviceAbc/espIn<<<.
    ---
    espInTopic topic >>>arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing/myDeviceAbc/espIn<<<.

**Full Code:**

    #include <Arduino.h>
    #include <Stream.h>
    #include <EEPROM.h>
    #include <ArduinoJson.h>
    #include <SoftwareSerial.h>
    #include <ESP8266WiFi.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266WiFiMulti.h>
    #include "helpers.h"
    #include "global.h"

    //AWS
    #include "sha256.h"
    #include "Utils.h"

    //WEBSockets
    #include <Hash.h>
    #include <WebSocketsClient.h>

    //MQTT PAHO
    #include <SPI.h>
    #include <IPStack.h>
    #include <Countdown.h>
    #include <MQTTClient.h>

    //AWS MQTT Websocket
    #include "Client.h"
    #include "AWSWebSocketClient.h"
    #include "CircularByteBuffer.h"

    #define ACCESS_POINT_NAME  "VM"
    #define ACCESS_POINT_PASSWORD  "12345678"

    extern "C" {
      #include "user_interface.h"
    }

    //AWS IOT config, change these:
    char wifi_ssid[]       = "TALKTALKAF521F";
    char wifi_password[]   = "xxxxxxxx";
    char aws_endpoint[]    = "xxxxxxxxxxxxxxxx.iot.us-east-2.amazonaws.com";
    char aws_key[]         = "xxxxxxxxxxxxxxxx";
    char aws_secret[]      = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    char aws_region[]      = "us-east-2";

    String baseTopic  = "arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing";
    //const char* espInTopic  = "";        // was global before, but later I also tried to keep this local on subscribe() method
    const char* espOutTopic  = "";
    int port = 443;

    //MQTT config
    const int maxMQTTpackageSize = 512;
    const int maxMQTTMessageHandlers = 1;

    const char response[] = "{\"response\": {\"request_id\":, \"data\":}}";

    String nodeName = ""; // Name needs to be unique
    String nodeMac = "";

    ESP8266WiFiMulti WiFiMulti;

    AWSWebSocketClient awsWSclient(1000);

    IPStack ipstack(awsWSclient);
    MQTT::Client<IPStack, Countdown, maxMQTTpackageSize, maxMQTTMessageHandlers> client(ipstack);

    //# of connections
    long connection = 0;
    unsigned long timer = 0;
    unsigned long maxTimeOut = 7000;  //7 seconds

    //generate random mqtt clientID
    char* generateClientID () {
      char* cID = new char[23]();
      for (int i=0; i<22; i+=1)
        cID[i]=(char)random(1, 256);
      return cID;
    }

    //count messages arrived
    int arrivedcount = 0;

    //callback to handle mqtt messages
    void messageArrived(MQTT::MessageData& md)
    {
        MQTT::Message &message = md.message;

        Serial.print("Message ");
        Serial.print(++arrivedcount);
        Serial.print(" arrived: qos ");
        Serial.print(message.qos);
        Serial.print(", retained ");
        Serial.print(message.retained);
        Serial.print(", dup ");
        Serial.print(message.dup);
        Serial.print(", packetid ");
        Serial.println(message.id);
        Serial.print("Payload ");
        char* msg = new char[message.payloadlen+1]();
        memcpy (msg,message.payload,message.payloadlen);

    }

    //connects to websocket layer and mqtt layer
    bool connect () {

        if (client.isConnected ()) {
            client.disconnect ();
        }
        //delay is not necessary... it just help us to get a "trustful" heap space value
        delay (1000);
        Serial.print (millis ());
        Serial.print (" - conn: ");
        Serial.print (++connection);
        Serial.print (" - (");
        Serial.print (ESP.getFreeHeap ());
        Serial.println (")");

       int rc = ipstack.connect(aws_endpoint, port);
        if (rc != 1)
        {
          Serial.println("error connection to the websocket server");
          return false;
        } else {
          Serial.println("websocket layer connected");
        }

        Serial.println("MQTT connecting");
        MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
        data.MQTTVersion = 4;
        char* clientID = generateClientID ();
        data.clientID.cstring = clientID;
        rc = client.connect(data);
        delete[] clientID;
        if (rc != 0)
        {
          Serial.print("error connection to MQTT server");
          Serial.println(rc);
          return false;
        }
        Serial.println("MQTT connected");
        return true;
    }

    //subscribe to a mqtt topic
    void subscribe () {
       //subscript to a topic
      String espInTopicStr  = baseTopic + "/" + "myDeviceAbc" + "/espIn";
    //  String espOutTopicStr = baseTopic + "/" + config.machineName + "/espOut";
      const char* espInTopic  = espInTopicStr.c_str();
    //  espOutTopic = espOutTopicStr.c_str();

      const char* hardCodedTopic = "arn:aws:iot:us-east-2:xxxxxxxxxxxxxx:thing/myDeviceAbc/espIn";
      Serial.print("size of hardcoded topic: ");
      Serial.println(strlen(hardCodedTopic));
      Serial.print("size of actual topic: ");
      Serial.println(strlen(espInTopic));

       Serial.print("hardCodedTopic >>>");
       Serial.print(hardCodedTopic);
       Serial.print("<<<");
       Serial.println(".");

       Serial.println("---");

       Serial.print("espInTopic topic >>>");
       Serial.print(espInTopicStr.c_str());
       Serial.print("<<<");
       Serial.println(".");
       int rc = 99;
       while (rc != 0){
          rc = client.subscribe(hardCodedTopic, MQTT::QOS0, messageArrived);
          if (rc != 0) {
            Serial.print("rc from MQTT subscribe is ");
            Serial.println(rc);
            return;
          } else {
            Serial.println("");
            Serial.println("MQTT subscribed");
          }
          Serial.println("rc: " + String(rc));
          delay(500);
       }

    }

    //send a message to a mqtt topic
    void sendmessage (const char* topic, String msg) {
        //send a message
        MQTT::Message message;
        char buf[100];
        strcpy(buf, msg.c_str());
        message.qos = MQTT::QOS0;
        message.retained = false;
        message.dup = false;
        message.payload = (void*)buf;
        message.payloadlen = strlen(buf)+1;
        int rc = client.publish(topic, message);
    }

    void setup() {

        wifi_set_sleep_type(NONE_SLEEP_T);
        EEPROM.begin(1024);
    //    for (int i = 0; i < 1024; ++i) { EEPROM.write(i, 0); }
        Serial.begin(115200);
        ardMegaSerial.begin(9600);

        delay (2000);

        //////////////////////////////////////////
      if (!ReadConfig())
      {
        // DEFAULT CONFIG
        config.configMode = true;
        config.ssid = "N.A";
        config.password = "N.A";
        config.machineName = "N.A";
        config.dhcp = true;
        config.IP[0] = 192;config.IP[1] = 168;config.IP[2] = 1;config.IP[3] = 100;
        config.Netmask[0] = 255;config.Netmask[1] = 255;config.Netmask[2] = 255;config.Netmask[3] = 0;
        config.Gateway[0] = 192;config.Gateway[1] = 168;config.Gateway[2] = 1;config.Gateway[3] = 1;
        WriteConfig(true);
        Serial.println("default configs applied");
        //////////starting web config server hotspot
            Serial.println("No configuration stored, starting access point.");
            ESP.eraseConfig();
            WiFi.disconnect();
            WiFi.setAutoConnect(false);
            WiFi.setAutoReconnect(false);
            WiFi.mode(WIFI_AP_STA);
            nodeName = String(ACCESS_POINT_NAME) + String("-") + String(WiFi.softAPmacAddress().c_str());
            WiFi.softAP(nodeName.c_str() , ACCESS_POINT_PASSWORD);
            Serial.print("Connect to ssid " + nodeName + " to configure Node on IP: ");
            Serial.println(WiFi.softAPIP());
            ConfigureWifi();
            server.on ( "/favicon.ico",   []() { Serial.println("favicon.ico"); server.send ( 200, "text/html", "" );   }  );
            server.on ( "/", send_gateway_node_config_html  );
            server.on ( "/admin/values", send_gateway_node_config_values_html );
            server.on ( "/admin/connectionstate", send_connection_state_values_html );
            server.on ( "/style.css", []() { Serial.println("style.css"); server.send ( 200, "text/plain", PAGE_Style_css );  } );
            server.on ( "/microajax.js", []() { Serial.println("microajax.js"); server.send ( 200, "text/plain", PAGE_microajax_js );  } );
            server.onNotFound ( []() { Serial.println("Page Not Found"); server.send ( 400, "text/html", "Page not Found" );   }  );
            server.begin();
            Serial.println( "HTTP server started" );
      } else {
          nodeName = String(ACCESS_POINT_NAME) + String("-") + String(WiFi.softAPmacAddress().c_str());
          Serial.println("Device already configured");
          Serial.println("Wifi SSID: " + config.ssid);
          Serial.println("Wifi password: " + config.password);
          Serial.println("Node name: " + config.machineName);

          setupWifiAndAws();
      }

        //////////////////////////////////////////

    }

    void setupWifiAndAws() {
        char ssidBfr[500];
        strcpy(ssidBfr, config.ssid.c_str());
        char passBfr[100];
        strcpy(passBfr, config.password.c_str());
        //fill with ssid and wifi password
        WiFiMulti.addAP(ssidBfr, passBfr);
        Serial.println ("connecting to wifi");
        while(WiFiMulti.run() != WL_CONNECTED) {
            delay(100);
            Serial.print (".");
        }
        Serial.println("\nconnected");
        ardMegaSerial.println("ESP Started\n");
        //fill AWS parameters
        awsWSclient.setAWSRegion(aws_region);
        awsWSclient.setAWSDomain(aws_endpoint);
        awsWSclient.setAWSKeyID(aws_key);
        awsWSclient.setAWSSecretKey(aws_secret);
        awsWSclient.setUseSSL(true);

        if (connect ()) {
            String espOutTopicStr = baseTopic + "/" + config.machineName + "/espOut";
            espOutTopic = espOutTopicStr.c_str();
            subscribe();
            sendmessage (espOutTopic, "{\"device\":\"connected\"}}");
        }
    }

    void loop() {

      receiveFromArduino();
      //responseTimeOutCheck();
      //keep the mqtt up and running
      if (awsWSclient.connected ()) {
       client.yield(50);
      } else {
     //handle reconnection
     if (connect ()){
       subscribe ();
     }
      }

    }

body:
The `c_str()` function of the `String` class returns a pointer to current internal char array. This pointer is valid only until the String exists and is not changed.

Variable `espInTopicStr` is defined in a function and is destroyed at the end of the function. It frees the memory allocated for the internal char array.

You send a pointer to the internal char array of the `espInTopicStr` to `client.subscribe`. The MQTT library doesn't copy that char array, it only stores the pointer. Later the library uses the pointer to call the topic, but the memory on that location already changed and doesnt't contain the name of the topic.


sender: user

message:
Reaction timer using millis

I've written this code for a reaction timer game. The reaction time is to be displayed in milliseconds to the serial monitor as accurately as possible. The reaction time is not being displayed correctly. I'm including my timer setup routine and where I increment milliseconds.

    TCCR1A=0;
    TCCR1B=0;
    timer1_counter=65536;
    TCNT1=timer1_counter;
    TCCR1B |=(1<<CS12);

    TIMSK1 |=(1<<TOIE1);
    interrupts();
    }

    ISR(TIMER1_OVF_vect)
    {
      TCNT1=timer1_counter;
      int_flag=1;
     }

      digitalWrite(LED,LOW);
      randomSeed(analogRead(A1));
      NumSecs=random(1000,7000);
      delay(NumSecs);
      digitalWrite(LED,HIGH);
      while(digitalRead(PUSHBUTTON) == HIGH)
      {
      }
      if (int_flag==1){
      millisecs++;
      int_flag=0;
      }

sender: assistant

body:
Your ISR is not counting the elapsed milliseconds. Instead, it just sets
a flag and lets the main program do the counting when it sees the flag.
Here:

<!-- language-all: lang-c++ -->

    while(digitalRead(PUSHBUTTON) == HIGH)
    {
    }

you are waiting for the user to press the button. The program does
nothing else during the wait. It doesn't event count the time. Here:

    if (int_flag==1){
        millisecs++;
        int_flag=0;
    }

you increment _once_ the millisecond count _after_ the wait.

The obvious solution is to count the milliseconds while waiting for the
button press:

    millisecs = 0;  // don't forget to reset the stopwatch!
    while (digitalRead(PUSHBUTTON) == HIGH) {  // button not pressed
        if (int_flag) {
            millisecs++;
            int_flag = false;
        }
    }

(side note: `int_flag` should be a `bool`).

There are still many issues with this program. First of all, it should
check that the user did not press the button before the LED came up.

Then, the interrupt period is not one millisecond, because the interrupt
takes some time to be processed by the CPU and to go through its
prologue. By the time you do `TCNT1=timer1_counter;` you are at least
several tens of cycles late. You should instead configure the timer to
keep the correct period by itself, typically using CTC mode.

Also, there is no point in letting the main program count the
milliseconds when the ISR could do it. E.g.

    ISR(TIMER1_OVF_vect)
    {
        millisecs++;
    }

    // Avoid a race condition when reading millisecs.
    static inline unsigned int getMillisecs()
    {
        noInterrupts();
        int millisecsCopy = millisecs;
        interrupts();
        return millisecsCopy;
    }

Note that the time keeping variables should be unsigned in order to
avoid undefined behaviour on overflows.

Finally, it may be a good learning experience for working with
interrupts, but in the end just using `millis()` or `micros()` would be
the easiest way to achieve what you want.


body:
You're over-thinking this:

      digitalWrite(LED,LOW);
      randomSeed(analogRead(A1));
      NumSecs=random(1000,7000);
      delay(NumSecs);
      digitalWrite(LED,HIGH);
      unsigned int startTime = millis();
      while(digitalRead(PUSHBUTTON) == HIGH)
      {
      }
      unsigned int elapsed = millis() - startTime;

After that code, `elapsed` will contain the number of milliseconds it took the user to press the button. Note, however, that the user could cheat and simply press the button the whole time while waiting for the LED to change states. You could add logic to make sure the button isn't pressed just before you change the LED state, but I'll leave that up to you.


message:
Play computer *.wav files through Arduino

I am doing mice behavioral training.
I have an arduino-controlled box for that.
The sounds are play using Mp3 player controlled b the arduino.
However, the mp3 player is not good enough for my needs.

I need two clear sounds of 10 msec duration and freqiencies of 5000Hrz and 1000Hrz.
(I prefer pure sine waves but can compromise on triangle or, for now, even square).
The problem is that the mp3 is not fast enough and the volume is too low for 10 msec durations. When I tried to build gain circuit it became too noisy.

I tried to use the Tone function but it is again not good for 10 msec sounds. espacially in the jigj frequency/

I created the wavefiles in Matlab.
The PC plays the file in the right volume with no nose.
However, I don't know how to make the arduino play the files from the computer.

Is there a relative simple way to do it, without bying extra hardware?
If now, is there ANY way of doing it?

or another option, Is there a way for the arduino to play files from a wave generator? (I have these in my lab)

Thanks!

body:
Two options:

1. Write software for the PC to react to serial commands sent by the Arduino, or
2. Use a more powerful Arduino-like board with a DAC and do wavetable synthesis.

The Arduino Due and many of the other smaller ARM-based boards (like M0 boards) are a good candidate for option 2 because they are faster than a traditional Arduino and have a built-in DAC.  However, a proper I2S CODEC chip attached to a powerful MCU would be the preferred method for high-quality playback.

Note that your amplification system is of critical importance. It's common for many cheap amplifiers to limit higher frequencies. You need an amplifier with a good flat response over and above the maximum frequency you want to reproduce. Just slapping together any old "gain" circuit is probably not going to be good enough. Most op-amp based solutions have a ratio (*[Gain Bandwidth Product](https://en.wikipedia.org/wiki/Gain–bandwidth_product)*) that reduces the bandwidth as the gain increases.


body:
This code will create a steady 20 KHz output. Adjust the duration to reflect the period of your frequencies.

    byte triggerOut = 19;

    unsigned long currentMicros;
    unsigned long nextMicros;
    unsigned long duration = 25UL; // flip every 50uS = 20KHz pulse
    unsigned long elapsedMicros;

    void setup() {
      pinMode (triggerOut, OUTPUT);
    }
    void loop() {
      while (1) {
        currentMicros = micros();
        elapsedMicros = currentMicros - nextMicros;
        if (elapsedMicros >= duration) {
          nextMicros = nextMicros + duration;
          PINC = PINC | 0b00111111; // toggle D19 output by writing it input port.
        }
      }
    }

Add some lines to start the output after a button push, and count the number of cycles to only output the time duration you want.
10,000 KHz = 0.1mS period, 10ms/0.1ms = 100 cycles.

Divide the 0 to 5V output down to 1V, and drive a computer self powered speaker to create the noise you want.


message:
"SSD1306 allocation failed" when #include SD.h

I'm using the ssd1306_128x64_i2c example file from the 1306's library.

It works perfectly until I add the ***#include SD.h*** line, after which it gives the allocation failed error.

Please advise.

    #include <SPI.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    #include <SD.h>

    Adafruit_SSD1306 display(128, 64, &Wire, 4);

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

      // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
      if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
        Serial.println(F("SSD1306 allocation failed"));
      }

      display.clearDisplay();
      display.display();
      testdrawchar();
    }

    void loop() {
    }

    void testdrawchar(void) {
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0, 0);
      display.cp437(true);

      for(int16_t i=0; i<256; i++) {
        if(i == '\n') display.write(' ');
        else          display.write(i);
      }
      display.display();
    }

body:
Both the SD library and the SSD1306 libraries want big buffers. That means lots of memory.  You don't have lots of memory.

* The SD wants at least 512 bytes for a sector buffer (which is allocated at compile time).
* The SSD1306 wants at least 1kiB for a display buffer (which is allocated at runtime).
* Serial wants at least 128 bytes for TX and RX buffers (which is allocated at compile time).
* The Wire library needs 32 bytes for a TX buffer.

That's 1696 bytes of a total 2048, and that's not taking into account any of the other variables and things that your program, the various libraries, and the Arduino core itself needs, plus the stack (and its specified minimum size safety zone).

There's nothing much you can do about it, short of upgrading your Arduino to one with more memory, or splitting your design across multiple Arduinos.


body:
I was able to make it all fit by using the text-only library for the OLED.

[SSD1306Ascii Library][1]

Much thanks to Majenko for explaining the problem and greiman for writing the library!

  [1]: https://github.com/greiman/SSD1306Ascii/blob/master/examples/HelloWorldAvrI2c/HelloWorldAvrI2c.ino


message:
bh1750 lightsesor won't work

ok, im having problems with my bh1750, here is all info i got:

board: esp32s nodeMCU v. 1.1

Pins:
[![Pins:][1]][1]

Wiring: (the 2 reds go to pin 21 and 22)
[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/YiF1z.png
  [2]: https://i.stack.imgur.com/XDHCo.jpg

code:

    #include <BH1750.h>
    #include <Wire.h>

    BH1750 lightMeter;

    void setup(){

    Wire.begin();
    Serial.begin(115200);
    lightMeter.begin();
    if (lightMeter.begin()) {
    Serial.println(F("BH1750 initialised"));
    }
    else {
    Serial.println(F("Error initialising BH1750"));
    }
    }

    void loop() {
    uint16_t lux = lightMeter.readLightLevel();
    Serial.println(lux);
    delay(500);
    }

Sorry for bad formating

Serial output:

13:01:41.926 -> [BH1750] ERROR: received NACK on transmit of address

13:01:41.926 -> [BH1750] ERROR: received NACK on transmit of address

13:01:41.926 -> Error initialising BH1750

13:01:41.926 -> [BH1750] Device is not configured!

13:01:41.926 -> 65534

13:01:42.430 -> [BH1750] Device is not configured!

13:01:42.430 -> 65534

13:01:42.932 -> [BH1750] Device is not configured!

13:01:42.932 -> 65534

and that goes on forever

Hope someone got an answer :D

body:
Your code looks good. I2C configuration is default which depends on your board manager.
Then your wiring may be wrong.

1. Using a multimeter to check supply voltage on the BH1750 module. It should be 3.3V
2. Using a multimeter to check the connection between the BH1750 module with ESP32.
3. Difference ESP32 vendor may provide a difference I2C pinout. Make sure you connect everything correctly.
4. Using an oscilloscope or logic analyzer to capture data on an I2C bus.
5. If everything good, try to use another module.

From your log, I guessed, the power supply is good. I2C connection is your problem.
More, you should use the different color wire for the difference signal. It helps prevent unexpected connections.


body:
The SCL and SDA silkscreen was reversed on my chips.
Took an hour of faffing to figure that out.

Never "Just presume" it is correct


message:
Arduino SPI Multiplexer problems

I want to use the ADG731 32 ch multiplexer to read 32 potentiometers, I have wired everything and it works but it doesn't works as fast as I would want.

The problem is that If I turn a potentiometer between the range of 10-90% of the rotation, the analog reading is so slow, for example, if I have my POT at 0, and i turn it to 50%, it goes so slow until it reach the 512 value(like an hysteresis effect), BUT, if I turn the potentiometer back to 0 or up to 1023 it makes the reading as quick as I would expect.

So in resume it reads slowly the values except the edges values.

This is my code(I have set it to read only one potentiometer at pin S16 to test how the ADG731 works:

    #include <SPI.h>

    void loadDrain(void);
    const int slaveSelectPin = 53;
    void setup() {
      pinMode(slaveSelectPin, OUTPUT);
      SPI.begin();
      Serial.begin(9600);
    }

    void loop() {
      loadDrain();
    }

    void loadDrain(){
      SPI.beginTransaction(SPISettings(30000000, MSBFIRST, SPI_MODE2));
      digitalWrite(slaveSelectPin, LOW);
      SPI.transfer(00001111);
      digitalWrite(slaveSelectPin, HIGH);
      SPI.endTransaction();
      Serial.println(analogRead(A0) >> 3);
    }

body: Take a deep look into the library you are using to read the POT. Most HW and / or SW will take many readings & average them to remove the randomness and improve the accuracy of the ADC HW. It could be that your setup is so noisy that the SW is compensating by taking even more readings to average. Hats off the the SW developer who had the foresight to adapt the code to noisier situations. If true, and you think that too much automation, remember you are using the Arduino platform where the libraries are designed to make things simple by abstracting (hiding) the hardware details.


body:
Some things look odd:

Why do this every time? You only need to set these up one time in setup():

    SPI.beginTransaction(SPISettings(30000000, MSBFIRST, SPI_MODE2));

Most 16 MHz Arduinos, including the Mega you appear to be using, won't do 3 MHz, choices are 8 MHz, 4,MHz, 2 MHz, 1 MHz  and 3 or 4 more slower speeds.

The chip seems to support higher speeds, 8 MHz should work:

>fSCLK 30 MHz max SCLK Cycle Frequency

So run it faster to same on time.

Why take a 10-bit reading and shift it down to 7?

    Serial.println(analogRead(A0) >> 3);

You could speed up the reads by doing an 8-bit read instead of 10-bit, and use a faster Serial speed, up to 115200, to send the results out.

Instead of digitalWrite() to control the slaveSelect pin, you could use direct port manipulation to toggle that pin.  You can write a 1 to the Input port to toggle the output bit. From the Atmega2560 datasheet:

>Toggling the Pin
>
>Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn. Note that the SBI
instruction can be used to toggle one single bit in a port.


body:
You can modify beginT and endT
// test SPI slave n=1
 SPI.beginTransaction(1, SPISettings(30000000, MSBFIRST, SPI_MODE2));
 SPI.transfer(00001111);
 SPI.endTransaction(1);


message:
Prioritizing one sensor

I want to ask is there a possible code to prioritize a specific part of a code? So I'm doing this project where I want to utilize muscle sensor, servo, and a button on an app over Bluetooth. The problem is since all is running in void() loop, even though I am not using the muscle sensor I can't move the servo with the app, since it reads the muscle sensor first. So is there a possible code to make the muscle sensor stop for a period of time after the button is pressed on the app and the servo is moved?

Here is the code:

    void loop()
     {
      if(Serial.available()>0)
       {
        char data = Serial.read();

          if (data == 'a')
           {
            myservo.write(15);
           }
      }

    int value = analogRead(EMG_PIN);

     if(value > THRESHOLD)
      {
       myservo.write(15);
      }

      else{
           myservo.write(140);
          }

So the first code is a bluetooth code where the servo is controlled through a button on an app. The second one is a muscle sensor. As stated above the problem is it will always read the muscle sensor even though the button is pressed from the app.

    #include <Servo.h>

     int increment = 0;

     Servo myservo;

     void setup() {

       myservo.attach(1);

     }

     void loop()
     {

       Serial.println(increment++);

       if (increment > 9);
        {

         if(Serial.available()>0)
          {
           char data = Serial.read();

           if (data == 'a')
           {
            myservo.write(15);
           }
     }

          else if (increment = 0);

          int value = analogRead(EMG_PIN);

          if(value > THRESHOLD)
           {
            myservo.write(15);
           }

         else{
           myservo.write(140);
          }
      }

body:
You have to think of your program as having two distinc modes of
operation:

* The "fixed servo" mode is entered when you press the button on the
  app. In this mode the servo is kept at a fixed position. The mode
  lasts for a predefined delay.

* The normal (not fixed servo) mode is the default mode. In this mode
  the servo is positioned according to the reading of the sensor.

So you need a boolean variable to remember whether the "fixed servo"
mode is active or not, and the code in `loop()` should take care of
providing the correct behavior depending on the mode, and updating that
variable when needed. For example:

<!-- language: lang-c++ -->

    void loop()
    {
        static bool fixed = false;  // whether we are in "fixed servo" mode
        static uint32_t fixed_started;  // when the mode started
        uint32_t now = millis();

        // On button press, start "fixed servo" mode.
        if (Serial.available() && Serial.read() == 'a') {
            servo.write(SERVO_LEFT);
            fixed = true;
            fixed_started = now;
        }

        // Get out of "fixed" mode after some delay.
        if (fixed && now - fixed_started >= FIXED_DELAY) {
            fixed = false;
        }

        // If not in "fixed" mode, react to the sensor.
        if (!fixed) {
            if (analogRead(EMG_PIN) >= THRESHOLD) {
                servo.write(SERVO_LEFT);
            } else {
                servo.write(SERVO_RIGHT);
            }
        }
    }


message:
Passing arrays, global arrays within functions, pointers, and declaring array sizes

I'm super confused right about now!

I've been working on project involving Xbees in API mode, and I need to send different arrays of bytes to the Xbee depending on which buttons I press. Mostly what I have is working fine, but I'm having a lot of issues with the following questions; I figured I'd summarize all my questions first, then further explain them with code examples.

 1. Arduino requires arrays contain to a size. How can I declare `byte data[]` without a size?
 2. Arrays sizes must be declared with a number, or a const integer. So how come I can declare `byte packet[arraySize];` when `arraySize` is being passed the integer `ledOn_len` that isn't constant?
 3. How can I create a global array within a function?

I've taken the liberty to condense my code for readability purposes. Everything you see is here is mirroring my issues with my Xbee code.

    byte ledOn[] = { 0x7E, 0xAA, 0x1C, 0x3B }; // turn led on
    byte ledOff[] = { 0x7E, 0xAB, 0x1D }; // turn led off

    int ledOn_len; // to be used for the array size of ledOn[] NOT a constant
    int ledOff_len; // to be used for the array size of ledOff[] NOT a constant

    // this doesn't work, because the array length must be a constant
    //int arrayLength = 4;
    //byte rando[arrayLength];

    // this works just fine, since arrayLength is now a constant
    //const int arrayLength = 4;
    //byte rando[arrayLength];

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

      // since using sizeof(data) inside of changeLed() doesn't
      // work (it returns with 2, which is the size of a pointer)
      // set them here, and pass them along.
      ledOn_len = sizeof(ledOn);
      ledOff_len = sizeof(ledOff);
    }

    void loop()
    {
      changeLed(ledOn, ledOn_len);
      delay(1000);
      changeLed(ledOff, ledOff_len);
      delay(1000);
    }

    void sendToXbee()
    {
      //Xbee.write(packet); // packet isn't global, this doesn't work
      // yes I know I didn't include any software serial in this demonstration
    }

    void changeLed(byte data[], int arraySize)
    {
      byte packet[arraySize]; // how does this work???? Pass by value
      memcpy(packet, data, arraySize); // clone data to packet

      // this is all the Serial print code

    }
**1)** I created the function `void changeLed()` to calculate the checksum (xbee crap). I need to pass it the array `ledOn[]` or `ledOff[]` for the checksum calculations to occur. So I simply added `void changeLed(byte data[])`  (and then void loop calls `changeLed(ledOn)` ) which works, but why?! Anywhere else if you declare an array without an array size it says you must provide one. Confusing to me, but it still works. . . kinda. When I serial print `data[i]` byte by byte, it perfectly displays each byte in `ledOn[]`, which is what I'm passing it. But when I call `sizeof(data)` it says it's only 2 bytes. How can it contain the exact data of 4 bytes I give it while only being 2 bytes? Here is the serial monitor of it. The first line is the printout of `data[]`, following the 4 bytes is the length which it claims is 2. The second line is the array of bytes `packet[]`. I set `packet[]` equal to `data[]` with this: `memcpy(packet, data, arraySize);`. Now you'll notice that the array size is correct. Interesting.

**Update #1:** It seems like this all has to do with pointers somehow. I guess `data[]` is just pointing to or referencing the array `ledOn[]`, and using `memcpy(packet, data, arraySize);` is actually copying the array `ledOn[]` to the array `packet[]`?

[![enter image description here][1]][1]

----------

**2)** I try to declare a random array (`byte rando[]`) using `int arrayLength` as the size. This does not work because the array size must be a constant. So I simply add `const int arrayLength` and that works. Great. So how am I able to do `byte packet[arraySize];`!? `ArraySize` is being passed `ledOn_len` which is not a constant, so how come that works?

----------

**3)** I need to be able to use the array `packet[]` inside of another function `void sendToXbee()`. `Packet[]` will be my final array of bytes to send to the Xbee containing either the array `ledOn[]` or `ledOff[]` which are different array lengths. As is, I cannot use `packet[]` in `void sendToXbee()` because `packet[]` is local to `void changeLed()`. But here's the catch 22: I cannot declare `packet[]` in the setup making it  global, because I don't have a size for that array yet!! The size of that array must be calculated within `void changeLed()`, depending on which array I need to send to the Xbee, `ledOn[]` or `ledOff[]`.

I know this is a lot but I'd appreciate the help! Thanks guys.

  [1]: https://i.stack.imgur.com/oBMJS.png

body:
> Arduino requires arrays contain to a size. How can I declare byte data[] without a size?

You can't. Pure and simple. The compiler can infer a size from a declaration time assignment.

> Arrays sizes must be declared with a number, or a const integer. So how come I can declare byte packet[arraySize]; when arraySize is being passed the integer ledOn_len that isn't constant?

It is a feature of C99 which GCC have also included in C++.

> How can I create a global array within a function?

Simple: you can't.*

Ok. Now we've to that out of the way, let's look at what you *want* to do and how you should do it.

First off, you have a number of arrays of data:

    uint8_t ledOn[] = { 0x7E, 0xAA, 0x1C, 0x3B }; // turn led on
    uint8_t ledOff[] = { 0x7E, 0xAB, 0x1D }; // turn led off

Those arrays have an associated length, which is the size of the array divided by the size of one array entry:

    const int ledOn_len = sizeof(ledOn) / sizeof(ledOn[0]);
    const int ledOff_len = sizeof(ledOff) / sizeof(ledOff[0]);

At the moment you're getting away with just using `sizeof(ledOn)` because `sizeof(ledOn[0])` is 1. But if you ever do this with arrays of anything other than `byte` you will come unstuck unless you get into this habit.

Now, those arrays are just blocks of memory with a fixed size, in a fixed location.  That means that the arrays, as well as being arrays, are also *pointers*.  That is, they are in effect just variables that contain the address where the data for the array is stored.

So you pass the pointer to the array, along with the length of the array, to your function:

    void changeLed(const uint8_t *data, int len) {
    }

    changeLed(ledOn, ledOn_len);

When you have done is pass the address of the array to the function, not the array.

Now you can do things with that array data using that address. What you can't do is change the data (because I've marked it `const`).

One of the things you can do, though, is just send it.  You know where the data is. You know how long it is. You know where you want to send it to.

So you just do:

    void changeLed(const uint8_t *data, int len) {
        Xbee.write(data, len);
    }

That is, write `len` bytes starting at the address pointed to by `data`.

There is no need to have variable size arrays. There is no need to have global packet buffers. There is no need to copy any data anywhere with `memcpy()`. Just pass the data and send it.

If you need to send more data than just the content of your array, then just send it.  For example you may have to (I don't know the XBee protocol) add a header and footer to the packet.

    void changeLed(const uint8_t *data, int len) {
        Xbee.write(0x01);
        Xbee.write(0x02);
        Xbee.write(len & 0xFF);
        Xbee.write(data, len);
        uint8_t cs = 0;
        for (int i = 0; i < len; i++) {
            cs += data[i];
        }
        Xbee.write(cs);
    }

Just because they're not together in the same `write` function doesn't mean that they aren't "together".  With serial communication, there is no such thing as "together". It's just one byte after another.

> I need to be able to use the array packet[] inside of another function void sendToXbee(). Packet[] will be my final array of bytes to send to the Xbee containing either the array ledOn[] or ledOff[] which are different array lengths. As is, I cannot use packet[] in void sendToXbee() because packet[] is local to void changeLed(). But here's the catch 22: I cannot declare packet[] in the setup making it global, because I don't have a size for that array yet!! The size of that array must be calculated within void changeLed(), depending on which array I need to send to the Xbee, ledOn[] or ledOff[].

Why do you think you need to copy the data into a separate packet variable? You already have the data in a variable.

If you really want to do that, then just pass `packet` to the next function in the same way as you already pass your other arrays.

----
<sup>* Actually there are ways, using dynamic memory allocation, but I won't condone using that</sup>


message:
Pipe serial dump to SD card file

I am using the RFID module to read mifare NFC chips and the library has only methods to send the data to the serial monitor. I need them to be saved to an SD card file. I have been adding custom methods to the library files to return strings that I then write to the SD card but this is a pain; there must be a quicker way to simply pipe all the data automatically but I do not know how to do this in cpp.

Here is an example of the function to dump to serial, that needs to be piped to the file on the SD card.

    void MFRC522::PICC_DumpDetailsToSerial(Uid *uid) {
     Serial.print(F("Card UID:"));
     for (byte i = 0; i < uid->size; i++) {
      if(uid->uidByte[i] < 0x10)
       Serial.print(F(" 0"));
      else
       Serial.print(F(" "));
      Serial.print(uid->uidByte[i], HEX);
     }
     Serial.println();

     // SAK
     Serial.print(F("Card SAK: "));
     if(uid->sak < 0x10)
      Serial.print(F("0"));
     Serial.println(uid->sak, HEX);

     // (suggested) PICC type
     PICC_Type piccType = PICC_GetType(uid->sak);
     Serial.print(F("PICC type: "));
     Serial.println(PICC_GetTypeName(piccType));
    }

Thanks!

body:
Have the MFRC522 objects remember where you want them to send the output
by adding a data member to the class like this:

<!-- language-all: lang-c++ -->

    private:
        Print &output;

This is a reference to a `Print` object, i.e. any object where you can
`print()` or `println()` to. This reference should be initialized in the
constructor, like this

    MFRC522:MFRC522(...other arguments..., Print &my_output = Serial)
    : ...other initializations..., output(my_output)
    {
        ...constructor body...
    }

Notice that, by default, the `output` is initialiazed as a reference to
`Serial`. Thus, unless you explicitly ask for the output to go
elsewhere, the class will behave as before.

Last step is to change, in the implementation of the class, _every_
reference to `Serial` by `output`. This is just a global find and
replace.

At this point, the `MFRC522` class can be used exactly as before, and it
will behave identically. This means that _every_ user of the library
should be able to use your modified version with no issues. I thus
encourage you to submit the changes to the original author, so that they
have a chance to be incorporated into the canonical version of the
library.

Now, if you want this debugging output to be sent elsewhere, just
provide the destination as the last argument of the constructor:

    MFRC522 my_RFID_module(...other arguments..., my_SD_card_file);

As long as the destination is an instance of the `Print` virtual class
(basically anything you can `print()` to should be OK), it should work
as expected.


message:
millis() replace delay() question

// each "event" (LED) gets their own tracking variable
    unsigned long previousMillisLED12=0;
    unsigned long previousMillisLED13=0;

    unsigned long previousMillisLED3=0;

    // different intervals for each LED
    int intervalLED12 = 500;
    int intervalLED13 = 5000;

    int intervalLED3 = 2000;

    // each LED gets a state varaible
    boolean LED13state = false;     // the LED will turn ON in the first iteration of loop()
    boolean LED12state = false;     // need to seed the light to be OFF

    void setup() {
       pinMode(13, OUTPUT);
       pinMode(12, OUTPUT);

       pinMode(3, OUTPUT);

    }
    void loop() {
       // get current time stamp
       // only need one for both if-statements
       unsigned long currentMillis = millis();

       // time to toggle LED on Pin 12?
       if ((unsigned long)(currentMillis - previousMillisLED12) >= intervalLED12) {
          LED12state = !LED12state;
          digitalWrite(12, LED12state);
          // save current time to pin 12's previousMillis
          previousMillisLED12 = currentMillis;
       }

    // time to toggle LED on Pin 13?
      if ((unsigned long)(currentMillis - previousMillisLED13) >= intervalLED13) {
          LED13state = !LED13state;
          digitalWrite(13, LED13state);
          // save current time to pin 13's previousMillis
          previousMillisLED13 = currentMillis;
      }
    }

My questions:

1. Didn't see the led12 and led13 have 10 times defferency, almost same intervals, why?

2. How can I use `millis()` as simple as delay?

3. Is that a must to use if?

body:
Your Timing is working, you can test it with the Serial monitor. So your problem is at some other place. Using delay() is from my perspective not a good solution, you did it better the way you already made.

For testing your sketch I included the communication for the Serial Montior (I had to comment out the LED activation since this is working in a different way on my board, and I also made the intervalls Shorter to see better the effect within the test sketch). Here you find the necessary changes and the output of the Serial Monitor.

My recommendation is to look with a simple Sketch if you are able to switch on/off your LEDs sperately without Timing to come closer to your problem. I dont think it is the Timing/use of millis().

    #include <M5Stack.h> // needed for my board

    // each "event" (LED) gets their own tracking variable
    unsigned long previousMillisLED12 = 0;
    unsigned long previousMillisLED13 = 0;

    unsigned long previousMillisLED3 = 0;

    // different intervals for each LED
    int intervalLED12 = 50;
    int intervalLED13 = 500;

    int intervalLED3 = 2000;

    // each LED gets a state varaible
    boolean LED13state = false;     // the LED will turn ON in the first iteration of loop()
    boolean LED12state = false;     // need to seed the light to be OFF

    void setup() {
      Serial.begin(9600);
      //  pinMode(13, OUTPUT);
      //  pinMode(12, OUTPUT);
      //  pinMode(3, OUTPUT);
    }
    void loop() {
      // get current time stamp
      // only need one for both if-statements
      unsigned long currentMillis = millis();

      // time to toggle LED on Pin 12?
      if ((unsigned long)(currentMillis - previousMillisLED12) >= intervalLED12) {
        LED12state = !LED12state;
        // digitalWrite(12, LED12state);
        // save current time to pin 12's previousMillis
        previousMillisLED12 = currentMillis;
      }

      // time to toggle LED on Pin 13?
      if ((unsigned long)(currentMillis - previousMillisLED13) >= intervalLED13) {
        LED13state = !LED13state;
        // digitalWrite(13, LED13state);
        // save current time to pin 13's previousMillis
        previousMillisLED13 = currentMillis;
      }
      Serial.print("LED12: ");
      Serial.print(LED12state);
      Serial.print("  LED13: ");
      Serial.println(LED13state);

    }

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/idA1P.png


message:
Create New Serial Class Inheriting from Stream

How should I inherit from `Stream`, for creating a new class `MySerial` able to be initialized from a `Stream0` instance?.

The error so far is: `"cannot declare variable 'mySerial' to be of abstract type 'MySerial'"`.

If I make a class `MySerial` not inheriting, but adding a property `Stream`, everything works fine, except the new call mechanism for the `resend()` function, created to accept `Stream` instances.

EDIT: This is the edited code. Current error is: `"expected unqualified-id before '=' token"`.

*MySerial.h*
<!-- language-all: lang-cpp -->

    class MySerial:public Stream{
        private:
            int param;
        public:
      MySerial(){}; // OK
            MySerial(Stream &Serial0){MySerial=&Serial0} // Here is the question
            // Stream Implementation
            int available(){return available();}
            int read(){return read();}
            int peek(){return peek();}
            size_t write(uint8_t c){return write(c);}
            using Print::write;
    };

*MySerial.ino*

    #include <MySerial.h>
    #include <SoftwareSerial.h>

    SoftwareSerial swSerial(6,7);
    MySerial mySerial(swSerial);

    void setup(){}
    void loop(){
        if (mySerial.available()){
            c=mySerial.read();
            resend(mySerial,c);
        }
    }
    // This function should accept any Stream: SoftwareSerial, MySerial, Serial...
    void resend(Stream &Stream0, char c){
        Stream0.write(c);
    }

body:
The `Stream` class has pure virtual methods which must be implemented in derived not abstract class.

The pure virtual method from base class `Print` is:

    virtual size_t write(uint8_t) = 0;

The pure virtual methods from `Stream` are:

    virtual int available() = 0;
    virtual int read() = 0;
    virtual int peek() = 0;

additionally add in your class the line

    using Print::write;

to pull in overloaded methods write(str) and write(buf, size) from`Print`

[Here][1] I have an example of a simple class derived from `Stream`.

----------

EDIT: Most of your question seemed to focus on wrapping some Stream implementation. Now I see that you maybe want to enhance the SoftwareSerial class and add a new method in the inherited class. It is simple:

MySerial.h

    #ifndef _MYSERIAL_H_
    #define _MYSERIAL_H_

    #include <SoftwareSerial.h>

    class MySerial: public SoftwareSerial {
    private:
      int param;

    public:

      MySerial(uint8_t receivePin, uint8_t transmitPin) :
          SoftwareSerial(receivePin, transmitPin, false) {
        param = 0;
      }

      void resend(char c) {
        write(c);
      }
    };
    #endif

MySerial.ino

    #include "MySerial.h"

    MySerial mySerial(6, 7);

    void setup() {
      mySerial.begin(9600);
    }

    void loop() {
      if (mySerial.available()) {
        int c = mySerial.read();
        mySerial.resend(c);
      }
    }

  [1]: https://github.com/jandrassy/TelnetStream/blob/master/src/TelnetStream.h


message:
I am getting blocks on my lcd screen 16*2

When I have tried interfacing my 16*2 LCD with Arduino I am getting only the black coloured boxes on my screen. What might be the problem?

Is there any solution to that? Do I need to connect any additional physical device to avoid that situation?

[product is here lcd display 16*2][1]

  [1]: http://uitechies.co.in/BBBcircuits/product.php?product=lcd-16x2-alphanumeric-display-jhd162a-8051-avr-arduino-pic-arm

body:
There are two possible problems, and you haven't stated which it is.

1. A single row of blocks (just the top row)

This is caused by either bad communication (wrong wiring) or incorrect code. Basically, the display isn't being initialized properly by your code for whatever reason.

2. Two rows of blocks (the entire display full of blocks)

The display is being initialized properly, so both your code and wiring are correct.  However, the contrast setting of the display is wrong. You need to check the wiring for your contrast potentiometer and adjust as necessary.


message:
i am getting an error while working with esp8266

i got an error
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00
An error occurred while uploading the sketch

can [esp8266][1]anyone rectify this

  [1]: http://uitechies.co.in/BBBcircuits/product.php?product=serial-wi-fi-wireless-transceiver-module-iot-esp8266

body:
oh i got the solution for the above question

it might be because i used TX AND RX pins of the arduino. what i observed is as tx and rx pins are for serial communication pin during the process of uploading i have to leave that pins disconnected.[arduino][1]

  [1]: http://uitechies.co.in/BBBcircuits/product.php?product=arduino-uno-r3-atmega328p


message:
Not able to split string into 2 char

I am trying to split an incoming string into 2 integer values since I have to control 2 dc motors with it. The processor is node MCU and I get following error:-

Com Port Reading:-

    WiFi connected
    Received: "84+62"
    "84+62"

    Soft WDT reset

    >>>stack>>>

    ctx: cont
    sp: 3ffffd90 end: 3fffffc0 offset: 01b0
    3fffff40:  2b343822 00223236 3ffee70c 40204148
    3fffff50:  3ffe85ee 3ffee6d8 3ffee70c 402043c5
    3fffff60:  3ffe85dc 3ffee70c 3ffee6d8 402043c5
    3fffff70:  3ffe85f0 3ffee69c 00000000 00000001
    3fffff80:  00000000 40200038 3ffefca4 0000000f
    3fffff90:  00000007 00000000 00000001 402048f9
    3fffffa0:  3fffdad0 00000000 3ffee744 40204984
    3fffffb0:  feefeffe feefeffe 3ffe851c 401009a5
    <<<stack<<<

     ets Jan  8 2013,rst cause:2, boot mode:(3,6)

    load 0x4010f000, len 1384, room 16
    tail 8
    chksum 0x2d
    csum 0x2d
    v951aeffa
    ~ld

Code:-

    if (msg.length() > 0) {
            Serial.print("Received: "); Serial.println(msg);
            char charBuf[50];
            msg.toCharArray(charBuf, 50);
            Serial.println(charBuf);

            char left[3] = {};
            char right[3] = {};
            int n = 0;

            while (charBuf != 0) {
              for (int i = 0; i < strlen(charBuf); i ++) {
                if (charBuf[i] != '+') {
                  left[n] += charBuf[i];
                  n++;
                }
                else {
                  n = 0;
                  break;
                }
                right[n] += charBuf[i];
                n++;
              }
            }
            Serial.println("Left Motor: "); Serial.print(left);
            Serial.println("Right Motor: "); Serial.print(right);

        }

My desired result is following:-

    Left Motor: 84
    Right Motor: 62

So what changes I need to make?

body:
You get this memory leak because you overflow the variable `right`. This does not happen in the for loop itself even though this could be implemented more straight forward. But it's the while loop that doesn't come to an end (`charBuf` doesn't change and will not become 0) and in the second iteration `n` will be 1 initially (due to `n++` at the end of the for loop). That causes the overflow at `right[n] += charBuf[i];`.

So: remove the `while` loop (and use `strtok()`).


body:
> "84+62"

The additional doublequote characters are part of your string and charBuf

        Serial.println(charBuf);  // Text with " and  +

        char* cpl = nullptr;
        char* cpr = nullptr;
        for (char* cp = charBuf; *cp != 0; cp++) {
            if (*cp != '"' && ! cpl )  cpl = cp;
            if (*cp == '"') *cp = 0;
            if (*cp == '+' ) {
              *cp = 0; // split
              cpr = cp+1;
            }
        }
        Serial.println("Left Motor: "); Serial.println(atoi(cpl));
        Serial.println("Right Motor: "); Serial.print(atoi(cpr));


body:
Here's an example sketch that uses `strtok()`.

    char charBuf[] = "\"84+62\"";

    // Set array size to maximum number of integers you will receive.
    uint16_t myArray[2];

    void setup(){

      Serial.begin(9600);

      int counter = 0;
      char* pch = strtok(charBuf, "\"+");

      while(pch != NULL){
        myArray[counter] = atoi(pch);
        pch = strtok(NULL, "\"+");
        counter += 1;
      }

      // Print out the contents of the integer array.
      for(int i = 0; i < counter; i++){
        Serial.println(myArray[i]);
      }
    }

    void loop(){}

`myArray[0]` contains 84 and `myArray[1]` contains 62.


message:
Help with code for pushbutton connected to adafruit motorshield v2

can anybody assist me with a code? I am using arduino uno with adafruit v2 motor shield stacked on top. I am using a pushbutton and one DC motor and I want the state of the push button to change after it has been pushed for a few seconds. That is I want the motor to stop running even though the push button is still pushed down.

Here is the code I'm using:

        /*
    This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
    It won't work with v1.x motor shields! Only for the v2's with built in PWM
    control

    For use with the Adafruit Motor Shield v2
    ----> http://www.adafruit.com/products/1438
    */

    #include <Wire.h>
    #include <Adafruit_MotorShield.h>
    #include "utility/Adafruit_MS_PWMServoDriver.h"

    // Create the motor shield object with the default I2C address
    Adafruit_MotorShield AFMS = Adafruit_MotorShield();
    // Or, create it with a different I2C address (say for stacking)
    // Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);

    // Select which 'port' M1, M2, M3 or M4. In this case, M1
    Adafruit_DCMotor *myMotor = AFMS.getMotor(1);

    // You can also make another motor on port M2
    //Adafruit_DCMotor *myOtherMotor = AFMS.getMotor(2);

    // digital pin 2 has a pushbutton attached to it. Give it a name:
    int pushButton = 4;

    void setup() {
      Serial.begin(9600);           // set up Serial library at 9600 bps
      Serial.println("Adafruit Motorshield v2 - DC Motor test!");

      // make the pushbutton's pin an input:
      pinMode(pushButton, INPUT);

      AFMS.begin();  // create with the default frequency 1.6KHz
      //AFMS.begin(1000);  // OR with a different frequency, say 1KHz

      // Set the speed to start, from 0 (off) to 255 (max speed)
      myMotor->setSpeed(150);
      myMotor->run(FORWARD);
      // turn on motor
      myMotor->run(RELEASE);

    }

    void loop() {
      uint8_t i;

        // read the input pin:
      int buttonState = digitalRead(pushButton);
      // print out the state of the button:
      Serial.println(buttonState);
      delay(0);        // delay in between reads for stability

      if (buttonState==1){
         delay(1000);

      myMotor->run(FORWARD);
        myMotor->setSpeed(150);
        delay(1000);

     }

     else if (buttonState==0){
      myMotor->run(FORWARD);
        myMotor->setSpeed(0);

      }

    }

body:
You need to do various things:

You need to change your logic not to use delay. Search on "Arduino Blink Without Delay" to find examples of doing timed actions with `millis()` instead of using delay.

Then you need to adjust your logic to start running the motor when the user presses a button, and stop running the motor when either the user releases the button or enough time elapses.


message:
expected unqualified-id before 'if' if (!client.connected() && lastConnected)

#include <PulseSensorPlayground.h>
    #include <Timer.h>
    #include <SPI.h>
    #include <Ethernet.h>

    Timer t;
    PulseSensorPlayground pulseSensor;

    // Local Network Settings
    byte mac[] = { 0xD4, 0x28, 0xB2, 0xFF, 0xA0, 0xA1 }; // Must be unique on local network
    // ThingSpeak Settings
    char thingSpeakAddress[] = "api.thingspeak.com";
    String writeAPIKey = "UVGOLIA40B9YHKU8";
    const int updateThingSpeakInterval = 16 * 1000; // Time interval in milliseconds to update ThingSpeak (number of seconds * 1000 = interval)
    // Variable Setup
    const int PulseWire = A0;       // PulseSensor PURPLE WIRE connected to ANALOG PIN 0
    const int LED13 = 13;          // The on-board Arduino LED, close to PIN 13.
    int Threshold = 550;           //for heart rate sensor
    float myTemp;
    int myBPM;
    String BPM;
    String temp;
    int error;
    int panic;
    int raw_myTemp;
    float Voltage;
    float tempC;

    long lastConnectionTime = 0;
    boolean lastConnected = false;
    int failedCounter = 0;
    // Initialize Arduino Ethernet Client
    EthernetClient client;
    void setup()
    {
      // Start Serial for debugging on the Serial Monitor
      Serial.begin(9600);
      pulseSensor.analogInput(PulseWire);
      pulseSensor.blinkOnPulse(LED13);       //auto-magically blink Arduino's LED with heartbeat.
      pulseSensor.setThreshold(Threshold);

      // Double-check the "pulseSensor" object was created and "began" seeing a signal.
      if (pulseSensor.begin()) {
        Serial.println("We created a pulseSensor Object !");  //This prints one time at Arduino power-up,  or on Arduino reset.
      }

      // Start Ethernet on Arduino
      void startEthernet();
    }
    void loop()
    {
      // Read value from Analog Input Pin 0
      String analogPin0 = String(analogRead(A0), DEC);
      // Print Update Response to Serial Monitor
      if (client.available())
      {
        char c = client.read();
        Serial.print(c);
      }
      //temp---
      raw_myTemp = analogRead(A1);
      Voltage = (raw_myTemp / 1023.0) * 5000; // 5000 to get millivots.
      tempC = Voltage * 0.1;
      Serial.println(tempC);

      //Serial.print(temp);
      //Serial.print(" ");

      //-----BMP180-----------
      //
      int myBPM = pulseSensor.getBeatsPerMinute();  // Calls function on our pulseSensor object that returns BPM as an "int".
      // "myBPM" hold this BPM value now.
      if (pulseSensor.sawStartOfBeat()) {            // Constantly test to see if "a beat happened".

        Serial.println(myBPM);
        char buffer1[10];
        char buffer2[10];
        String BPM = dtostrf(myBPM, 4, 1, buffer1);
        String temp = dtostrf(tempC, 4, 1, buffer2);
        // Print the value inside of myBPM.
      }
    }
    //----------------
    void panic_button() {
      panic = digitalRead(8);
      if (panic == HIGH) {
        Serial.println(panic);
      }
    }
    // Disconnect from ThingSpeak
    if (!client.connected() && lastConnected)
    {
      Serial.println("...disconnected");
      Serial.println();
      client.stop();
    }
    // Update ThingSpeak
    if (!client.connected() && (millis() - lastConnectionTime > updateThingSpeakInterval))
    {
      updateThingSpeak("field1=" + BPM + "&field2=" + temp + "&field3=" + panic);
    }
    // Check if Arduino Ethernet needs to be restarted
    if (failedCounter > 3 ) {
      startEthernet();
    }
    lastConnected = client.connected();
    }
    void updateThingSpeak(String tsData)
    {
      if (client.connect(thingSpeakAddress, 80))
      {
        client.print("POST /update HTTP/1.1\n");
        client.print("Host: api.thingspeak.com\n");
        client.print("Connection: close\n");
        client.print("X-THINGSPEAKAPIKEY: " + UVGOLIA40B9YHKU8 + "\n");
        client.print("Content-Type: application/x-www-form-urlencoded\n");
        client.print("Content-Length: ");
        client.print(tsData.length());
        client.print("\n\n");
        client.print(tsData);
        lastConnectionTime = millis();
        if (client.connected())
        {
          Serial.println("Connecting to ThingSpeak...");
          Serial.println();
          failedCounter = 0;
        }
        else
        {
          failedCounter++;
          Serial.println("Connection to ThingSpeak failed (" + String(failedCounter, DEC) + ")");
          Serial.println();
        }
      }
      else
      {
        failedCounter++;
        Serial.println("Connection to ThingSpeak Failed (" + String(failedCounter, DEC) + ")");
        Serial.println();
        lastConnectionTime = millis();
      }
    }
    void startEthernet()
    {
      client.stop();
      Serial.println("Connecting Arduino to network...");
      Serial.println();
      delay(1000);
      // Connect to network amd obtain an IP address using DHCP
      if (Ethernet.begin(mac) == 0)
      {
        Serial.println("DHCP Failed, reset Arduino to try again");
        Serial.println();
      }
      else
      {
        Serial.println("Arduino connected to network using DHCP");
        Serial.println();
      }
      delay(1000);
    }

body:
If you look at this fragment of your code:

    void panic_button(){
      panic = digitalRead(8);
        if(panic == HIGH){
        Serial.println(panic);
        }
    }
    // Disconnect from ThingSpeak
    if (!client.connected() && lastConnected)

You see that the function panic_button() stops at the last }, the next is a statement which is not part of a function.

I think the } should be removed, but your code is aligned quite badly, so:

- First align all { and }
- Indent each level with a tab or 2, 3 or 4 spaces
- You will see a misalignment, add/remove a { (like above) or }.


message:
attachInterrupt() corrupting Serial buffer requiring Serial restart

I am working on a proof-of-concept ADC to "explode" what's inside of an ADC chip for teaching purposes.

Currently, I have a sketch that uses a push-button to act as a clock-pulse that counts up (1, 2, 3, 4, ...) for every positive edge using the attachInterrupt() function.

The sketch works great to view the data in the serial monitor.

I am pairing the Arduino (Teensy 3.2) with a Raspberry Pi configured to read data off the Serial line to a text box.

After a good bit of troubleshooting it appears that the `attachInterrupt()` function corrupts the Serial buffer with garbage for every interrupt. For instance, if I use

    Serial1.flush();
    Serial1.begin(115200);

immediately after the interrupt and *then* send out my data using `Serial.println()` I get my expected decimal value at my output. However, without these lines I just get unicode garbage at my Serial output. See full "fixed" sketch code below:

My question is: why is this happening? I should not need to restart Serial every iteration of the clock.

    #define HWSERIAL Serial1

    const int numBits = 12;             //Number of bits in ADC (resolution)
    const int comparatorPin = 14;       //Pin number of comparator out
    const int clockPin = 15;            //Pin number of external clock (square wave) input; expecting clock with 50% duty-cycle
    volatile int comparatorState = 0;   //Is comparator high or low?
    volatile bool clockState = 0;       //Is clock high or low?
    volatile int masterCount = 0;       //Our master count
    volatile bool isSameVal = false;    //Is the value of the master count the same value as last cycle?

    int outVal = 0;

    int masterBinCount[12];     //Array to store binary value of the master count
    byte outputPins[12];        //Array to store the numbers associated with the output pin numbers
    int maxValue = 0;           //Initialize max counter value to zero

    void setup() {
      Serial.begin(115200);       //Begin Serial transmission
      HWSERIAL.begin(115200, SERIAL_8N1);
      HWSERIAL.flush();
      delay(2000);

      defineOutPins(outputPins);  //Assign pin numbers for output pins

      pinMode(14, INPUT);   //Comparator Pin
      pinMode(15, INPUT);   //Clock-in pin

      maxValue = pow(2, numBits);   //Set max counter value to max bit resolution. Ex. for 12 bits --> 4096
    }

    void loop() {
      attachInterrupt(clockPin, doOnClock, RISING);   //When clock is on a positive-edge execute doOnClock function

      HWSERIAL.flush();
      HWSERIAL.begin(115200);

      if(isSameVal == false) {    //If the master count is NOT the same as the last cycle
        convertDecToBin();        //Convert the master count (dec) to binary
        binaryToPins();           //Send the binary value (via digitalWrite) to output pins
      }
      else {
        //Do nothing
      }
      delay(1000);
    }

    void defineOutPins(byte pinNos[]) {   //Assign pin numbers to parallel binary out: Teensy 3.2 pin #0 --> #11
      for(byte i = 0; i < numBits; i++) {
        pinNos[i] = {i};      //Assign current pin this value
        pinMode(i, OUTPUT);   //Define pins as outputs
      }
    }

    void doOnClock() {
      comparatorState = digitalRead(comparatorPin);   //Check comparator state

      if(comparatorState >= 0.5) {            //Check if positive clock pulse
        if(masterCount == (maxValue - 1)) {   //Check if current count value is at "ceiling"
          //Do nothing
        }
        else {            //Else increment count up
          masterCount++;
        }
      }
      else if(comparatorState < 0.5) {    //Check if negative clock pulse
        if(masterCount == 0) {            //Check if current count value is at "floor"
          //Do nothing
        }
        else {
          masterCount--;    //Else decrment count down
        }
      }

      isSameVal = false;    //Set "finished" counting for this clock-pulse
    }

    void convertDecToBin() {
      for(int j = 0; j < numBits; j++) {
        int tempCnt = bitRead(masterCount, j);
        masterBinCount[numBits - (j+1)] = tempCnt;    //Populate the master binary count array in "reverse" order starting with the LSB at the highest array index
      }
    }

    void binaryToPins() {
      for(int e = 0; e < numBits; e++) {
        //digitalWrite(outputPins[e], masterBinCount[e]);   //Write our master binary value to output pins
        //Serial.print(masterBinCount[e]);                    //THIS LINE IS FOR TROUBLESHOOTING!!
      }
      isSameVal = true;       //Tell program we wrote the master count to the pins for this clock cycle

      outVal = masterCount;

      Serial.println(outVal);
      HWSERIAL.println(outVal);

      //Serial.print(" decimal: ");   //THIS LINE IS FOR TROUBLESHOOTING!!
      //Serial.print(masterCount);    //THIS LINE IS FOR TROUBLESHOOTING!!
      //Serial.println("");           //THIS LINE IS FOR TROUBLESHOOTING!!
    }

body:
I believe your issue is with initializing `HWSERIAL.begin(115200);` in `void loop`. I created this simple sketch to verify this. Firstly, I commented out the second initialization of `Serial.begin`, and you can see I was getting a perfect output to the serial monitor. Then I uncommented the line, re-uploaded the code to the Arduino, and you can see it didn't even make it through one print before it sent a bunch of garbled junk and effectively froze my serial port.

Remove `HWSERIAL.begin(115200);` from `void loop` and only set it in `void setup`.

Hope this helps!

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

    void loop()
    {
      Serial.begin(115200);
      Serial.print("Test");
      Serial.print(" - ");
      Serial.println(millis());
    }

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/1zd6Y.png


message:
Generate a ramp input with an Arduino Uno

Is there anyway to generate a ramp input from an Arduino Uno? A visual depiction of the pulse I am looking for is as follows:
[![Ramp Input][1]][1]

With other microcontrollers, I was able to use their in-built DACs, however I am aware that the Arduino UNO doesn't have any? Is there a way using PWM or analogWrite to output these type of pulses? I'm new to Arduino programming, so I'm a bit unsure. However my next guess would be to use an R-2R ladder to output this type of pulse?

  [1]: https://i.stack.imgur.com/j6zWr.png

body:
By "ramp", it seems that you mean a square wave with sloping rather than vertical edges between + and -.  Can you clarify the question further: do the sloping parts need to be linear?

Direct synthesis of the waveform could be done using the digital output ports and an R2R ladder, as suggested in the comments.  Each PWM timer output of the AVR can control output of 2 digital pins and definitely with a timing precision better than 1 microsecond.  If high voltage resolution is needed, this method may not be able to produce the result you want.

Other possible solutions:

 - The waveform as plotted in the original post looks like a truncated sine wave.  Such a waveform could be made by clipping a sine wave with an operational amplifier.  For the sine wave connect the Arduino to a DDS module such as AD9850/1.

 - Use an external digital-to-analog converter, [e.g. MCP48x2][1]

 - Use an Arduino Zero or other 32-bit microcontroller (e.g. ARM STM32).  These microcontrollers have a true analog output pin, but it's not bipolar.

  [1]: http://ww1.microchip.com/downloads/en/devicedoc/20002249b.pdf


body:
A RC filter will create a slow slewrate.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/MHmk0.png)

<!-- End schematic -->

The circuit creates this signal:
[![enter image description here][1]][1]

A slow rising signal and a fast falling signal can be created with an extra transistor (the signal will be inverted).

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/gPYKr.png)

<!-- End schematic -->

For a linear rising and falling edge, a resistor network with a few digital pins is a simple solution. I think it can be created with an opamp circuit as well, but there are also special chips called "slew rate limiter".

  [1]: https://i.stack.imgur.com/iTkMG.png


message:
How can I create an analog signal which is similar to PMT (Photo Multiplier Tube) pulse using analog write?

I have developed a circuit to process the PMT pulse output. For the testing, I need an artificial signal which is similar to the PMT pulse. How can I use `AnalogWrite()` to create such type of signal?

[![Attached image show the waveform of PMT Pulse][1]][1]

  [1]: https://i.stack.imgur.com/yo1oo.jpg

body:
Short answer: You can't.

The Arduino can't do analog output at all, much less matching a specific analog waveform of ≈40ns duration.

PWM on the Arduino simulates **constant** analog voltages using square wave pulses of variable duty cycle. It has no support for creating analog waveforms of any type, much less ones with such a short duration.

**EDIT**

As mentioned in this thread: https://arduino.stackexchange.com/questions/62816/generate-a-ramp-input-with-an-arduino-uno

You could use a resistor ladder to create a roll-your-own DAC, and then use direct port register manipulation (not digitalWrite) to set the pins controlling your resistor ladder and get a crude approximation of your waveform.

**Edit #2**

There is no way you'll be able to generate nanosecond scale waveforms with a normal Arduino. It just isn't fast enough.


body:
I doubt very much AVR-based Arduinos could do that.

SAMD21-based Arduinos do have a DAC, but their conversion time is about 2.85 μs. Their timer/counters can be clocked at 96 MHz, so about 10.5 ns/tick, but would yield a square pulse (that may or may not degenerate into what you need 8-).

Overall, I don't think an Arduino is the right tool for the job. Maybe something like the (very fast) Teensy 4.0 could do it, but I don't know much about those.


message:
Problem with SPI when using rf24 NRF24L01 transceiver with LED matrix MD_MAX72xx

I am currently using Arduino Mega to use a LED matrix and a NRF24L01 transceiver.

for LED matrix, I use MD_MAX72xx library. While for the transceiver I use the RF24 library.

I am already able to interface Arduino using two different LED matrix, and two matrix board is already using the SPI.

But when I try to add the RF24 library, and radio.begin(); the LED matrix isn't working properly anymore.

Here is my whole code:

    #include <MD_MAX72xx.h>
    #include <SPI.h>
    #include <Servo.h>

    #include <nRF24L01.h>
    #include <RF24.h>

    #define PRINT(s, v) { Serial.print(F(s)); Serial.print(v); }

    #define BUF_SIZE      75  // text buffer size
    #define CHAR_SPACING  3   // pixels between characters
    #define HARDWARE_TYPE MD_MAX72XX::FC16_HW
    #define MAX_DEVICES 4

    const int buzzer_pin = 26;
    const int servo_pin = 28;

    unsigned long buzz_time;
    unsigned long sys_time;
    String buzz_type = "off";
    int buzz_count = 0;
    char charr[50];

    Servo myservo;

    RF24 radio(30, 32); // CE, CSN
    const byte address[6] = "GLN71";
    //const byte address[5] = {'R','x','A','A','A'};

    struct LineDefinition
    {
      MD_MAX72XX  mx;
      char    message[BUF_SIZE];
      boolean newMessageAvailable;    // true if new message arrived
    };

    struct LineDefinition  Line[] =
    {
      { MD_MAX72XX(HARDWARE_TYPE, 51, 52, 53, MAX_DEVICES), "MAX", true },
      { MD_MAX72XX(HARDWARE_TYPE, 51, 52,  49, MAX_DEVICES), "MAX", true }
    };

    #define MAX_LINES   (sizeof(Line)/sizeof(LineDefinition))

    void printText(uint8_t lineID, uint8_t modStart, uint8_t modEnd, char *pMsg)
    // Print the text string to the LED matrix modules specified.
    // Message area is padded with blank columns after printing.
    {
      uint8_t   state = 0;
      uint8_t   curLen;
      uint16_t  showLen;
      uint8_t   cBuf[8];
      int16_t   col = ((modEnd + 1) * COL_SIZE) - 1;

      Line[lineID].mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);

      do     // finite state machine to print the characters in the space available
      {
        switch(state)
        {
          case 0: // Load the next character from the font table
            // if we reached end of message, reset the message pointer
            if (*pMsg == '\0')
            {
              showLen = col - (modEnd * COL_SIZE);  // padding characters
              state = 2;
              break;
            }

            // retrieve the next character form the font file
            showLen = Line[lineID].mx.getChar(*pMsg++, sizeof(cBuf)/sizeof(cBuf[0]), cBuf);
            curLen = 0;
            state++;
            // !! deliberately fall through to next state to start displaying

          case 1: // display the next part of the character
            Line[lineID].mx.setColumn(col--, cBuf[curLen++]);

            // done with font character, now display the space between chars
            if (curLen == showLen)
            {
              showLen = CHAR_SPACING;
              state = 2;
            }
            break;

          case 2: // initialize state for displaying empty columns
            curLen = 0;
            state++;
            // fall through

          case 3: // display inter-character spacing or end of message padding (blank columns)
            Line[lineID].mx.setColumn(col--, 0);
            curLen++;
            if (curLen == showLen)
              state = 0;
            break;

          default:
            col = -1;   // this definitely ends the do loop
        }
      } while (col >= (modStart * COL_SIZE));

      Line[lineID].mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::ON);
    }

    void buzz_start(){
        buzz_count = 5;
        buzz_time = millis();
    }

    void buzz_call(){
      if(buzz_count > 0){
        if(millis() >= buzz_time){
          if(buzz_type == "off"){
            tone(buzzer_pin, 1000);
            buzz_type = "on";
          }else{
            noTone(buzzer_pin);
            buzz_type = "off";
            buzz_count--;
          }
          buzz_time = millis() + 300;
        }
      }
    }

    void setup()
    {
      Serial.begin(57600);
      pinMode(buzzer_pin, OUTPUT);

      myservo.attach(servo_pin);

      tone(buzzer_pin, 1000);
      Serial.println("BEGIN");

      for (uint8_t i=0; i<MAX_LINES; i++){
        Line[i].mx.begin();
      }

      radio.begin();
      radio.openReadingPipe(20, address);
      radio.setPALevel(RF24_250KBPS);
      radio.startListening();

      String charrr = "STOP";
      charrr.toCharArray(charr, 50);
      printText(1, 0, MAX_DEVICES-1, charr);

      myservo.write(90);
      delay(500);
      myservo.write(180);

      noTone(buzzer_pin);
      sys_time = millis();
    }

    int counter = 10;
    int disp = 0;
    void loop()
    {
      String charrr = String(counter);
      charrr.toCharArray(charr, 50);
      printText(0, 0, MAX_DEVICES-1, charr);
      if(counter == 0){
        counter = 9;
        if(disp == 0){
         disp = 1;
         String charrr = "  GO";
         charrr.toCharArray(charr, 50);
         printText(1, 0, MAX_DEVICES-1, charr);
         myservo.write(90);
         buzz_start();
        }else{
         disp = 0;
         String charrr = "STOP";
         charrr.toCharArray(charr, 50);
         printText(1, 0, MAX_DEVICES-1, charr);
         buzz_start();
         myservo.write(180);
        }
      }
      if(millis() >= sys_time){
        counter--;
        sys_time = millis() + 1000;
      }

      buzz_call();

    }

I think the problem here is not connection, but with the initalization of the RF24, and radio.begin();

body:
I looked into the source code of the MD_MAX72XX library. The constructor with SPI pins starts software SPI.

Use the `MD_MAX72XX::MD_MAX72XX(moduleType_t mod, uint8_t csPin, uint8_t numDevices):` constructor to work with SPI hardware/library with all devices.

    struct LineDefinition  Line[] =
    {
      { MD_MAX72XX(HARDWARE_TYPE, 53, MAX_DEVICES), "MAX", true },
      { MD_MAX72XX(HARDWARE_TYPE, 49, MAX_DEVICES), "MAX", true }
    };

Or if the MD_MAX72XX worked for you with software SPI, then use some other pins then hardware SPI pins to make hardware SPI free for the NRF24L01.

    struct LineDefinition  Line[] =
    {
      { MD_MAX72XX(HARDWARE_TYPE, SW_SPI_SI, SW_SPI_CLK, MAX1_CS, MAX_DEVICES), "MAX", true },
      { MD_MAX72XX(HARDWARE_TYPE, SW_SPI_SI, SW_SPI_CLK, MAX2_CS, MAX_DEVICES), "MAX", true }
    };


message:
HC-SR04 Echo Pin Fails To Go Low After Trigger Pulse

I have implemented an HC-SR04 distance sensor using an Arduino.  After power up, the sensor operates well when objects are within range of the sensor.  However, if the distance to be measured exceeds the maximum (about 15 feet) distance, the sensor times out (which is what I expect).  However, after a time-out and with the distance between the object and the sensor in range, the Echo pin fails to be set low after a trigger pulse is generated.  The only way to fix this condition is to power down the sensor and power it back up again.  (I have verified the state of the Echo pin by using an oscilloscope.)

body: After many hours of research, I discovered that the problem is related to the fact that there is (apparently) a well-known bug in the HC-SR04 which is a Chinese clone of a Devantech SRF04.  I replaced the HC-SR04 with an SRF04 and the problem was solved.  Now, the ECHO pin always goes low after a trigger and after a time-out (i.e. the object is beyond the maximum measurement distance).


message:
Initializing variables of a function

By playing with some examples I found the following construct:

`void Show(int nav = 0) // -1 top, 1 bottom`

and I wondered what effect it has to initialize the handover parameters in the function declarations, I never noticed such an construct consciously.

So I made a small demo:

    #include <M5Stack.h> //necessary for my board
      int a;
      int b;
      int c;

    int addFunction(int x = 3, int y = 3){
      int result;
      result = x + y;
      return result;
    }

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

      // testcase 1
      a = 1;
      b = 2;
      c = addFunction(a, b);
      Serial.println("testcase 1:");
      Serial.println((String)a + " + " + b + " = " + c);

       // testcase 2
      a = 1;
      b = 2;
      c = addFunction();
      Serial.println("testcase 2:");
      Serial.println((String)a + " + " + b + " = " + c);

       // testcase 3
      a = 1;
      b = 2;
      c = addFunction(a);
      Serial.println("testcase 3:");
      Serial.println((String)a + " + " + b + " = " + c);
    }

    void loop() {
    }

The output was:

[![enter image description here][1]][1]

So I learnd:

 - if you hand over parameters, the initialization is ignored, if you call the function without handing over paramters, the functions works with the init values.

 - if you handover only one parameter it will be assigned to the first in the declaration.

**Question:**

Is there a syntax possible to only call the function with the second parameter, so that for the first paramter the intialized value of the declaration is used? Spoken for this example with a = 1, b = 2 you only handover b and the expected result would be 5.

  [1]: https://i.stack.imgur.com/9RK3G.png

body:
This is (unfortunately) not an Arduino question. It is actually about the syntax of C++ which is a rather complex language.

The mechanism you have discovered is called **default arguments**. The function prototype or definition may contain the default values of the arguments. As this is a list the default values are restricted from right to left. It is not possible to use a default parameter for argument to the left of a given argument. The order is strictly right to left.

    f(int x = 0, int y = 1, int z = 2)

    f(1,2,3) binds x = 1, y = 2, z = 3
    f(1,2) equals f(1,2,2) binds x = 1, y = 2, z = 2
    f(1) equals f(1,1,2) binds x = 1, y = 1, z = 2
    f() equals f(0,1,2) binds x = 0, y = 1, z = 2

There is a syntax for struct initialization (aka aggregate initialization) in C++ that allows naming of struct field values. This type of naming is not allowed for function calls.

Please read https://en.cppreference.com/w/cpp/language/default_arguments, https://en.cppreference.com/w/cpp/language/aggregate_initialization and https://en.cppreference.com/w/cpp/utility/functional/bind for more details. And a good C++ book.

There are languages that allow default arguments and named parameters e.g. C#, Python, Ruby and Smalltalk. Please see https://en.wikipedia.org/wiki/Named_parameter.

Cheers!

(Update)

Below is a rewrite of @VE7JRO Add function class using cast operator to perform the evaluation:

    class Add
    {
    public:
      Add(int x, int y) : m_x(x), m_y(y) {}
      operator int() { return m_x + m_y; }
      void x(int x) { m_x = x; }
      void y(int y) { m_y = y; }
      int print(Print& outp) {
        int res;
        res = outp.print(F("Add(x="));
        res += outp.print(m_x);
        res += outp.print(F(",y="));
        res += outp.print(m_y);
        res += outp.print(F(")"));
        return res;
      }
    private:
      int m_x, m_y;
    };

    Add func(1,2);

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

      func.print(Serial);
      Serial.print(F("="));
      Serial.println(func);

      func.x(12);
      func.print(Serial);
      Serial.print(F("="));
      Serial.println(func);

      func.y(13);
      func.print(Serial);
      Serial.print(F("="));
      Serial.println(func);
    }

    void loop() {
    }


body:
If your function is inside a class, you can set either variable, both variables or use the defaults.

    class Add{

        int a, b;

      public:

        Add(): a(1), b(2){}

        int AddTwoIntegers(){
          return a + b;
        }

        void SetInt1(int int1){
          a = int1;
        }

        void SetInt2(int int2){
          b = int2;
        }

    };

    Add Test1;

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

      Serial.print("Test default values = ");
      Serial.println(Test1.AddTwoIntegers());

      Test1.SetInt2(4);
      Serial.print("Set b = 4 then add to a = ");
      Serial.println(Test1.AddTwoIntegers());
    }

    void loop(){}


message:
Multiple definitions of "xxxx"

I really need your help. I use VisualStudio and PlatformIo I still get this error:
    > Linking .pioenvs\esp12e\firmware.elf
    > .pioenvs\esp12e\src\main.cpp.o:(.data.DebugX+0x0): multiple definition of `DebugX'
    > .pioenvs\esp12e\src\customFunctions.cpp.o:(.data.DebugX+0x0): first defined here
    > collect2.exe: error: ld returned 1 exit status
    > *** [.pioenvs\esp12e\firmware.elf] Error 1

I use header guards in my file, so I do not understand why is this part of code redeclared. I had to miss some elementary in cpp programming but I still can't get it to work.

Copy of my project:
https://bitbucket.org/fires/programingtesting/src/master/ESP8266/cpp/RedefinedError/

main.cpp
```
    #include <Arduino.h>;
    #include "../include/defines.h"
    //#include "../include/customFunctions.h"
    // Time
    uint32_t mTimeToSec = 0;
    uint32_t mTimeSeconds = 0;
    void setup() {
    etc. etc. etc.
```

customFunction.h
```
    #pragma once
    #ifndef CUSTOMFUNCTIONS_H
    #define CUSTOMFUNCTIONS_H
    void connectWiFi();
    void initializeOTA();
    #endif
```

defines.h
```
    #pragma once
    #ifndef DEFINES_H
    #define DEFINES_H
    #include <jled.h>
    #define BowlingLed 5
    #define StatekLed 4
    int DebugX = 1;
    #endif
```

Thanks for the help, I read many articles and many issues but I still do not understand why DebugX is redefined if it is in header guard.

body:
Included files are included before compilation, really replacing the #include with the content of the file.

If you write `int DebugX = 1;` you define a variable. And it is defined in every source file which includes it. Then the linker finds it in more then one unit and ends with "multiple definitions" error.

The variable must be defined only in one compilation unit (.c, .cpp). For example in your case customFunctions.cpp. To make it available in other source files put `extern int DebugX;` into the .h file.


message:
Why is Arduino resetting while driving motors?

I am driving motors for my line-follower project . The circuit schematic is given below [![Circuit schematic][1]][1]

  [1]: https://i.stack.imgur.com/7bVmC.jpg
The power source is a 11.1V 2200mAh 25C Lipo . Practically the cells give 11.5-12V. I used a switching buck regulator to step down the voltage. However , when i run my robot on track after few seconds,the arduino tends to reset and run again. This problem typically arises when i drive the motors at higher PWM(above 180 on analogWrite function). Since i use PID, limiting the PWM means i have to drive at lower speeds which i do not want.

I am providing links for the items i used for my circuit:

  1. [buck converter](https://www.amazon.in/LM2596S-Converter-Module-Supply-1-23V-30V/dp/B0784PYZ97/);

  2. [motor driver](https://www.amazon.in/Generic-E_14013096-Tb6612Fng-Arduino-Microcontroller/dp/B01DAA6GMC/);

  3. [IR sensor module](https://www.amazon.in/Products-Channel-Analogue-Digital-Follower/dp/B07GXL5L7J/);

  4. [DC motors](https://www.amazon.in/Invento-Kg-cm-Shaft-Torque-Geared/dp/B07CKMFYDG/).

The sensor array draws 150mA at peak. Any suggestions as to where the problem might lie would be of great help. Thank you .

EDIT 1: Changed the input voltage Vin to 7.9V through the buck converter .
        The problem still persists .

body: The VIN pin goes to a 5V voltage regulator on the Arduino and needs at least about 7V minimum to work properly.  If you want to supply 5V to an Arduino do it either on the 5V pin or via the USB connector.  The VIN pin should receive 7V to 12V.


body:
Resetting is due either to a software bug or voltage sag, and since it correlates with driving the motors harder, it's almost certainly the latter. You probably suspected as much since you mentioned the current draw of the sensor array. A quick experiment - disconnecting the sensors (and possibly a software patch to keep the robot running straight, without them) might help you discover the reason.

Each chip and each of its pin drivers has a current budget. It would be a good idea to look at the max current spec of the Atmega2560 and its pin drivers, and any other current specs mentioned in the datasheet, and make sure you're not trying to run it out of spec. The buck converter will have a limit, too, so make sure you're within its spec. If the output regulation of the buck converter is good enough, you can regulate it to 5v and bypass the Mega's on board regulator, for another saving.


body: One major drawback to working with motors is the large amounts of electrical noise they produce. This noise can interfere with your sensors and can even impair your microcontroller by causing voltage dips on your regulated power line. Large enough voltage dips can corrupt the data in microcontroller registers or cause the microcontroller to reset. You can avoid this problem by soldering capacitors along your motor terminals. Use 1µF ceramic capacitors for example


body:
You should either feed the 5.5v from the buck converter to the 5v pin of the arduino, or the 11.5v to the Vin.
The arduino board contains its own 5v converter (and a 3.3v but that's not in question here). That takes the voltage of the Vin pin and converts it to 5v for the board to use. This regulated 5 v is available on the 5v pin for your sensors for example.

You can also power it directly on the 5v pin, but that requires regulated 5v. This is also how it is powered through USB which supplied regulated 5 v.

The 5.5 v from your buck should be fine for this, by you don't need it. Put the "raw" 11.5 to the Vin pin.


body:
This is the common issue when trying to connect power and digital circuits together. Probably, when motor starts, there is a short-time voltage drop in **Vin** due to high motor start current. Consider to use Schottky diode and capacitor to protect digital power circuit from transitional currents.[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/YLzQf.png


message:
WindowsError(31, 'A device attached to the system is not functioning.') in arduino

Having board esp32 devkit v1, to get started with arduino ide (installed recommended boards for esp32) I marked board as`DOIT ESP32 DEVKIT V1` (as no other options as like `ESP32 DEVKIT V1` ) so upload gets this error

        esptool.py v2.6
    Serial port COM3
    Traceback (most recent call last):
    File "esptool.py", line 2959, in <module>
    File "esptool.py", line 2952, in _main
    File "esptool.py", line 2652, in main
    File "esptool.py", line 222, in __init__
    File "site-packages\serial\__init__.py", line 88, in serial_for_url
    File "site-packages\serial\serialwin32.py", line 62, in open
    serial.serialutil.SerialException: could not open port 'COM3': WindowsError(31, 'A device attached to the system is not functioning.')
    Failed to execute script esptool
    the selected serial port Failed to execute script esptool
     does not exist or your board is not connected

so how do I upload my programs?
I would be highly obliged if you could please help me solve this problem.
Thank you.

body: I got this error.  Then switching USB ports fixed the problem.  Showed up on COM3 in either place. I just switched from a built-in USB port to on off a hub, and it started working.


message:
Arduino Uno with 6x 5V solenoids + 9V battery - Not enough power?

I have 6 5V solenoids connected to an Arduino Uno, each of them with a TIP120 transistor, diode and resistor. Exactly like https://core-electronics.com.au/tutorials/solenoid-control-with-arduino.html but 6 times. I'm using a 9V battery connected to the DC input, as well as USB input to my PC.

Now the problem is that if I activate 5 or 6 solenoids at once, the Arduino seems to get interrupted / lose all power for a second (disconnect sound from the PC and no activity). I've tested them one by one and everything works, but I can activate at most 4 solenoids at once.

What am I missing? Do I need more power?

body:
>I'm using a 9V battery connected to the DC input

Well, there's your problem. Those 9V PP3 batteries are barely enough to power the Arduino by itself. Add anything like motors and solenoids and you're going to have problems. Big problems.

Ditch the PP3 battery. It's only suitable for very low current devices, like smoke alarms. For anything more you need at least multiple series AA batteries.

Also the solenoids must be powered direct from your power source (or through their own regulator if needed), since the Arduino's on-board regulator will go into thermal shutdown quite quickly with 9V in and a large current draw.


body: Another possibility is to use latching solenoids controlled by an H-bridge so that they only need power to turn on or turn off. However, I don't know if they are available for your application. When I looked into latching irrigation valves they were much more expensive than simple solenoid valves.


body: You're experiencing a lack of available current. When the solenoids are operating, the system is trying to draw more current than the battery can provide, so what happens instead is the voltage starts to drop. (I can't remember exactly why this happens right now). When this happens the arduinos power supply detects an under-voltage condition and shuts down, but as soon as it shuts down the current draw tanks and the voltage rises again causing the system to restart. Essentially, the answer to this is to provide your system with a larger current source and the problem should go away.


message:
Arduino delay inside of an Interrupt

Using the delay function inside of an ISR is frowned upon when programming in an Arduino. The general response to solve this desire is to design the program to delay in a more cleanly way outside of the interrupt.

My question is simply why. Why does putting a delay() inside of an ISR cause wonky behavior with the Arduino. Whats going on under the hood?

body:
Because a delay inside an interrupt causes that interrupt and other (lower priority) interrupts not to execute anymore until the delay is over.

Assume in an ISR you handle the incoming bytes from a UART. If you add a delay in the ISR, and the buffer of the UART gets full, it will overflow and you miss bytes.


body:
> Why is putting a delay() inside of an ISR cause wonky behavior with the Arduino. Whats going on under the hood?

The first problem is that delay() is a busy loop monitoring millis(). The value that millis() returns will not change inside an ISR as interrupts are turned off inside an ISR; this is why ISRs must be as short and fast as possible, or they will interfere with other interupts

So if you call delay() within an ISR your poor AVR is now deadlocked! It is waiting for something to happen that can now never happen.

A second problem is that if your ISR takes too long, you can miss other interrupts; millis() and micros() can miss ticks and become inaccurate!


body:
This is an addition to esoterik's answer.

Most of the times, that people try to use `delay()` inside an ISR it is a poor design choice to even use it in a general way, that will lead to the described problems (waiting forever or missing other interrupts). `delay()` is a simple function mainly for beginners with very simple programs. It is a simple starting point. Mostly the use of it in any program is not a good choice, since you are busy waiting without being able to do something else (like responding to user input). There are better ways, involving `millis()` itself, that keep your program extendable (so that, if you want to add a functionality, this will not be blocked by the first part of the code). And when your program reaches the complexity of using own ISRs, you should avoid `delay()`, unless you really know, what you are doing.

IMO at some (rather early) point, every Arduino programmer has to learn how to use `millis()` to do timed code execution. You can look at the `BlinkWithoutDelay` example, that comes with the Arduino IDE.