body:
I tried to make code following your instruction about `mills`,
and it looks like this. Unfortunately, it is not working. Is there problem with my code?

Here is my code:
<!-- language-all: lang-cpp -->

    #include <LiquidCrystal.h>
    #include<Servo.h>

    Servo myservo;  // create servo object to control a servo

    // These constants won't change. They're used to give names to the pins used:
    const int analogInPin1 = A0;  // Analog input pin that the photosensor is attached to
    const int analogInPin2 = A1;  // Analog input pin that the photosensor is attached to
    const int analogInPin3 = A2;  // Analog input pin that the photosensor is attached to
    const int analogInPin4 = A3;  // Analog input pin that the photosensor is attached to
    int sensorValue1;
    int sensorValue2;
    int sensorValue3;
    int sensorValue4;
    unsigned long m;

    //declare counter as an input
    int Chactr =0;
    int Disctr =0;

    byte state;

    const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    void setup() {
      myservo.attach(9);  // attaches the servo on pin 9 to the servo object
      myservo.write(0);  // back to 0 degrees.
      delay(1000); // wait for a second.
      pinMode(13, OUTPUT); // initialize digital pin 13 as an output.
      Serial.begin(9600);  // initialize serial communications at 9600 bps:
      lcd.begin(16,2);

      delay(5000);
    }

    void loop() {

      // read the analog in value:
      sensorValue1 = analogRead(analogInPin1);
      sensorValue2 = analogRead(analogInPin2);
      sensorValue3 = analogRead(analogInPin3);
      sensorValue4 = analogRead(analogInPin4);

      delay(3000);

      // print the results to the Serial Monitor:
      Serial.print("sensor1 = ");
      Serial.print(sensorValue1);
      Serial.print("\n");

      Serial.print("sensor2 = ");
      Serial.print(sensorValue2);
      Serial.print("\n");

      Serial.print("sensor3 = ");
      Serial.print(sensorValue3);
      Serial.print("\n");

      Serial.print("sensor4 = ");
      Serial.print(sensorValue4);
      Serial.print("\n");

      Serial.print("Led State:  ");
      Serial.println(state);
      Serial.print("\n");

      if (sensorValue1 >=569 && sensorValue2 >=520 && sensorValue3 >=419 && sensorValue4 >=250)
      {
        m=(millis()+60000);
      }

      if(sensorValue1 <=568 && sensorValue2 <=519 &&sensorValue3 <=418 && sensorValue4 <=249)
      {
        m=0;
      }

      if (sensorValue1 >=569 && sensorValue2 >=520 && sensorValue3 >=419 && sensorValue4 >=250 && m==millis())
      {
        state=1;
        delay(5000);
        digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
        delay(5000); // wait for a second

        myservo.attach (9);
        myservo.write(30);
        delay(3000);
        myservo.write(0);
        delay(3000);

        myservo.detach ();
        delay (1000);

        Disctr = Disctr + 1;

        delay(900);

        Serial.print("Battery Full: Discharge ON");
        Serial.print("\n");
      }
      else if (sensorValue1 ==0 && sensorValue2 ==0 && sensorValue3 ==0 && sensorValue4 ==0 )
      {
        m=(millis()+60000);
      }

      if(sensorValue1 >=1 && sensorValue2 >=1 && sensorValue3 >=1 && sensorValue4 >=1)
      {
        m=0;
      }

      if(sensorValue1 ==0 && sensorValue2 ==0 && sensorValue3 ==0 && sensorValue4  ==0 && m==millis())
      {
        state=0;
        delay(5000);
        digitalWrite(13, HIGH ); // turn the LED On by making the voltage high
        delay(5000); // wait for a second

        Chactr = Chactr + 1;
        delay(900);

        Serial.print("Battery Empty: Charging ON");
        Serial.print("\n");
      }
      {
        lcd.setCursor(0,0);
        lcd.print("Charge Cycle: ");

        lcd.setCursor(13,0);
        lcd.print(Chactr);

        lcd.setCursor(0,1);
        lcd.print("Discha Cycle: ");

        lcd.setCursor(13,1);
        lcd.print(Disctr);

        delay(1000);
      }
    }

title: Question regarding Servo including Serial monitor display

Answers: 1

body:
So what you want to do is be able to activate the servo when 4 green bars appear over the course of one minute correct?

I think you would need to create three if statements and one new variable. The first if statement will be, if it detects four green bar, then `m=(millis() + 60000)`. Then you will need to nest another if statement in here to say if it detects ONLY three bar, then `m = 0`.
Your third if the statement is if it detects the four green bars AND `m == millis()` then the servo will activate.

This is how I would do it, but I am not very experienced. I'm pretty sure others will have a cleaner and simpler code but this should work.


body:
I want to use an ultra-sonic sensor and the led concurrently. I want the led to blink every 0.2 seconds and the ultra-sonic to measure distance without regard to the blinking.

The problem is I have the following code for blinking:
>     digitalWrite(13, HIGH);
>     delay(1000);
>     digitalWrite(13, LOW);
>     delay(200);

which makes the ultra-sonic sensor to be delayed as well, but I want it to keep measuring distance.
Any tips?

title: Using two sensors with delay concurrently

Answers: 2

body:
You could try to use [millis()][1]. It is a timer that measures how long your program has been running. With some math, you could use millis to let your LED blink without delaying the ultra sonic sensor.

  [1]: https://www.arduino.cc/reference/en/language/functions/time/millis/

body:
There is a non-blocking library that works similar to `delay()` [Virtual Delay][1]. This sketch turns your Uno's built-in LED ON for 1 second, then OFF for 200ms, repeatedly.

    #include <Arduino.h>
    #include "avdweb_VirtualDelay.h"

    VirtualDelay delay1, delay2;

    void setup(){

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

    }

    void loop(){

      // This sequence has a deadlock.
      if(delay1.elapsed()){
        digitalWrite(LED_BUILTIN, LOW);
        delay2.start(200);
      }

      if(delay2.elapsed()){
        digitalWrite(LED_BUILTIN, HIGH);
        delay1.start(1000);
      }

      // This breaks the deadlock. You can start with any
      // delay object you want e.g. delay2.start(0);
      DO_ONCE(delay1.start(0));

      // Your code here.

    }

The library's author has an excellent tutorial on their website: [avdweb Virtual Delay timer for Arduino][2].

  [1]: https://github.com/avandalen/VirtualDelay
  [2]: http://www.avdweb.nl/arduino/libraries/virtualdelay


body:
In previous question in this forum - I asked about updating clock on an ESP8266, using MQTT broker to send a time stamp on demand, in following manner:

1) ESP8266 sends a publish containing the payload :"sync",

2) broker answers in string format ( this part is python )

    def on_message(self, client, obj, msg):
        self.arrived_msg = msg.payload.decode()
        if self.arrived_msg == "sync":
            a = datetime.datetime.now()
            b = "%d,%d,%d,%d,%d,%d,%d" % (a.year, a.month, a.day, a.hour, a.minute, a.second, a.microsecond) .  <------ here a string time format is created
            self.client.publish(topic=self.topics[0], payload=b, qos=self.topic_qos)

3) on a terminal (MAC OS), subscribed to relevant topic- cant see publish results. which are OK:

    sync                           <----- ESP sends request
    2018,9,18,12,44,18,903242      <----- string answer from broker

4) **BUT** when Arduino code get this time stamp:

    void callback(char* topic, byte* payload, unsigned int length) {
            char incoming_msg[50];
            // ledBlink(30, 5);
            Serial.print("Message arrived [");
            Serial.print(topic);
            Serial.print("] ");
            for (int i = 0; i < length; i++) {
                    Serial.print((char)payload[i]);  <----- print #1
                    incoming_msg[i] = (char)payload[i];  <----- generate incoming msg
            }
            Serial.println("");

            if (strcmp(topic,clockTopic)==0) {       <------- detect relvant topic for clock sync
                    Serial.print(incoming_msg);  <------ Print #2
            }

5) I get this result on serial monitor :

    Message arrived [HomePi/Dvir/Clock] 2018,9,18,13,48,5,230009 <---- here time stamp is OK , Print #1
    2018,9,18,13,48,5,230009$��?O: @ . <----- Print #2

EDIT1:

6) I tried adding a null termination in time stamp, but it just added `\0` to time stamp
Appreciate any help

Guy

title: Using MQTT to send time stamp - to Arduino

Answers: 2

body:
You forgot to set the terminating zero of the c-ctring `incoming_msg`.

add `incoming_msg[length] = 0;`

body:
In C a string is "null terminated".  That means that the very last character of every string *must* be character 0 (or NULL).

You need to ensure that you add that NULL character to the end of your `incoming_msg` string to terminate it, or force the entire string to be cleared to NULLs before you populate it.

The simplest way is to zero the string:

    bzero(incoming_string, 50);

Or you can force a 0 to be appended after each byte is added:

    incoming_msg[i] = (char)payload[i];
    incoming_msg[i+1] = 0;

Or just add one at the end:

    incoming_msg[length] = 0;

There's many ways of doing it - as long as you get that NULL in there somehow.


body:
I am trying to make a alarm and I have two blinking leds (red and blue). They work fine but I want two more that fade in and out.

I have a buzzer on it too.

I am very new to programming. By the way, the code below runs with no errors; just does not do what its intended to.

    int led = 9;
    int brightness = 0;
    int fadeAmount = 5;

    void setup() {
      pinMode(11,OUTPUT);
       pinMode(12,OUTPUT);
        pinMode(led, OUTPUT);
    }

    void loop() {
      digitalWrite(11, HIGH);
      delay(200);
      digitalWrite(11, LOW);
      delay(200);

      digitalWrite(12, HIGH);
      delay(200);
      digitalWrite(12, LOW);
      delay(200);

     digitalWrite(led, brightness);

     brightness = brightness + fadeAmount;

    if (brightness <= 0 || brightness >= 255) {
      fadeAmount = -fadeAmount;
    }
     delay(30);
    }

title: How can you have two blinking leds and a fading one

Answers: 2

body:
You have 2 problems:

 1. You are using `digitalWrite()` with an analog value. `digitalWrite()` will interpret a value of `0` as LOW and any other value as HIGH. So the LED will mostly be on and only off in the time, when the brightness value becomes zero. You will have to use `analogWrite()` to get a fading effect.

 2. Currently your fading effect will be very very slow, since the value is only updated once every 830 ms. You should ditch all the `delay()` calls and instead use the principle, that is shown in the `BlinkWithoutDelay` example of the Arduino IDE. Think of the blinking as being like baking a pizza. When you want to bake a pizza in your oven, you wouldn't want to sit in front of the oven, staring at the pizza and waiting for it to be ready. This is basically, what you are doing with LED blinking in your sketch. With the pizza you would look at the clock, when you put the pizza in. Then you would go away doing other things and regularly check the clock for how much time has gone by. And then, when it is finally the time to take the pizza out, you would go back to the oven. There are plenty explanations and tutorials on the web, what exactly is done there.

[Here at the Arduino documentation][1] you can find the example with explaining text.

  [1]: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

body:
While there are better ways to do this, as pointed out by other posters, for what you're trying to learn right now, your program (almost!) works just fine. You'll need the more advanced techniques as you progress to more complex programs. But for now, I made a couple of edits to your program to get you going:

 - The most important one was to use `analogWrite()` for the PWM LED (LED 9). That makes it fade in and out instead of turn on and off (with a long period).
 - I turned one LED on and one off at the same time, getting rid of the dark periods and 400ms of combined delay.
 - I doubled the fadeAmount to fade in and out a little faster; it wasn't very visible with an increment of 5.

Here it is with those changes:

    int led = 9;
    int brightness = 0;
    int fadeAmount = 10;

    void setup() {
      pinMode(11,OUTPUT);
       pinMode(12,OUTPUT);
        pinMode(led, OUTPUT);
    }

    void loop() {
      digitalWrite(11, HIGH);
      digitalWrite(12, LOW);
      delay(200);
      digitalWrite(11, LOW);
      digitalWrite(12, HIGH);
      delay(200);

     analogWrite(led, brightness);

     brightness = brightness + fadeAmount;

    if (brightness <= 0 || brightness >= 255) {
      fadeAmount = -fadeAmount;
    }
     delay(30);

}

Update:

> what if i wanted to add a a second led

I'm assuming you mean a fading LED, that it's pretty clear where you'd a blinking one?

Blinking in-phase is easy - write the same `brightness` to both. To fade them out of phase, you'll need a second brightness-variable (and possibly a second fade-amount), and an increment/decrement and limit test for each LED.

But note how your code starts getting more complex as you add components and try to manage them in a single loop, with `delay()`s? That's when you'll want to try the Blink Without Delay example, and compare adding new LEDs that way, to adding new LEDs to your current program.


body:
I have developed an Arduino program that plays a **WAV** file from the **SD** card using a **speaker**.

This is the circuit schematic

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

The sketch I'm using is based on **TMRpcm** library and **PWM** output

    #include <TMRpcm.h>
    #include <SD.h>
    #include <SPI.h>
    int sdpin=10;
    TMRpcm tmrpcm;

    void setup()
    {
        Serial.begin(9600);
        pinMode(sdpin, OUTPUT);
        tmrpcm.speakerPin=9;
        tmrpcm.setVolume(3);
        SD.begin();
    }

    void loop()
    {
        if(Serial.available()>0)
        {
            String data=Serial.readString();
            if(data=="pause")
            {
                if(tmrpcm.isPlaying()==1)
                {
                    tmrpcm.pause();
                }
            }
            else if(data=="stop")
            {
                if(tmrpcm.isPlaying()==1)
                {
                    tmrpcm.stopPlayback();
                }
            }
            else
            {
                String path="/Music/"+data;
                if(tmrpcm.isPlaying()==1)
                {
                    tmrpcm.stopPlayback();
                }
                tmrpcm.play(path.c_str());
            }
        }
    }

At first I could play the music with the speaker but then it stopped working and because I don't have enough skill to make one myself, I would like to know if I can use a **buzzer** for that.

I know that buzzers can be used to generate melody using the **tone()** function but I'm not sure if I can use them to play wav files using PWM output.

Any help will be appreciated.

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

title: Arduino - Playing WAV files with a buzzer

Answers: 2

body:
There are different kinds of buzzers. The simplest one is just a piezoelectric transducer in a plastic casing. You can drive it directly by an arduino pin since its impedance is high. It will work fairly well for high frequencies, but don't expect any bass from it.

Another type of buzzer is a piezoelectric transducer connected to a simple oscillator circuit that will generate a waveform with a frequency typically between 1 and 4 kHz. This type of buzzer most likely won't work since the signal produced by your Arduino will be used to power the oscillator circuit rather than drive the piezoelectric transducer.

Please note that the pin you used to drive the speaker is possibly no longer operational. The impedance of the speaker was likely low enough to draw more current than what the pin of the microcontroller is rated for which probably caused damage to it. A non-piezoelectric speaker should never be connected to an Arduino without an amplifier in between.

body:
When driving a passive buzzer, you should always have the signal output from the Arduino go to a transistor tied between the ground and the (-) negative side of the buzzer. Also, if you use a regular NPN transistor, you should also have a small resistor between the Arduino and the transistor base.

[![buzzer driver circuit][1]][1]

The transistor is providing two functions; it's potentially amplifying the signal (if the (+) positive side of the buzzer is at a higher voltage than the Arduino) and it's also isolating (partially) that voltage from the Arduino. This helps save pins!

The resistor is to limit the current going through the transistor and helps keep both your Arduino and the transistor healthy. Voltage thrills, current kills and resistors limit current. If you use a MOSFET you want to change this from a low-ohm series resistor to a high-ohm pull-down resistor -- 4.75K or 10K is fine. A MOSFET is much higher impedance than an NPN transistor and should not be left floating.

Additionally, you want to add a diode between the (+) and (-) terminals on the buzzer. This may be the most important part of the circuit! When oscillating, the buzzer (whether magnetic or piezo) acts like an inductor and will accumulate a charge over time. This will be heard as a slowly diminishing volume from the buzzer. This charge will eventually overcome the protection diodes built into the GPIO pin (or any transistor) and destroy it! The diode blocks that charge loop and saves your chips.

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


body:
I'm trying to control NodeMCU via Android application and I can control NodeMCU easily but when I added the URL to hit the PHP code to enter data in MYSQL, neither NodeMCU is controllable nor NodeMCU is hitting the PHP code. I'm confused with `content type: text/html` - I'm not sure where to set this piece. Is there any mistake I'm doing or anything I'm missing?

Following is the ESP8266 code on Arduino IDE:

    #include <ESP8266WiFi.h>

    const char* ssid = "ssid";
    const char* password = "password";
    const char* host = "aoatech.ml";

    WiFiServer server(3000);
    int light1 = 13;
    int light2 = 15;
    int fan = 12;
    int socket = 14;
    String what;
    int which;
    String mac;

    void setup() {
      Serial.begin(115200);
      delay(10);
      pinMode(light1, OUTPUT);
      pinMode(light2, OUTPUT);
      pinMode(fan, OUTPUT);
      pinMode(socket, OUTPUT);
      digitalWrite(light1, 0);
      digitalWrite(light2, 0);
      digitalWrite(fan, 0);
      digitalWrite(socket, 0);
      Serial.print("Connecting to: ");
      Serial.print(ssid);
      WiFi.begin(ssid, password);
      Serial.println("Connecting");
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected");
      server.begin();
      Serial.println("Server started");
      Serial.println(WiFi.localIP());
    }

    void loop() {
      WiFiClient client = server.available();
      if (!client) {
        return;
      }
      Serial.print("Connecting to ");
      Serial.println(host);
      //  const int httpPort = 3000;
      //  if (!client.connect(host, httpPort)) {
      //    Serial.println("Connection failed!");
      //    return;
      //  }
      mac = WiFi.macAddress();
      Serial.println("new client");
      while(!client.available()){
        delay(1);
      }
      String req = client.readStringUntil('\r');
      Serial.println(req);
      client.flush();
      int val;
      if (req.indexOf("/light1/1") != -1){
        val = 1;
        what = "Light_1";
        which = light1;
      }
      else if (req.indexOf("/light1/0") != -1){
        val = 0;
        what = "Light_1";
        which = light1;
      }
      else if (req.indexOf("/light2/1") != -1){
        val = 1;
        what = "Light_2";
        which = light2;
      }
      else if (req.indexOf("/light2/0") != -1){
        val = 0;
        what = "Light_2";
        which = light2;
      }
      else if (req.indexOf("/fan/1") != -1){
        val = 1;
        what = "Fan";
        which = fan;
      }
      else if (req.indexOf("/fan/0") != -1){
        val = 0;
        what = "Fan";
        which = fan;
      }
      else if (req.indexOf("/socket/1") != -1){
        val = 1;
        what = "Socket";
        which = socket;
      }
      else if (req.indexOf("/socket/0") != -1){
        val = 0;
        what = "Socket";
        which = socket;
      }
      else {
        Serial.println("invalid request");
        client.stop();
        return;
      }

      digitalWrite(which, val);

      String url = "http://aoatech.ml/hitthis.php?room=Bed Room 1";
      url += "&state=";
      url += val;
      url += "&button=";
      url += what;
      url += "&mac=";
      url += mac;

      Serial.print("Requesting URL: ");
      Serial.println(url);

      client.flush();
      //  client.println("HTTP/1.1 200 OK");
      //  client.println("Content-Type: text/html");
          client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
      unsigned long timeout = millis();
      while (client.available() == 0) {
        if (millis() - timeout > 5000) {
          Serial.println(">>> Client Timeout !");
          client.stop();
          return;
        }
      }
      client.println("");
      client.print(what + " is now: ");

      if(val == 0) {
        client.print("Off");
      } else {
        client.print("On");
      }
      Serial.println("Client disonnected");
    }

title: ESP8266 not accessing PHP file

Answers: 2

body: Your PHP server has a certain content type it can receive to process your requests from the ESP8266. The two most generic content-types used for php are either application/x-www-form-urlencoded or multipart/form-data. Try to play with those two and see if that solves it for you.

body:
You mixed WiFiServer and client request examples by replacing servers HTTP response text with a HTTP request text. A client object returned by WiFiServer's `available` function is a counterpart of requesting client (for example web browser).

See WebClient example for a client connecting to some server.


body:
I, being new to Arduino started off by making a simple lcd watch which also shows the temperature.

Everything was working fine untill this error came up
**"a function-definition is not allowed here before '{' token
"**

And I have done everything to resolve the problem. I wrote the function from scratch. I read somewhere that a function definition can't come within  a function, so I made it a Global function(though, personally I somehow don't feel that it's true). But even then the error managed to survive.

Being completely frustrated I don't know what to do. Can anyone please help me out ?

here's my code :-

    #include < LiquidCrystal.h >

      const int rs = 12,
        en = 11,
        d4 = 5,
        d5 = 4,
        d6 = 3,
        d7 = 2,
        lm = A0;
    int input;
    float temp;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    void tem() //Calculates Temperature
    {
      int i = analogRead(lm);
      float temp = 500.0 * i / 1024;

      lcd.print("Temp : ");
      lcd.print(temp);
      lcd.print(" ^C");

    }

    void Clock(int h = 0, int m = 0, int s = 0, char ch = 'A') {
      int H = h;

      char ampm = ch;

      void mornight(char ampm) //changes am to am to pm and vice versa
      { //THE RED HIGHLIGHTED ERROR LINE
        String AMPM;
        if (ampm == 'A')
          AMPM = "PM";
        else
          AMPM = "AM";

      }
      while (H != 12) //HOUR'S LOOP
      {
        for (int M = m; M <= 59; M++) //MINUTE'S LOOP
        {
          for (int S = s; S <= 59; S++) //SECOND'S LOOP
          {
            delay(1000);
            lcd.clear();

            if (H < 10) {
              lcd.print('0');
              lcd.print(H);
              lcd.print(':');
            } else {
              lcd.print(H);
              lcd.print(":");
            }
            if (M < 10) {
              lcd.print('0');
              lcd.print(M);
              lcd.print(':');
            } else {
              lcd.print(M);
              lcd.print(":");
            }
            if (S < 10) {
              lcd.print('0');
              lcd.print(S);
              lcd.print(AMPM);
            } else {
              lcd.print(S);
              lcd.print(AMPM);
            }
            lcd.setCursor(0, 1);
            tem(); // shows temperature

          }
          s = 0;
        }
        m = 0;
        if (H == 23) {
          H = 1;
          mornight(ampm);
        } else
          H++;
      }
    }

    void setup() {
      lcd.begin(16, 2);
      lcd.setCursor(0, 1);
      Clock(10, 1, 20);

    }
    void loop() {

    }

title: not able to resolve "a function-definition is not allowed here before '{' token "

Answers: 2

body:
Your line:

    void mornight(char ampm)

Is trying to define a function called `mornight()` inside of `Clock()`.

Functions are "global" if they are defined outside of any other function. I can't see what you tried in order to make this function global, but besides object-oriented programming, plain functions are always global.

A "non-global" function would mean defining a class and declaring the function inside the class definition; but even then you have to define the function (that is, the actual instructions in the function) outside of any other class or function definition.

body:
Move function `void mornight(char ampm)` outside of function `void Clock(int h = 0, int m = 0, int s = 0, char ch = 'A') {`

as the error message says, function can't be defined inside functions


body:
I need a way to both ID (a sketch/compiled hex) and later on, identify based on this ID the project that got uploaded to my Arduino microcontroller. As of right now, I have explored multiple options for storing the ID and reading the ID from the Arduino. The ID would be a custom string or later on multiple strings. Here are the 3 options I have been thinking about with their pros and cons:

----------

**Option 1:**

**Writing:** A custom function that would be added to every sketch before compilation, containing the ID information and a serial connection setup

**Reading:** The function would dump the ID over the serial connection using a fixed baud, after this, the projects original serial and baud would be initialized. The microcontroller would need to be rebooted in order for the user to be able to read the ID from it.

**Pros:** Easy to implement.

**Cons:** Would require manual or software restart of the microcontroller in order to read the ID

----------

**Option 2:**

**Writing:** writing the ID to the EEPROM

**Reading:** reading the ID from the EEPROM over the serial connection.

**Pros:** Would probably not interference with the original code

**Cons:** it wears the EEPROM, it might need its own function in the sketch to read the ID from the EEPROM thus making it a complicated Option1.

----------

**Option 3:** Editing the HEX file to include a signature

**Writing:** add the ID to the hex file itself (hex editing), after compiling it.

**Reading:** dumping the hex file and decoding the string.

**Pros:** No baud or serial needed to be set?

**Cons:** Probably slow, can end up producing a bad hex file, hard to implement properly with larger ID-s and structures

----------
Example data:

`project="marlin2.1",
config="prusa",
version="8.80",
env1="pin2"`

As said, the basic idea is storing an ID but I would late want to expand this and store more information like a struct.  This solution should be able to Target as many Arduino models as possible. I am looking for the best way that I might have missed to achieve this task or any recommendations.

title: Writing and reading an ID to/from an Arduino reliably

Answers: 1

body:
I'd go with #2. If you are concerned that you will eventually burn-out your EEPROM (100.000 **write** cycles per ATmega328 ds), try writing a macro, which will dictate at which upload you want new ID to be written in EEPROM.
Heck, instead of writing all of these onboard, why don't you maintain an offline lookup database and encode things yourself? It would still require writing to EEPROM but you could encode your information in a couple of ints.


body:
I am a beginner in Arduino, coding, and electrical engineering (learning on my own time) and am working on creating an EEG. I've got the hardware down and have managed to get numerical data output from the analog (A0) of Arduino. The next step is transforming these numbers to outputting dominant frequency and I have managed to find a code that uses FFT to find the dominant frequency from the input of A0. The following is the code:

    #include "arduinoFFT.h"

    #define SAMPLES 128             //Must be a power of 2
    #define SAMPLING_FREQUENCY 1000 //Hz, must be less than 10000 due to ADC

    arduinoFFT FFT = arduinoFFT();

    unsigned int sampling_period_us;
    unsigned long microseconds;

    double vReal[SAMPLES];
    double vImag[SAMPLES];

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

    sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
    }

    void loop() {

    /*SAMPLING*/
    for(int i=0; i<SAMPLES; i++)
    {
        microseconds = micros();    //Overflows after around 70 minutes!

        vReal[i] = analogRead(0);
        vImag[i] = 0;

        while(micros() < (microseconds + sampling_period_us)){
        }
    }

    /*FFT*/
    FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
    double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);

    /*PRINT RESULTS*/
    Serial.println(peak);     //Print out what frequency is the most dominant.

    for(int i=0; i<(SAMPLES/2); i++)
    {
        /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/

        //Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
        //Serial.print(" ");
        //Serial.println(vReal[i], 1);    //View only this line in serial plotter to visualize the bins
    }

    delay(1000);  //Repeat the process every second OR:
    //while(1);       //Run code once
}

The problem I have is with the line microseconds = micros(). The comment state that this will overflow after 70 minutes and after some days of research, I sorta understand what is meant by this. However, I need this program to run over 9 hours, so I can log the dominant frequency of the brainwave throughout the night. Is that possible?

title: Getting FFT arduino code to run over 9+ hours, utilizing micros()

Answers: 2

body:
Chris Do, there is indeed a rollover problem when `micros` is used that way. When that happens, the samples are taken at full speed without interval. That will create bad data for the FFT.
The solution is in the [Blink Without Delay][1] example. The magic to avoid a rollover problem is the substraction with two `unsigned long` values.

The [arduinoFFT library][2] is in the Library Manager of the Arduino IDE.
The example "[FFT_03.ino][3]" uses `micros` in the wrong way.

The next sketch shows how to avoid the rollover problem:

    // Use micros() without rollover problem for a fixed sample rate
    // for a certain amount of samples.

    #define SAMPLES 128

    unsigned long previousMicros;
    const unsigned long intervalMicros = 1000UL;   // 1000 Hz is 1000 us

    float vReal[SAMPLES];
    float vImag[SAMPLES];

    void setup() {
    }

    void loop() {

      previousMicros = micros();  // set the previousMicros just before entering the for-statement
      for(int i=0; i<SAMPLES; i++) {

        // A while-statement to wait.
        // Note that the ';' at the end means 'do nothing'.
        while( micros() - previousMicros < intervalMicros);

        // The 'previousMicros' is increased with a fixed number, for a fixed sample rate.
        previousMicros += intervalMicros;  // for next interval

        vReal[i] = float(analogRead(0));
        vImag[i] = 0.0;
      }

      delay(1000);
    }

Take the current value of `micros` and substract the previous value of micros. The result of that substraction is a valid number, even during a rollover. It is the only way that always works.

The line to calculate the sample period has too many things in it that can go wrong. These lines:

    unsigned int sampling_period_us;
    sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));

In my example, I set the `intervalMicros` to a certain number. Could you do that as well? When everything works, you can try to calculate it.

Added: The answer by Edgar Bonet is exactly the same. That is no surprise because there is no other way.

  [1]: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
  [2]: https://github.com/kosme/arduinoFFT
  [3]: https://github.com/kosme/arduinoFFT/blob/master/Examples/FFT_03/FFT_03.ino

body:
As long as you never compare timestamps, [the rollover is not an
issue][rollover]. The idiom you used:

    while (micros() < previous_timestamp + period) ...

is comparing two timestamps. This is incorrect, and it fails whenever
`micros()` rolls over. However, subtracting timestamps to get a duration
does work fine across rollover events. And comparing durations does
always work. So the correct idiom is:

    while (micros() - previous_timestamp < period) ...

Note also that the way you update `microseconds` is incorrect. You are
incrementing it by the period you want **plus** the time taken by the
CPU to execute some of the code in the loop. You should instead
increment it by the requested period and no more. Here is my take at
what you are trying to accomplish:

    /* SAMPLING */
    microseconds = micros();  // record initial time
    for (int i = 0; i < SAMPLES; i++) {
        while (micros() - microseconds < sampling_period_us)
            ;  // wait for the right time to take the sample
        microseconds += sampling_period_us;  // update as per the period
        vReal[i] = analogRead(0);
        vImag[i] = 0;
    }

[rollover]: https://arduino.stackexchange.com/q/12587


body:
I'd like to control some digital ICs with a ESP8266-12.

1. How can I switch 2 pins to HIGH in the same moment?
2. How can I switch one to LOW and the other to HIGH in the same moment?
3. Is it possible with every port or only with grouped ports and how are the groups?

title: Switch two or more digital outputs of ESP8266 at the same time

Answers: 1

body:
See the datasheet: [esp8266-technical_reference_en][1]

Paragraph 2.2.2 shows how to use the output registers.

With the registers GPIO_OUT, GPIO_OUT_W1TS and GPIO_OUT_W1TC you can set or clear multiple GPIOs.

  [1]: https://www.espressif.com/sites/default/files/documentation/esp8266-technical_reference_en.pdf


body:
I want to power up my Arduino and my Nodemcu via 12 V , 1 A power adapter (it's an AC to DC power Adapter).

Recently I have two voltages regulators: a 5 V for nodemcu and 9 V for Arduino Uno.

The question is does the 1A affect both boards or not?

title: Powering arduino and node mcu

Answers: 1

body:
In principle not. However, the voltage regulators may become quite hot, since you are going down from 12 V to 9 V and 5 V (especially the step from 9 V to 5 V is quite a lot). It depends on the current (in (milli)Amps) how hot they get.

For the adapter it does not matter, if it is 1 A or 10 A, the microcontrollers will only take whatever they need. Only if the adapter can deliver less than needed by both microcontrollers there is a problem.

The voltage regulators are not of switching type I guess, so they will use the same amount of amperes. Assuming the Arduino Uno takes 300 mA (at 5 V) and the NodeMCU 200 mA (at 12 V), you can add them together: 200 mA + 300 mA = 500 mA. Since this is less than 1 A the adapter can deliver, you are ok.


body: I'm making a midi controller with the Arduino uno. It contains approximately 50 analog inputs with potentiometers. I have enough MCP3008 adc's here but I have no idea how I connect 2 or more adc's to the Arduino so that I can read 50. How do you stack adc's?

title: Stacking adc's when making an midi controller ( lots of potmeters)

Answers: 2

body:
These ADC's use the SPI protocol. Luckily the Arduino has one onboard.

With each ADC you get 8 channels (thus inputs). Since you need more than one SPI device (ADC in your case).

With SPI you can chain multiple SPI devices to your SPI port of the Arduino. To select which is active you use the Chip/Slave select signal. This is a separate GPIO you can define yourself. Read more about SPI to read details.

For 50 inputs you need 50 / 8, rounded up is 7 ADCs. This means also 7 CS pins. Thus in total you need 3 (for SPI) + 7 = 10 pins. I hope you have that many left.

About 'stacking', just put the ADC's on a breadboard and wire them according to the SPI protocol.

See also [Arduino Reference SPI][1]

  [1]: https://www.arduino.cc/en/Reference/SPI

body:
With SPI the SCK, MISO, MOSI are connected in parallel to all devices. The device with the active low Chip Select pin is the one that receives a command and then sends data, the others ignore what is happening.  You can also load data into a shift register to create the chip selects, thus only 4 pins are needed: SCK (13), MISO (12), MOSI (11), to all the devices, and use D10, the SS pin, as the latch pin (SRCK) into a 74HC595 for the 7 chip selects out to the MCP3008s.

The code to loop can be pretty simple.

    for (pin = 0; pin <7; pin = pin +1){
      digitalWrite (csPin[pin], LOW); // select a device
      SPI.transfer(startByte); // send out start byte
      upperBits[pin + address] = SPI.transfer(addressByte [address]); // send out address, read in D9, D8
      lowerBits[pin + address] = SPI.transfer(0);  // send out don't care read in D7-D0
      digitalWrite (csPin [pin), HIGH); // deselect a device

      digitalWrite (csPin[pin], LOW); // select a device
      SPI.transfer(startByte); // send out start byte
      upperBits[pin + address+1] = SPI.transfer(addressByte [address+1]); // send out address, read in D9, D8
      lowerBits[pin + address+1] = SPI.transfer(0);  // send out don't care read in D7-D0
      digitalWrite (csPin [pin), HIGH); // deselect a device

      digitalWrite (csPin[pin], LOW); // select a device
      SPI.transfer(startByte); // send out start byte
      upperBits[pin + address+2] = SPI.transfer(addressByte [address+2]); // send out address, read in D9, D8
      lowerBits[pin + address+2] = SPI.transfer(0);  // send out don't care read in D7-D0
      digitalWrite (csPin [pin), HIGH); // deselect a device

      digitalWrite (csPin[pin], LOW); // select a device
      SPI.transfer(startByte); // send out start byte
      upperBits[pin + address+3] = SPI.transfer(addressByte [address+3]); // send out address, read in D9, D8
      lowerBits[pin + address+3] = SPI.transfer(0);  // send out don't care read in D7-D0
      digitalWrite (csPin [pin), HIGH); // deselect a device

      digitalWrite (csPin[pin], LOW); // select a device
      SPI.transfer(startByte); // send out start byte
      upperBits[pin + address+4] = SPI.transfer(addressByte [address+4]); // send out address, read in D9, D8
      lowerBits[pin + address+4] = SPI.transfer(0);  // send out don't care read in D7-D0
      digitalWrite (csPin [pin), HIGH); // deselect a device

      digitalWrite (csPin[pin], LOW); // select a device
      SPI.transfer(startByte); // send out start byte
      upperBits[pin + address+5] = SPI.transfer(addressByte [address+5]); // send out address, read in D9, D8
      lowerBits[pin + address+5] = SPI.transfer(0);  // send out don't care read in D7-D0
      digitalWrite (csPin [pin), HIGH); // deselect a device

      digitalWrite (csPin[pin], LOW); // select a device
      SPI.transfer(startByte); // send out start byte
      upperBits[pin + address+6] = SPI.transfer(addressByte [address+6]); // send out address, read in D9, D8
      lowerBits[pin + address+6] = SPI.transfer(0);  // send out don't care read in D7-D0
      digitalWrite (csPin [pin), HIGH); // deselect a device

      digitalWrite (csPin[pin], LOW); // select a device
      SPI.transfer(startByte); // send out start byte
      upperBits[pin + address+7] = SPI.transfer(addressByte [address+7]); // send out address, read in D9, D8
      lowerBits[pin + address+7] = SPI.transfer(0);  // send out don't care read in D7-D0
      digitalWrite (csPin [pin), HIGH); // deselect a device

    }

The end result are two 56 byte arrays, upperBits[] and lowerBits[], combine a byte from each for a reading per channel.

I do have a lot of duplicate code there that could likely be reduced to a loop within a loop to remove the redundancy.

'address' could come from an array also, as the data needs to be 0b10000000, 0b10010000, 0b10100000, 0b10110000, 0b11000000, 0b11010000, 0b11100000, 0b11110000

or start with address = 0x80 and add 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70

That code has to integrate to drive the shift register, which I forgot about, so instead of

    digitalWrite (csPin[pin], LOW);
    and
    digitalWrite (csPin[pin], HIGH);

you'd have

    digitalWrite (shiftRegisterLatch, LOW); // first MCP3008 CS low
    SPI.transfer(0b11111110);
    digitalWrite (shiftRegisterLatch, HIGH); //first MCP3008 CS low
    // read from ADC0 on first MCP3008 using SPI.transfers above
    digitalWrite (shiftRegisterLatch, LOW); // first MCP3008 CS high
    SPI.transfer(0b11111111);
    digitalWrite (shiftRegisterLatch, HIGH); //first MCP3008 CS high

Repeat for channels ADC1 to ADC7

Then go to the next device:

    digitalWrite (shiftRegisterLatch, LOW); // 2nd MCP3008 CS low
    SPI.transfer(0b11111101);
    digitalWrite (shiftRegisterLatch, HIGH); //2nd MCP3008 CS low
    // read from ADC0 on second MCP3008 using SPI.transfers above
    digitalWrite (shiftRegisterLatch, LOW); // 2nd MCP3008 CS high
    SPI.transfer(0b11111111);
    digitalWrite (shiftRegisterLatch, HIGH); //2nd MCP3008 CS high

So the data could be in an array as well: 0b11111110, 0b11111101, 0b11111011, 0b11110111, 0b11101111, 0b11011111, 0b10111111, with 0b11111111 to turn off CS

I'd be using direct port manipulation as well instead of digitalWrite() to speed up latching data into the shift register.


body:
I have recently been trying to send integers via SPI between two arduino Uno's. I am using the first example of Nick Gammons tutorial, and trying to modify it to get a basic understanding of how to communicate via SPI.

http://www.gammon.com.au/spi

MASTER

    // Written by Nick Gammon
    // February 2011

    #include <SPI.h>

    void setup (void)
    {

      digitalWrite(SS, HIGH);  // ensure SS stays high for now

      // Put SCK, MOSI, SS pins into output mode
      // also put SCK, MOSI into LOW state, and SS into HIGH state.
      // Then put SPI hardware into Master mode and turn SPI on
      SPI.begin ();

      // Slow down the master a bit
      SPI.setClockDivider(SPI_CLOCK_DIV8);

    }  // end of setup

    void loop (void)
    {

      char c;

      // enable Slave Select
      digitalWrite(SS, LOW);    // SS is pin 10

      // send test string
      for (const char * p = "Hello, world!\n" ; c = *p; p++)
        SPI.transfer (c);

      // disable Slave Select
      digitalWrite(SS, HIGH);

      delay (1000);  // 1 seconds delay
    }  // end of loop
SLAVE - WITHOUT INTERRUPTS

    // Written by Nick Gammon
    // February 2011

    #include <SPI.h>

    char buf [100];
    volatile byte pos;
    volatile boolean process_it;

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

      // turn on SPI in slave mode
      SPCR |= bit (SPE);

      // have to send on master in, *slave out*
      pinMode(MISO, OUTPUT);

      // get ready for an interrupt
      pos = 0;   // buffer empty
      process_it = false;

      // now turn on interrupts
      SPI.attachInterrupt();

    }  // end of setup

    // SPI interrupt routine
    ISR (SPI_STC_vect)
    {
    byte c = SPDR;  // grab byte from SPI Data Register

      // add to buffer if room
      if (pos < (sizeof (buf) - 1))
        buf [pos++] = c;

      // example: newline means time to process buffer
      if (c == '\n')
        process_it = true;

    }  // end of interrupt routine SPI_STC_vect

    // main loop - wait for flag set in interrupt routine
    void loop (void)
    {
      if (process_it)
        {
        buf [pos] = 0;
        Serial.println (buf);
        pos = 0;
        process_it = false;
        }  // end of flag set

    }  // end of loop

SLAVE - WITH INTERRUPTS

    // Written by Nick Gammon
    // April 2011

    // what to do with incoming data
    byte command = 0;

    // start of transaction, no command yet
    void ss_falling ()
    {
      command = 0;
    }  // end of interrupt service routine (ISR) ss_falling

    void setup (void)
    {

      // have to send on master in, *slave out*
      pinMode(MISO, OUTPUT);

      // turn on SPI in slave mode
      SPCR |= _BV(SPE);

      // turn on interrupts
      SPCR |= _BV(SPIE);

      // interrupt for SS falling edge
      attachInterrupt (0, ss_falling, FALLING);

    }  // end of setup

    // SPI interrupt routine
    ISR (SPI_STC_vect)
    {
      byte c = SPDR;

      switch (command)
      {
      // no command? then this is the command
      case 0:
        command = c;
        SPDR = 0;
        break;

      // add to incoming byte, return result
      case 'a':
        SPDR = c + 15;  // add 15
        break;

      // subtract from incoming byte, return result
      case 's':
        SPDR = c - 8;  // subtract 8
        break;

      } // end of switch

    }  // end of interrupt service routine (ISR) SPI_STC_vect

    void loop (void)
    {
    // all done with interrupts
    }  // end of loop

ORIGINAL ISSUE - I am able to get this working, so the wiring is correct, however i am unable to get it to send anything other than a string. I can change the string and that works, but i am getting confused with pointers in C. Any code i have tried doesn't compile correctly, or doesn't send at all if it does compile. Could someone give me a clue as to where to start with this. My best effort is below

MASTER

    #include <SPI.h>

    int x = 10000;
    int y = 20000;
    int z = 30000;
    byte High_x = highByte(x);
    byte Low_x = lowByte(x);
    byte High_y = highByte(y);
    byte Low_y = lowByte(y);
    byte High_z = highByte(z);
    byte Low_z = lowByte(z);

    int X =  word(High_x<<8|Low_x);
    int Y =  word(High_y<<8|Low_y);
    int Z =  word(High_z<<8|Low_z);

      byte myArray[7];

    void setup (void)
    {

      Serial.begin(115200);
      digitalWrite(SS, HIGH);  // ensure SS stays high for now

      // Put SCK, MOSI, SS pins into output mode
      // also put SCK, MOSI into LOW state, and SS into HIGH state.
      // Then put SPI hardware into Master mode and turn SPI on
      SPI.begin ();

      // Slow down the master a bit
      SPI.setClockDivider(SPI_CLOCK_DIV8);

     myArray[0] = High_x;
     myArray[1] = Low_x;
     myArray[2] = High_y;
     myArray[3] = Low_y;
     myArray[4] = High_z;
     myArray[5] = Low_z;
     myArray[6] = 0;

      Serial.println(X);
      Serial.println(Y);
      Serial.println(Z);
      delay(2000);
    }

    void loop (void)
    {

      byte data;

      // enable Slave Select
      digitalWrite(SS, LOW);    // SS is pin 10

      // send test string
      for (byte * p =  myArray[0]; data = *p; p++)
        SPI.transfer (data);
        Serial.println("sending data");

      // disable Slave Select
      digitalWrite(SS, HIGH);

      delay (1000);  // 1 seconds delay
    }  // end of loop

SLAVE

    #include <SPI.h>

    byte buf [100];
    volatile byte pos;
    volatile boolean process_it;

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

      // turn on SPI in slave mode
      SPCR |= bit (SPE);

      // have to send on master in, *slave out*
      pinMode(MISO, OUTPUT);

      // get ready for an interrupt
      pos = 0;   // buffer empty
      process_it = false;

      // now turn on interrupts
      SPI.attachInterrupt();
    Serial.println("End of Setup");
    }  // end of setup

    // SPI interrupt routine
    ISR (SPI_STC_vect)
    {
      Serial.println("Beginning of Interrupt Routine");
    byte data = SPDR;  // grab byte from SPI Data Register

      // add to buffer if room
      if (pos < (sizeof (buf) - 1))
        buf [pos++] = data;

      // example: newline means time to process buffer
      if (data == '0')
        process_it = true;
          Serial.println("End of Interrupt Routine");
    }  // end of interrupt routine SPI_STC_vect

    // main loop - wait for flag set in interrupt routine
    void loop (void)
    {
        Serial.println("Beggining of Loop");

      for(int i = 0; i < 100; i++)
      if (process_it)
        {
        buf [pos] = 0;
        Serial.println (buf[i]);
        pos = 0;
        process_it = false;
        }  // end of flag set
        Serial.println("End of Loop");
    }  // end of loop

In the future i hope to send 10 16-bit integers over SPI from an arduino to an arduino or maybe arduino to a raspberry Pi.

Thanks

EDIT -I have started using the code that uses interrupts and managed to get the data i need sent across, however, i can only get the correct data by setting both the first and second element of the array to "High_x", otherwise it skips the first part of data?

NEW MASTER

    #include <SPI.h>

    int x = 10000;
    int y = 20000;
    int z = 30000;
    byte High_x = highByte(x);
    byte Low_x = lowByte(x);
    byte High_y = highByte(y);
    byte Low_y = lowByte(y);
    byte High_z = highByte(z);
    byte Low_z = lowByte(z);

    int X =  word(High_x<<8|Low_x);
    int Y =  word(High_y<<8|Low_y);
    int Z =  word(High_z<<8|Low_z);

      byte myArray[8];

    void setup (void)
    {

      digitalWrite(SS, HIGH);  // ensure SS stays high for now

      // Put SCK, MOSI, SS pins into output mode
      // also put SCK, MOSI into LOW state, and SS into HIGH state.
      // Then put SPI hardware into Master mode and turn SPI on
      SPI.begin ();

      // Slow down the master a bit
      SPI.setClockDivider(SPI_CLOCK_DIV8);

     myArray[0] = High_x;
     myArray[1] = High_x;
     myArray[2] = Low_x;
     myArray[3] = High_y;
     myArray[4] = Low_y;
     myArray[5] = High_z;
     myArray[6] = Low_z;
     myArray[7] = 0;

      Serial.print("wait for loop");
      //Serial.println(X);
      //Serial.println(Y);
      //Serial.println(Z);
      delay(2000);
    }

    void loop (void)
    {

      byte data;

      // enable Slave Select
      digitalWrite(SS, LOW);    // SS is pin 10

      // send test string
      for (byte * p =  &myArray[0]; data = *p; p++){
        SPI.transfer (data);
      }
      // disable Slave Select
      digitalWrite(SS, HIGH);

      delay (1000);  // 1 seconds delay
    }  // end of loop

NEW SLAVE

    byte buf [100];
    volatile byte pos;
    // what to do with incoming data
    byte command = 0;

    // start of transaction, no command yet
    void ss_falling ()
    {
      command = 0;
    }  // end of interrupt service routine (ISR) ss_falling

    void setup (void)
    {

      Serial.begin(9600);

      // have to send on master in, *slave out*
      pinMode(MISO, OUTPUT);

      // turn on SPI in slave mode
      SPCR |= _BV(SPE);

      // turn on interrupts
      SPCR |= _BV(SPIE);

      // interrupt for SS falling edge
      attachInterrupt (0, ss_falling, FALLING);

    }  // end of setup

    // SPI interrupt routine
    ISR (SPI_STC_vect)
    {
      byte data = SPDR;

      // add to buffer if room
      if (pos < (sizeof (buf) - 1))
        buf [pos++] = data;

    }  // end of interrupt service routine (ISR) SPI_STC_vect

    void loop (void)
    {

      for(int i = 0; i < 100; i++){

        Serial.println (buf[i]);
        pos = 0;
        delay(1000);
      }
    }  // end of loop

Any suggestions on why this is necessary? Is there some basic SPI idiosyncrasy I'm missing?

Thanks all

Ross

title: send more than one byte at a time SPI Arduino

Answers: 2

body:
You have a couple of issues going on here.

First of all, Nick Gammon's example is transmitting strings. Strings have the property that a particular value, `'\0'` (null), cannot normally appear in the string itself, and it can therefore be used as an "end flag" to mark the end of the string. This is why the `for` loop on the master side works correctly.

Note that the null itself is NOT transmitted over the SPI link. Instead, Nick shows an example of using another character (`'\n'` - newline) to trigger processing on the slave side.

If you want to transmit binary data, which could easily contain bytes of 0x00 (null), you need to find a different way to delimit the data on both the sending side and the receiving side. Your example data (16-bit integers of 10000, 20000 and 30000) doesn't contain any null bytes, but you can't rely on that in general. Also, because the null doesn't actually get transmitted, you can't use it on the receiving side to trigger processing.

There are a couple of approaches that are frequently used to send binary data:

- Send the number of bytes explicitly at the beginning of the transaction, and trigger receive-side processing once that number of bytes has been received.

- Use a "special" value (e.g., null) to mark the end of the data, but then you have to "escape" that value in some way if it ever appears in the actual data.

---

In addition to all of that, you have a bug on your master side code. The initialization of your `for` loop, `byte * p =  myArray[0]` does not set the pointer `p` to the address of `myArray` as intended; instead, it sets it to the value of the first byte in the array, which is 0x27 (`High_x`). You need to say either `byte * p =  &myArray[0]` or simply `byte * p =  myArray`.

body:
I can see two big problems at your code (there could be more, but i didnt look that hard).

First is using Serial.println in interrupt routine. This prevent receiving of more than one byte as Serial.println will take much more time to execute than receiving 6 bytes (even on slow SPI clock) on SPI. In most cases Interrupt routines should finish fast.

Next problem is that you are testing for char 0 ('0') which is not equal to byte 0 you are sending as end of data, but has value of 48 in decimal.

Edit for how to test for end of data:

You can test for end of that few different ways, having fixed number of byte transfers, setting interrupt on slave select pin or encode data binary data in base64 and use control char. I would recommend interrupt.


body:
I was trying to run [this library][1] on Arduino Mega, using ESP8266 as replacement of Wifi Shield, [as suggested on my older thread.][2]

The problem is, I got error in compiling, after with this code :

    #include <WiFiEsp.h>
    #include <WiFiEspClient.h>
    #include <WiFiEspUdp.h>

    #include "AppleMidi.h"
    APPLEMIDI_CREATE_INSTANCE(WiFiUDP, appleMIDI1);
    ....

> exit status 1

> 'WiFiUDP' was not declared in this scope

if I modified the code into this :

    #include <WiFiEsp.h>
    #include <WiFiUdp.h>

    #include "AppleMidi.h"
    APPLEMIDI_CREATE_INSTANCE(WiFiUDP, appleMIDI1);
    ....

I got this error instead

> C:\Program Files
> (x86)\Arduino\libraries\WiFi\src\utility\server_drv.cpp:313:40: error:
> 'WARN' was not declared in this scope
>
>     WARN("error waitResponse isDataSent");
>
>                                         ^
>
> exit status 1

Full code [here at pastebin.][3]
I was pretty much stuck now. Please help! :(

Thanks :D

  [1]: https://github.com/lathoub/Arduino-AppleMIDI-Library
  [2]: https://arduino.stackexchange.com/questions/55753/is-there-any-easy-way-to-change-arduino-wifi-shield-to-esp8266
  [3]: https://pastebin.com/K8b5J726

title: Using WifiUdp.h on Arduino Mega and ESP8266?

Answers: 1

body:
the WiFiEsp class for UDP is `WiFiEspUDP`

    #include <WiFiEsp.h>
    #include <WiFiEspUdp.h>
    #include "AppleMidi.h"

    APPLEMIDI_CREATE_INSTANCE(WiFiEspUDP, AppleMIDI);


body:
So, I'm trying to read the voltage on analog pin A0 and make a "regulation", where if the voltage will be lower than 2.5V (analog value 512), then it should be output pin 9 used as PWM with duty cycle of 50% ( analogWrite(ledPin, 128); ) unless the voltage rises again higher than 2.5V.

Where/how am I supposed to use mentioned line ( analogWrite(ledPin, 128); in IF sentence, so it will be used continuous untill it is reached the limit?

PS: I just want to refresh LCD with frequency of 1 Hz while PWM works independently of delay(1000). How is that even possible?

How am I able to do that?

    #include <LiquidCrystal.h>

    const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    const int numRows = 2;
    const int numCols = 16;

    void setup() {
      lcd.begin(numCols, numRows);
    }

    void loop() {

        int sensorValue = analogRead(A0);
        float voltage = sensorValue * (5.0 / 1023.0);
            lcd.setCursor(0, 0);
            lcd.write(voltage);

            delay(1000);
    }

title: Using delay(1000); without influence on analogWrite?

Answers: 3

body:
You don't need an if-statement here. You can simply contineously take the measurements and act accordingly.

About the `delay(1000)`:

It is considered a bad coding practice to use `delay()`, especially for longer periods, because it's just busy waiting. In real life you wouldn't just sit fiddling your thumbs, until a task is done. You would do something else in the intermediate time. Here you can reach this by using non-blocking code like in the [`BlinkWithoutDelay`](https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay) example of the Arduino IDE.

About PWM:

PWM is not handled by the software, but by the hardware. The Atmega on the Arduino has dedicated PWM hardware included in the package, which will handle the control of the PWM pin, so that the CPU can do other things.

body:
I think you need something like this, with a flag so you are not contantly restarting the PWM on pin 8 and making the output erratic:

    void loop(){
    if (analogRead(A0)<512  && halfLevel9 == 0){
    analogWrite (9, 128);
    halfLevel9 = 1; // flag to let you know it's been set
    }
    else {
    analogWrite (9, withWhat?);
    halfLevel9 = 0;
    }
    // use blink without delay to determine if 1 second has passed
    {
    // write whatever is going to the LCD
    }
    // do other stuff while the 1 second passes
    }

body: The PWM started by `analogWrite` will not be influenced be the `delay`, because the analogWrite function only sets the registers and starts the PWM. The PWM generator is independent from the CPU on AVR microcontrollers. On esp8266 for example the PWM is generated with use of interrupt and it is too not influenced by the `delay` function. To stop the PWM you must call analogWrite with 0 or change the pin mode.


body:
To be able to set the date and time of the files on my SD card I followed this answer: https://arduino.stackexchange.com/a/39127/49678

Now I am wondering **How do I read the values out in the microcontroller?**
To clearify, I get the correct timestamps when I remove the SD card and view them on a PC, but I also want to be able to read this on the microcontroller.

Inside SdFile.cpp on line 1025 there is a function called timestamp which is used to set the timestamp but I cant seem to find any function to read it.
https://github.com/adafruit/SD/blob/master/utility/SdFile.cpp

I would prefer a solution where I don't have to add it to the library myself.

The underlying problem I am facing is that I want to log files, and once the memory is full I which to remove the oldest files.

title: How does one **get** attributes for SD files?

Answers: 2

body:
You need to get an `SdFile` object for your file then use the `SdFile::dirEntry` method to get the directory entry for the file.

The directory entry (`struct directoryEntry`) has the timestamps.

body:
In the FAT filesystem the timestamps and other attributes are stored in the directory, not in the file.  So you need to read the "file" that is the directory that contains the file you're interested in.

That "file" contains entries in a pre-defined structure. Reading each block of data using that structure gives you the information for each file in turn.

You can just do a normal `SD.open(...)` call to open the directory that contains your file, and then read chunks of data from it to get each file entry.

That data is arranged in the `directoryEntry` structure ([here](https://github.com/arduino-libraries/SD/blob/master/src/utility/FatStructs.h#L321)), so reading a block of data with `File.read(...)` into a variable of that structure type will yield your data:

    struct directoryEntry dirent;

    // myDir has already been opened and points at the start of your dir
    while (myDir.read((uint8_t *)&dirent, sizeof(struct directoryEntry))) {

        // Names are tricky to print. Also you should check for deleted files here.
        Serial.print("Name: ");
        for (int i = 0; i < 11; i++) {
            Serial.print(dirent.name[i]);
            if (i == 7) {
                Serial.print(".");
            }
        }
        Serial.println();
        Serial.print("Creation Time: ");
        Serial.println(dirent.creationTime);
        Serial.print("Creation Date: ");
        Serial.println(dirent.creationDate);
    }


body:
i have my esp32 module in deep sleep and i use it with a couple of buttons using a wake up that detect the button pressed
now i'd like to have a battery level to send to a server right before going back to deep sleep. How can i do it?
and what cheap rgb led do you suggest using?

title: Battery voltage monitor right after deep sleep

Answers: 1

body:
Using "battery level" (voltage)  is poor way to monitor its useful life. Battery discharge  characteristic varies with its technology.
On the other hand many electronics devices are very tolerable as far as "supply level " AKA voltage.

RGB LED light intensity can be made to monitor different voltage, however, I fail to see how you propose to send the LED intensity level /state to other device.

Addendum

As I pointed out - the battery useful life depends on technology.
You mentioned AAA , hence I assume alkaline battery.
Then I would suggest software solution.
Let the server monitor the actual running time of your device.Then measure or calculate the load your device is drawing from the battery.
Then determine or calculate the discharge curve of your battery and let the server "output" the battery life / discharged level in relation to time. Perhaps I misunderstood and you actually wanted the RGB LED to be connected to the server. Then you can display green LED up to 80% of battery life and so on ...Keep in mind that the discharge curve is pretty abrupt at the end of battery useful life,


body:
I'm developing a device system in our campus - my aim is to provide three IoT smart garbage containers that will get the fill level (to determine the space of garbage inside and to inform the garbage collector if the garbage is empty, not yet full and full), temperature and humidity from the garbage bin and will send the information to my application that I'm going to develop.

I don't know how I can connect these three IoT devices which are a fair distance from each other. I know it should be wireless though I can't figure out the exact Arduino device to provide connection to my mobile application.

title: IoT gabage monitoring system with my own Android application

Answers: 1

body:
Does your campus have WiFi? If so, go with EPS8266 if its pins are OK for your sensors.
[ESP Pinout][1]

You'd want to keep an eye on power consumption; you'd sample your sensors per desired interval and deep-sleep at all other times. Check out available sleep [here][2]. It also has en example of how to sample and send a sensor, and sleep afterwards.

On the application end, you could either use a ready service such as Blynk, or go for a custom solution and send the data on your server. Of course, you would then need to write an API and some sort of application to present your data.

Let me also point out that for measuring garbage level, you should calculate the total volume of your bin and subtract the volume of garbage your sensor detects. Having non-uniform trash would give you some trouble, but it's a good technique for an estimation of garbage volume. Also, if using ultrasonic distance sensors, given the fact that you have temperature readings available, you should compensate your measurements; check [this][3] out.

  [1]: https://cdn.instructables.com/FJC/J4AP/JH8JBTHA/FJCJ4APJH8JBTHA.LARGE.jpg?auto=webp
  [2]: https://www.losant.com/blog/making-the-esp8266-low-powered-with-deep-sleep
  [3]: https://www.instructables.com/id/Temperature-Compensated-Ultrasonic-Range-Finder-Wi/


body:
Arduino will not recognise USB ports on my Mac running Sierra
I am a teacher who helps teachers to use LilyPad. I used to be able to plug in my LilyPad Arduino and see the USB port. I have read all the answers and dowloaded the drivers from Spark fun and another driver from Github. Nothing is working and i am not technical enough to find the answer myself.  I have spent three hours today trawling through the answers to this problem and still cannot fix it myself. I am a luddite who needs a simple step by step remedy. Apple support had no idea when I rang them and told me it was an Arduino problem and to talk to them. you cant talk to anyone at Arduino you can only go to the forums. the forums tell you to read others answers before you post. I have. it's still not working. i need help. And not a lecture about being on a forum asking dumb questions.[![this is what I see when i look for the port][1]][1]

 I even mucked around in terminal and am hoping it's not a 'terminal" problem because I have no clue what i am doing. If you can explain in plain speak please respond. i have to teach this stuff in 4 days.
[![These are the drivers I downloaded.][2]][2]

This is the message I get when I try to upload a sketch

[![enter image description here][3]][3]

  [1]: https://i.stack.imgur.com/As6bG.png
  [2]: https://i.stack.imgur.com/FCRp9.png
  [3]: https://i.stack.imgur.com/qaYH4.png

Answers: 4

body:
The Lillypad uses the ATMega32U4 chip. This is the same as the Arduino Leonardo and the Arduino Micro, and suffers the same basic issue that they both suffer from.

Basically, the USB connection is driven by the main chip, not by an interface chip as in most other Arduino boards.  This gives you increased flexibility (e.g., using it as a keyboard or a mouse) and decreased cost (less components on the board), but at the additional cost of certain problems that you have to be prepared to resolve.

Because the main chip runs the USB connection that main chip must be working properly for there to even be a USB connection. With other boards that isn't the case - you can remove the main chip completely and the USB interface chip will still work.  So it is perfectly possible to "kill" the board by installing a sketch on it which stops the main chip from functioning. As soon as the main chip stops functioning the USB stops functioning - and if the sketch that is installed never starts working at all then you never see a USB connection.

Sometimes it is possible to get the USB port to appear for a short period (a few seconds) by pressing the reset switch, but you have to time it right (press reset and immediately select the port in the menu, then press upload, and press reset again just *before* the uploading itself starts).

The sure-fire fix, though, is to erase the entire chip (along with your installed "broken" sketch) and reinstall the bootloader using the IDE's tools.  You'll need either a hardware programmer (the USBASP is dirt cheap and easy to get on eBay) or another Arduino using the *ArduinoISP* sketch bundled with the IDE.

If you're going to do any serious work or teaching with any microcontroller-based system it's always good to have a hardware programmer available to help recover from problems, no matter what platform you're working with.  **Remember: if there's a way to break it, kids will find it. And do it.**

body:
I spoke to a very clever friend who has had similar problems. The answer lay in downloading the FTDI helper package not just the driver.  If anyone else is having a similar problem the website is

https://www.ftdichip.com/Drivers/D2XX/MacOSX/D2xxHelper_v2.0.0.pkg

I downloaded it and now my lilypad and USB port is recognised by the Arduino software.

Just in time for Thursday.

Thanks to all who tried to help.

K

body: I had a problem getting my computer (Mac Pro, OS 1.12.1 Sierra) to recognize my Arduino Leonardo and Micro boards. Tried many different fixes, nothing worked. Finally used a different cable, and both boards worked fine. NB: I didn't suspect a cable problem, since I removed the cable from a working device. Just to make things weirder, the original device I removed the cable from worked just fine when I re-installed the (supposedly defective) cable.

body:
I had the same problem: my MacBook Air registered by Arduino Board in the USB Device Tree but it was not showing up in the Ports list of the Arduino IDE. It was resolved when I changed the Privacy and Security setting for Allow Accessories to Connect. When I changed the setting to "Automatically When Unlocked" the Arduino IDE was able to recognize my board.

Route to setting: Apple Logo on top Right -> System Settings -> Privacy and Security -> (scroll down to Security) Allow Accessories to Connect.


body:
UPDATE : I still can't receive MIDI as of 2019/07/01.

Here goes so far : I'm trying to follow this schematics from instructables, using 6N138. To make it easier, I'm going to copy his schematics.
[![enter image description here][1]][1]

===================================

I'm using Arduino Mega. I tried to find specific topic about this and can't find any.

The target is actually send and receive MIDI, then replace the whole Arduino Mega to ESP8266 (probably the ESP-01, or Wemos D1), but I'm afraid it is too specific.

Here's the code so far on PasteBin

Here's my work so far.
[![enter image description here][2]][2]
[![6N138][3]][3]

The diodes were replaced with LED, because I don't have one Original guide here.
But that schematics on that thread also didn't work for some reason.

  [1]: https://i.stack.imgur.com/VmuRr.png
  [2]: https://i.stack.imgur.com/n56Xu.jpg
  [3]: https://i.stack.imgur.com/l6ByZ.jpg

title: How do I properly receive MIDI with Arduino, with 6n138?

Answers: 4

body:
Most start at the [midi site at playground.arduino.cc][1].  But there are numerous web sites across the Internet.  It is important to understand that the [MIDI interface][2] uses a [current loop][3] to send and receive data.  While the Arduino normally uses voltage levels to communicate.  As such, an electronic interface needs to be built or bought to convert between these two types of signals.  [Some interface designs are simple and limited][4].  [Others are complex and robust][5].

  [1]: https://playground.arduino.cc/Main/MIDILibrary
  [2]: https://en.wikipedia.org/wiki/MIDI
  [3]: https://en.wikipedia.org/wiki/Current_loop
  [4]: https://www.instructables.com/id/Custom-Arduino-MIDI-Controller/
  [5]: https://www.sparkfun.com/products/12898

body:
There are plenty of MIDI circuits and most of them are quite simple, mostly an optocoupler (6N137 or 6N138, although I had better luck with H11L1), some resistors and that's mostly it. I also added ferrite beads for EMI protection, but this is not absolutely necessary.

To test your circuit, use a lot of data (e.g. by pitchbend/aftertouch), and play notes meanwhile. If you hear stuck notes (meaning the MIDI Note Off command is missed), you know the circuit is not full proof.

Regarding libraries: the [FortySeven Effects library][1] is really easy to use. I used it in the beginning before I moved on to STM32 and having to write my own, but this is a good starting point.

For the schematics I based my circuit of can be found at [H11L1 optocoupler][2].

The best way is to read the official MIDI documentation, see page [MIDI 1.0 Specification][3], than search for

    Download the Complete MIDI 1.0 Detailed Specification Document (1996)
    (Please Register! It's Free!).

  [1]: https://github.com/FortySevenEffects/arduino_midi_library
  [2]: https://electronics.stackexchange.com/questions/311889/i-cannot-get-opto-coupler-h11l1-to-work-as-midi-input
  [3]: https://www.midi.org/specifications-old/item/the-midi-1-0-specification

body:
How to connect 6N138 to Arduino :

[![enter image description here][1]][1]
Schematics :
[![enter image description here][2]][2]

Basically the above schematics and installation is already okay, but instead of 1k, I used 10k on 6N138 PIN 7 to GND.
VCC to 470 ohm is on PIN 6, also RX out, connected in series.

----------

Just in case you want to use 6N137 :

[![enter image description here][3]][3]

Schematics :
[![enter image description here][4]][4]

Pin 5 of the MIDI DIN connector goes to pin 2 of the 6N137

Pin 4 of the MIDI DIN connector goes via 330 ohm resistor to pin 3 of the 6N137 (so the 6N137 pins and the resistor are connected in series)

You should also have a reverse connection protection diode between pins 2 and 3 of the 6N137 but I like living dangerously and rely on the diode inside the 6N137

Pin 8 and 7 are connected to VCC

Pin 6 is connected to RX

Pin 5 is connected to GND

4.7 kohm pullup resistor between pin 8 and 6 (VCC and signal out)

Adapted from this blog post.

----------

How to test it :

I used Arduino Mega with this code.

I then attached the Arduino Mega to Hairless MIDI, then to loopMIDI.

Then I read the MIDI output using MIDIOX.

  [1]: https://i.stack.imgur.com/n56Xu.jpg
  [2]: https://i.stack.imgur.com/VmuRr.png
  [3]: https://i.stack.imgur.com/t6V0G.jpg
  [4]: https://i.stack.imgur.com/GJhPo.jpg

----------

I might update it with H11L1 / PC900 later, if I have some time. Also, I'm going to put this thread in Indonesian in my blog later.

body:
I use this library with Arduino Uno (where can change bootloader):
https://github.com/TheKikGen/USBMidiKliK
And after the device is recognized from windows how a Midi device, so not need any other program to interface em.

You can use your preferred sequencer program and your arduino interface is recognized how a midi interface.

The sketch is very simple:

        /**********************************************************************************

      KIKGEN MIDI USB
      A MIDI USB RELIABLE INTERFACE
      USB-MIDI simple converter Sketch for Arduino
           USB                           ATMEGA8U2                    ATMEGA 328P
      --------------         ------------------------------         ---------------
      IN Endpoint  o<--------o USBOUT | usbMidiKliK |  RX o<--------o (TX) MIDI IN
      OUT Endpoint o-------->o USBIN  |  firmware   |  TX o-------->o (RX) MIDI OUT

      The RX/TX on the Arduino must no be crossed, as the ATMEGA8U2 is directly connected
      to the RX and TX pins.  When PIN0 (RX) and PIN1 (TX) are configured as INPUT, we
      can talk directly with the ATMEGA8U2 managing the USB, making the Arduino transparent.

    ************************************************************************************/

    void setup() {

      // Make Arduino transparent for serial communications from and to USB

      pinMode(0,INPUT); // Arduino RX - ATMEGA8U2 TX

      pinMode(1,INPUT); // Arduino TX - ATMEGA8U2 RX

    }

    void loop() {

    }

And hardware schema is this:
[![enter image description here][1]][1]

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


body:
I'm using arduino atmega 328p and currently using on custom PCB
I programmed using the arduino board and take the IC and migrated to my custom PCB
currently the program run well on the arduino board but after i tried to run it in my custom PCB  and i found it didn't worked
im using along with 16000 mhz oscillator with 22n capacitor

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

as shown this is my schematic for my PCB

[![enter image description here][2]][2]

this is my trace for my PCB board

so is this problem caused by my schematics or i didn't upload the bootloader?

  [1]: https://i.stack.imgur.com/bcvgf.png
  [2]: https://i.stack.imgur.com/gF4Iu.png

title: Burning bootloader

Answers: 1

body:
Schematic corrections:

Missing 0.1uF caps on VCC, AREF pins.

AREF pin connected to 5V - don't do that. It will connect internally using the ADC Mux if used.

C1, C6 need to be 22pF as noted earlier.

Xtal and C1, C6 should be right next to the chip as noted, with no traces going under the xtal.

Board should have Gnd plane anywhere there is not a trace.

Use Vias to connect top & bottom Gnd planes.

Do not use traces to connect all the Gnds - have pins connect to the Gnd planes instead.

Add a 1uF or 10uF electrolytic capacitor where power comes into the board, especially if the power leads will be long.


body:
**Goal:**

I am trying to send some characters to Arduino through serial from PC via a Prolific PL2303 USB to TTL converter(Chinese clone).

I have wrote a simple sketch(attached bellow) which should light up the LED if 'n' is found or should switch the LED off if 'f' is found from serial.

**What's Happening:**

I opened up the serial monitor. Send a character(say 'n' which should light up the LED). But nothing happened though the RX/TX LEDs flashed. Then I re opened the serial monitor. And just after re opening the serial monitor LED light up! Every time when I issue a character from serial monitor nothing happens. But just after re opening the monitor character is sent.

**H/W Connection:**

* Arduino Vin -> LiPo positive rail(+11V)
* Arduino GND -> LiPo negative rail(GND)
* Prolific GND -> Arduino GND
* Prolific RX -> Arduino TX
* Prolific TX -> Arduino RX

**Arduino Sketch:**

    int led = 13;

    void setup() {
      // put your setup code here, to run once:
      pinMode(led, OUTPUT);
      Serial.begin(9600);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      if(Serial.available() > 0){
        char bytesReceived = Serial.read();
        Serial.println(bytesReceived);

        if(bytesReceived == 'n'){
          digitalWrite(led, HIGH);
        }
        else if(bytesReceived == 'f'){
          digitalWrite(led, LOW);
        }
      }
    }

**Additional Notes:**

* Platform Windows 10
* Installed Prolific PL2303 driver from [here](http://www.totalcardiagnostics.com/support/Knowledgebase/Article/View/92/20/prolific-usb-to-serial-fix-official-solution-to-code-10-error)
* This code is working using USB cable provided with Arduino.(I need longer cable)

Can't understand why this strange thing is happening. Any kind of help will be appreciated.

Thanks!

title: Can't write to serial immediately from PC to Arduino nano via pl2303 usb to ttl converter

Answers: 1

body:
I have experienced similar behavior with clone chips. What worked for me is using ferrite choked USB cables similar to [these][1]; as you referenced as well, I observed that the problem occurs with either longer cable, or with cables without ferrite chokes on them. This might have to do with the PCB or the cheap chips being prone to electromagnetic interference.

  [1]: https://www.amazon.com/Device-Cable-Dual-Ferrite-Chokes/dp/B004ZXN7B2


body:
Hi i am using ESP8266EX along with Arduino Due rev3 to check wifi status. when i compile my following sketch compiler give me error
User\Awais\Document\Arduino\liberaries\espsoftserialmaster\softserial.cpp\:27:18: fatal error: gpio.h: no file or directory found
any one help me solve this problem

        #include <SoftwareSerial.h>
        SoftwareSerial ESPserial (15,14); //RX|TX

         void setup() {
      // put your setup code here, to run once:

      Serial.begin(115200);
      ESPserial.begin(115200);
      Serial.println("NL & CR");
    }

      void loop() {
     // put your main code here, to run repeatedly:

      if (ESPserial.available()){
       Serial.write(ESPserial.read());
      }

    if (Serial.available()){
    ESPserial.write(Serial.read());
    }
      }

Answers: 1

body:
And where did you get that SoftwareSerial library? SoftwareSerial libraries are architecture dependent. You can't use AVR ore esp8266 SoftwareSerial library with ARM.

Due has no need for SoftwareSerial, it has 4 Serial ports configured.


body:
I am working on a project where a rotary encoder is generating 0 - 359° output and I am feeding that to a 60 Neopixel ring but I need a way to simplify or come up with a better way of a bunch of *if-then-else* statements.  Here is some sample code.

    // NeoPixel Display
      if ((counter >=3) && (counter <=9))
    (
      strip.setPixelColor(0, 255, 0, 0); //set pixel number 1 and set color to red
      strip.show(); //send color to pixel 1 on NeoPixel Ring
    )
    else if strip.setPixelColor(0, 0, 0, 0);
            strip.show();

      if ((counter >=10) && (counter <=15))
    (
      strip.setPixelColor(1, 255, 0, 0); //set pixel number 2 and set color to red
      strip.show(); //send color to pixel 2 on NeoPixel Ring
    )
    else if strip.setPixelColor(1, 0, 0, 0);
            strip.show();

      if ((counter >=16) && (counter <=21))
    (
      strip.setPixelColor(2, 255, 0, 0); //set pixel number 3 and set color to red
      strip.show(); //send color to pixel 3 on NeoPixel Ring
    )
    else if strip.setPixelColor(2, 0, 0, 0);
            strip.show();

title: Simplify if then else statements for Neopixel/compass project

Answers: 1

body:
You don't use the correct syntax. I assume you mean:

    // NeoPixel Display
    if ((counter >=3) && (counter <=9))
    {
      strip.setPixelColor(0, 255, 0, 0); //set pixel number 1 and set color to red
      strip.show(); //send color to pixel 1 on NeoPixel Ring
    }
    else
    {
      strip.setPixelColor(0, 0, 0, 0)
      strip.show();
    }

And similar for the other colors.

First you see there are a lot of occurences of calls to setPixelColor and show. We make a function of this, where the color and the red value is parameterized:

    void setPixel(int pixelNumber, int red)
    {
      strip.setPixelColor(pixelNumber, red, 0, 0);
    }

Now we can write your code as

    // NeoPixel Display
    if ((counter >=3) && (counter <=9))
    {
      setPixel(0, 255);
    }
    else
    {
      setPixel(0, 0);
    }

    void setPixel(int pixelNumber, int red)
    {
      strip.setPixelColor(pixelNumber, red, 0, 0);
      strip.show();
    }

And similar for the other colors.

Now we get rid of the if statements. For the first color this will become:

    // NeoPixel Display
    setPixel(0, ((counter >= 3) && (counter <= 9)) ? 255 : 0);

Combined with the other colors we get

    // NeoPixel Display
    setPixel(0, ((counter >=  3) && (counter <=  9)) ? 255 : 0);
    setPixel(1, ((counter >= 10) && (counter <= 15)) ? 255 : 0);
    setPixel(2, ((counter >= 16) && (counter <= 21)) ? 255 : 0);

    void setPixel(int pixelNumber, int red)
    {
      strip.setPixelColor(pixelNumber, red, 0, 0);
      strip.show();
    }

However, the conditions can be simplified by adding them into the function. So we get

    // NeoPixel Display
    setPixel(0, counter,  3,  9);
    setPixel(1, counter, 10, 15);
    setPixel(2, counter, 16, 21);

    void setPixel(int pixelNumber, int counter, int lowValue, int highValue)
    {
      strip.setPixelColor(pixelNumber,
         ((counter >= lowValue) && (counter <= highValue)) ? 255 : 0,
         0, 0);
      strip.show();
    }

If you need to have more checks if a value is in range you can make it a specific function. This will increase the code, but makes it easier to reuse code. So you will get:

    // NeoPixel Display
    setPixel(0, counter,  3,  9);
    setPixel(1, counter, 10, 15);
    setPixel(2, counter, 16, 21);

    void setPixel(int pixelNumber, int counter, int lowValue, int highValue)
    {
      strip.setPixelColor(pixelNumber,
        inRange(counter, lowValue, highValue) ? 255 : 0,
         0, 0);
      strip.show();
    }

    int inRange(int counter, int lowValue, int highValue)
    {
       return ((counter >= lowValue) && (counter <= highValue));
    }


body:
I want to read a Omron E6B2-CWZ6C Incremental Rotary Encoder w/Index (360P/R).
A couple questions, I found out that an Uno can only handle 2 interrupt pins and I think I need 3 for the Index.  What do I need to do to the following code to get it to run on a Mega which I believe can handle 3 interrupt pins?

Also I am getting a 'outAChange' was not declared in this scope.
What am I missing here.

I will be using the data from the encoder value to run a NeoPixel 60 for a directional mast/antenna.

Here is the code I am trying to use:

    // Wiring connections for my encoder:
    // Brown : VCC = 5 to 24VDC
    // Blue: 0V(Common) = GND
    // Shield: GND
    // Black: outA = Digital pin 2
    // White: outB = Digital pin 3
    // Orange: outZ = Digital pin 4 (Index)
    // With these outA/outB/outZ connections and the interrupt code below
    // clockwise rotation gives positive encoder counts

    const int outA = 2;
    const int outB = 3;
    const int outZ = 4;

    volatile long encoder = 0; // declare volatile since modified by interrupt routines
    float encoder_save = 0;

    void setup(){  // set encoder pins
    pinMode(outA, INPUT_PULLUP);
    pinMode(outB, INPUT_PULLUP);
    pinMode(outZ, INPUT_PULLUP);  //Index

    // attach interrupts to pins
    attachInterrupt(digitalPinToInterrupt(outA), outAChange, CHANGE);
    attachInterrupt(digitalPinToInterrupt(outB), outBChange, CHANGE);
    attachInterrupt(digitalPinToInterrupt(outZ), outZChange, CHANGE);

    // initialize serial
    Serial.begin(57600);
    }

    void loop(){

    if (encoder_save != encoder)  // only print if new value
    encoder_save = encoder;

    // If Index(Z) reads low reset encoder to 0
    if (digitalRead(outZ) == LOW)
    {
      encoder = 0;
    }
    }

    {
    Serial.println((encoder * 360)/360);
    }
    }

    // interrupt routines
    void outAChange(){
    // when outA changes, outA==outB means negative direction
    encoder += digitalRead(outA) == digitalRead(outB) ? -1 : 1;
    if (encoder < 0)
    {
      encoder = (encoder + 360);
    }
    }

    void outBChange(){
    // when outB changes, outA==outB means positive direction
    encoder += digitalRead(outA) == digitalRead(outB) ? 1 : -1;
    if (encoder >= 360)
    {
      encoder = (encoder - 360);
    }
    }

title: Uno to Mega and where is the error for the interrupt that isn't delared?

Answers: 1

body:
Your brackets are all messed up.  If you pass your code through an autoformatter (such as the one included in the IDE) you end up with this:

    // Wiring connections for my encoder:
    // Brown : VCC = 5 to 24VDC
    // Blue: 0V(Common) = GND
    // Shield: GND
    // Black: outA = Digital pin 2
    // White: outB = Digital pin 3
    // Orange: outZ = Digital pin 4 (Index)
    // With these outA/outB/outZ connections and the interrupt code below
    // clockwise rotation gives positive encoder counts

    const int outA = 2;
    const int outB = 3;
    const int outZ = 4;

    volatile long encoder = 0; // declare volatile since modified by interrupt routines
    float encoder_save = 0;

    void setup() { // set encoder pins
        pinMode(outA, INPUT_PULLUP);
        pinMode(outB, INPUT_PULLUP);
        pinMode(outZ, INPUT_PULLUP);  //Index
    // attach interrupts to pins
        attachInterrupt(digitalPinToInterrupt(outA), outAChange, CHANGE);
        attachInterrupt(digitalPinToInterrupt(outB), outBChange, CHANGE);
        attachInterrupt(digitalPinToInterrupt(outZ), outZChange, CHANGE);
    // initialize serial
        Serial.begin(57600);
    }

    void loop() {
        if (encoder_save != encoder) { // only print if new value
            encoder_save = encoder;
        }

    // If Index(Z) reads low reset encoder to 0
        if (digitalRead(outZ) == LOW) {
            encoder = 0;
        }
    }

    {                                                << WHAT
        Serial.println((encoder * 360) / 360);       << IS
    }                                                << THIS
    }                                                << CODE?

    // interrupt routines
    void outAChange() {
    // when outA changes, outA==outB means negative direction
        encoder += digitalRead(outA) == digitalRead(outB) ? -1 : 1;

        if (encoder < 0) {
            encoder = (encoder + 360);
        }
    }

    void outBChange() {
    // when outB changes, outA==outB means positive direction
        encoder += digitalRead(outA) == digitalRead(outB) ? 1 : -1;

        if (encoder >= 360) {
            encoder = (encoder - 360);
        }
    }

As you can see, after the end of your `loop()` function, you have an extraneous block of code with a bunch of random brackets.

You need to decide where in your program that should actually be and move it there, deleting those extra brackets.


body:
After some time off, I decided to get back into my project after some help from this topic I started earlier https://arduino.stackexchange.com/questions/55216/difference-in-pinout-types-uno-mega. Unfortunately, even tho I have read multiple times what has been said about the SPI pins on a mega, the displays simply will not work. Both my LED strips and rotary encoder are working, so my code compiles and uploads as it should. The displays are ssd1307 using SPI.

    Pinout from MEGA to displays
    49 > RST for display1/display2/display3
    50 > DC for display1/display2/display3
    51 > SDA for display1/display2/display3
    52 > SCK for display1/display2/display3

    33 > CS for display1
    34 > CS for display2
    35 > CS for display3

Here is the code I am trying to use:

    #include <Adafruit_NeoPixel.h>
    #include "HCuOLED.h"
    #include "SPI.h"

    Adafruit_NeoPixel REVLEDS = Adafruit_NeoPixel(7, 2, NEO_GRB);
    Adafruit_NeoPixel DASHLEDS = Adafruit_NeoPixel(3, 3, NEO_GRB);

    #define SCK 52
    #define SDA 51
    #define DC 50
    #define RST 49

    HCuOLED HCuOLED_5(SSD1307, 33, DC, RST); // For SSD1307 displays (HCMODU0050 & HCMODU0052)
    HCuOLED HCuOLED_4(SSD1307, 34, DC, RST); // For SSD1307 displays (HCMODU0050 & HCMODU0052)
    HCuOLED HCuOLED_3(SSD1307, 35, DC, RST); // For SSD1307 displays (HCMODU0050 & HCMODU0052)

    #define s1 6
    #define s2 5
    #define key 4

    int newCounter = 0;
    int oldCounter = 0;
    int oldState;
    int newState;
    int rotated = 0;
    int keyState = 0;
    int keyReset = 0;

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

      REVLEDS.begin();
      REVLEDS.setBrightness(25);

      DASHLEDS.begin();
      DASHLEDS.setBrightness(25);

      pinMode(s1, INPUT);
      pinMode(s2, INPUT);

      oldState = 1;
      newState = oldState;

      HCuOLED_5.Reset();
      pinMode(53, OUTPUT);
    }

    void loop() {

      newState = digitalRead(s1);
      if(newState != oldState){
        if(digitalRead(s2)!= oldState){
          newCounter ++;
        } else {
          newCounter --;
        }
        if(newCounter == (oldCounter+2) ||newCounter == (oldCounter-2)){
          if(newCounter > oldCounter) rotateRight();
          else rotateLeft();
          oldCounter = newCounter;
        }
      }
      oldState = newState;

      keyState = digitalRead(key);
      //Serial.println(keyState);
      if(keyState == LOW && keyReset == 0){
        onButtonPress();
        keyReset = 1;
      } else if (keyReset == 1 && keyState == HIGH){
        keyReset = 0;
      }

      for(int i = 0; i < 7; i++){
      REVLEDS.setPixelColor(i, 0,255,0);}
      REVLEDS.show();

      for(int i = 0; i < 3; i++){
      DASHLEDS.setPixelColor(i, 0,0,255);}
      DASHLEDS.show();

      //display 5
      HCuOLED_5.SetFont(Terminal_8pt);
      HCuOLED_5.Cursor(44,0);
      HCuOLED_5.Print("Cpt");
      HCuOLED_5.Cursor(20,10);
      HCuOLED_5.Print("Fastlane");
    }

    void onButtonPress(){
      Serial.println("Pressed button");
    }

    void rotateLeft(){
      Serial.println("Rotated left");
    }

    void rotateRight(){
      Serial.println("Rotated right");
    }

Now the question is, what am I missing?
TIA!

title: getting SPI SSD1307 to work on Arduino Mega

Answers: 2

body: The displays do not use SPI MISO pin. It is 12 in Uno and 50 on Mega. On Mega you try to use pin 50 for DC pin of the displays and it creates a conflict with SPI. MISO should be an INPUT and DC is OUTPUT.

body:
Found the problem... after my break, i forgot that the .refresh() command is actually the command that displays something on the screen, while I kept thinking it was to clear the screen. After adding that to my code together with .clearBuffer(), everything works with the following pinout:

    Pinout from MEGA to displays
    48 > RST for display1/display2/display3
    49 > DC for display1/display2/display3
    51 > SDA for display1/display2/display3
    52 > SCK for display1/display2/display3

    33 > CS for display1
    34 > CS for display2
    35 > CS for display3

With the following code to show different stuff on screen:

    #include "HCuOLED.h"
    #include "SPI.h"

    #define SCK 52
    #define SDA 51
    #define DC 49
    #define RST 48

    HCuOLED HCuOLED_5(SH1106, 33, DC, RST); // For SSD1307 displays (HCMODU0050 & HCMODU0052)
    HCuOLED HCuOLED_4(SH1106, 34, DC, RST); // For SSD1307 displays (HCMODU0050 & HCMODU0052)
    HCuOLED HCuOLED_3(SH1106, 35, DC, RST); // For SSD1307 displays (HCMODU0050 & HCMODU0052)

    int tCounter = 0;

    void setup(){
      HCuOLED_5.Reset();
      //pinMode(53, OUTPUT);
    }

    void loop() {
      //display 3
      HCuOLED_3.SetFont(Terminal_8pt);
      HCuOLED_3.Cursor(44,0);
      HCuOLED_3.Print("Cpt");
      HCuOLED_3.Cursor(20,10);
      HCuOLED_3.Print("Fastlane");
      HCuOLED_3.SetFont(LCDLarge_24pt);
      HCuOLED_3.Cursor(20,30);
      HCuOLED_3.Print("3 - ");
      HCuOLED_3.Cursor(65,30);
      HCuOLED_3.Print(tCounter);
      HCuOLED_3.Refresh();
      HCuOLED_3.ClearBuffer();

      //display 4
      HCuOLED_4.SetFont(Terminal_8pt);
      HCuOLED_4.Cursor(44,0);
      HCuOLED_4.Print("Cpt");
      HCuOLED_4.Cursor(20,10);
      HCuOLED_4.Print("Fastlane");
      HCuOLED_4.SetFont(LCDLarge_24pt);
      HCuOLED_4.Cursor(20,30);
      HCuOLED_4.Print("4 - ");
      HCuOLED_4.Cursor(65,30);
      HCuOLED_4.Print(tCounter);
      HCuOLED_4.Refresh();
      HCuOLED_4.ClearBuffer();

      //display 5
      HCuOLED_5.SetFont(Terminal_8pt);
      HCuOLED_5.Cursor(44,0);
      HCuOLED_5.Print("Cpt");
      HCuOLED_5.Cursor(20,10);
      HCuOLED_5.Print("Fastlane");
      HCuOLED_5.SetFont(LCDLarge_24pt);
      HCuOLED_5.Cursor(20,30);
      HCuOLED_5.Print("5 - ");
      HCuOLED_5.Cursor(65,30);
      HCuOLED_5.Print(tCounter);
      HCuOLED_5.Refresh();
      HCuOLED_5.ClearBuffer();

      tCounter++;
    }