body:
I will be working with Arduino(s), and I would like to find a way to download the sketches to the board semi permanently, in a way that I can remove the USB from the board, apply power, and still have the Arduino execute the code

I am planning to use Mega2960, Uno, and Nano. If there are any differences between the uploading process,
please let me know.

P.S., I am using boards produced by Elegoo, not by Arduino, if that makes a difference.

title: How do I download a sketch to an Arduino semi-permanently?

Answers: 1

body:
1. Download the Arduino software (IDE, or Integrated Development Environment).

In our case, we only need to download and run Windows Installer and follow the pop up instructions.  When asked if you want to install the Arduino driver, just press Yes.

2. Connect your Arduino Nano board to your computer.

In this step, Windows should automatically find the proper Arduino driver and install it, and your Nano board should be ready to use.  If not, please refer to the above mentioned instruction for details on installing the drivers.  Some compatible Nano boards such as DCCduino manufactured by a Chinese company use different USB-to-Serial chips so they require to install different drivers, but the installation should be quite straight forward once you have downloaded the proper drivers from internet.

3. Launch the Arduino application.

4. Open the blink example.

Open the LED blink example sketch: File > Examples > 01.Basics > Blink.

For those who are not familiar with Arduino sketch, a sketch is simply a program with various instructions telling Arduino board what to do.

5. Select your board.

You’ll need to select what type of Arduino board you are using.  In our case, simply select Tools > Board > Arduino Nano w/Atmega328.

6. Select your serial port

You also need to select the serial device of the Arduino board: Tools > Serial Port.  Usually the port number will be COM3 or higher (COM1 and COM2 are usually reserved for hardware serial ports). To find out, you can disconnect your Arduino board and re-open the menu; the entry that disappears should be the Arduino board. Reconnect the board and select that serial port.

7. Upload the program to Nano board

Now, simply click the “Upload” button in the environment. Wait a few seconds – you should see the RX and TX leds on the board flashing. If the upload is successful, the message “Done uploading.” will appear in the status bar.

A few seconds after the upload finishes, you should see the pin 13 (L) LED on the board start to blink (in orange). If it does, congratulations! You’ve gotten Arduino up-and-running.

Disconnect from your computer and connect to a power supply to see the blinking light.


body:
the code posted below runs perfectly on UNO, but the loop only runs for twice or thrice (figured this out by printing out "TEST" on the Serial Monitor) on the Arduino mega. Someone can tell me what's wrong with this? It's a 4wd robot which runs on RF Joystick. The circuit has a RF receiver connected to digital pin 2. Also, I noticed that when all the functions are removed from the loop, it runs perfectly.
However, as my suspicion that the board is not functioning properly, I tried uploading other programs to the MEGA and they run flawlessly.Including the "ESP8266 as a shield controlled using the Blynk app version" of this code.

    #include <VirtualWire.h>
    #include <AFMotor.h>
    int RF_RX_PIN = 2;// RF signal from joystick
    void(* resetFunc) (void) = 0;
    AF_DCMotor rb(4);//means rightside,back wheel
    AF_DCMotor lb(3);//leftside, back wheel
    AF_DCMotor rf(1);
    AF_DCMotor lf(2);
      int xh,xl,yh,yl;
      uint8_t z;
      uint8_t button;

    void setup()
    {
      Serial.begin(9600);
      vw_set_rx_pin(RF_RX_PIN);  // Setup receive pin.
      vw_setup(2000); // Transmission speed in bits per second.
      vw_rx_start(); // Start the PLL receiver.
      pinMode(servopin,OUTPUT);
      pinMode(13,OUTPUT);
      rf.run(RELEASE);
      lf.run(RELEASE);
      lb.run(RELEASE);
      rb.run(RELEASE);
      digitalWrite(13,HIGH);
    }

    uint8_t buffer[VW_MAX_MESSAGE_LEN]; // buffer array for data recieve over serial port
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    int x=0;
    int y=0;
    int state=2;

    void loop()
    {
      Serial.println("TEST");
      if(vw_get_message(buffer, &buflen)) // non-blocking I/O
      {
        decode();
      if ((x==0 && y==0) || z==1){rstop();}
      else {
      Serial.print(x);
      Serial.print(" ");
      Serial.println(y);
      godirection(x,y);
      }
      }else{
        state=2;
        rstop();
      }
    }

    void decode()
    {
      if((buffer[0]!=0x7E)||(buffer[4]!=0xEF))
      {
      resetFunc();
      }
      uint8_t i = 0;
      x = buffer[1]<<2;
      y = buffer[2]<<2;
      z = buffer[3]>>3;
      button = buffer[3]&0x07;
       if (x>600){
        x=1;
      }else if (x<=600 && x>=400){x=0;}
      else {x=-1;}
      if (y>600){
        y=1;
      }else if (y<=600 && y>=400){y=0;}
      else {y=-1;}
    }

    void clearBufferArray()              // function to clear buffer array
    {
      for (int i=0; i<VW_MAX_MESSAGE_LEN;i++)
        { buffer[i]=0;}                  // clear all index of array with command NULL
    }
    void godirection(int x,int y) {
         if (x==0){
          if (y==1){forward();}
          else if (y==0){rstop();}
          else if (y==-1){backward();}
         }
         else if (x==1){
          if (y==1){srf();}
          else if (y==0){right();}
          else if (y==-1){srb();}
         }
         else if (x==-1){
          if(y==1){slf();}
          else if (y==0){left();}
          else if (y==-1){slb();}
         }
    }

    void rstop (){
      if (state==0){
      rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
      rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
      delay(75);
      rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
      rf.setSpeed(0);lf.setSpeed(0);rb.setSpeed(0);lb.setSpeed(0);
      state=2;
    }
    else if (state==1){
      rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
      rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
      delay(75);
      rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
      rf.setSpeed(0);lf.setSpeed(0);rb.setSpeed(0);lb.setSpeed(0);
      state=2;
    }
    else if (state==2){
        rf.run(RELEASE);lf.run(RELEASE);lb.run(RELEASE);rb.run(RELEASE);
      rf.setSpeed(0);lf.setSpeed(0);rb.setSpeed(0);lb.setSpeed(0);
    }
    }

    void forward(){
      state=1;
      rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
      rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
    }

    void backward(){
      state=0;
      rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
      rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
    }

    void right(){
      state=2;
      rf.run(BACKWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(BACKWARD);
      rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
    }
    void left(){
      state=2;
      lf.run(BACKWARD);rf.run(FORWARD);rb.run(FORWARD);lb.run(BACKWARD);
      rf.setSpeed(200);lf.setSpeed(200);rb.setSpeed(200);lb.setSpeed(200);
    }

    void srf(){//srf means slanted right forward
      state=1;
      rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
      rf.setSpeed(50);lf.setSpeed(200);rb.setSpeed(50);lb.setSpeed(200);
    }

    void srb(){
      state=0;
      Serial.println("SRB");
      rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
      rf.setSpeed(50);lf.setSpeed(200);rb.setSpeed(50);lb.setSpeed(200);
    }

    void slf(){
      state=1;
      rf.run(FORWARD);lf.run(FORWARD);lb.run(FORWARD);rb.run(FORWARD);
      lf.setSpeed(50);rf.setSpeed(200);lb.setSpeed(50);rb.setSpeed(200);
    }

    void slb(){
      state=0;
      rf.run(BACKWARD);lf.run(BACKWARD);lb.run(BACKWARD);rb.run(BACKWARD);
      lf.setSpeed(50);rf.setSpeed(200);lb.setSpeed(50);rb.setSpeed(200);
    }

title: Code running on UNO doesn't run on MEGA

Answers: 0


body:
I am having a problem compiling the code for my ATtiny85 circuit.

I am using the timer/counter0 in normal mode so that when it overflows it triggers the TIMER0_OVF_vect ISR. When I have that ISR in my code, it wont compile and gives this error:

    wiring.c.o (symbol from plugin): In function `__vector_5':
    (.text+0x0): multiple definition of `__vector_5'
    sketch\Glove_heater_v1.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
    collect2.exe: error: ld returned 1 exit status
    exit status 1
    Error compiling for board ATtiny25/45/85.

Maybe I just need to use a different name for the ISR?
---------------------------------------------------------

    My Code:

    //Red LED on PB0
    //Blue LED on PB1
    //Pushbutton PB2
    //Battery voltage divider PB3
    //Mosfet control PB4

    #include <avr/io.h>
    #include <stdint.h>
    #include <avr/interrupt.h>

    volatile uint8_t checkVoltage = 0;

    void setup() {

       DDRB = 0b0010011; //set PB0,PB1,PB4 as output, PB2,PB3 as input
       PORTB = 0b00000011; //set PB0,PB1 HIGH so LEDs are off, other pins LOW

       //Setup TC0 for overflow interrupt trigger
       TCCR0B |= 0b00000101; //clk/1024 prescaler
       TIMSK |= 0b00000010;  //set TOIE0 enable overflow interrupt
       sei();
    }

    void loop() { //do nothing in this test code

    }

    ISR(TIMER0_OVF_vect){ //Timer/counter0 interrupt check voltage
       checkVoltage = 1;
    }

Any ideas are appreciated!

title: Arduino IDE with ATtiny85 error "multiple definition of `__vector_5"

Answers: 1

body:
The error message was:

> wiring.c.o [...]: multiple definition of \`\_\_vector\_5'
> Glove\_heater\_v1.ino.cpp.o [...]: first defined here

`__vector_5` is `TIMER0_OVF_vect`. So you have one definition of this
ISR in your sketch, and another one in wiring.c. This wiring.c is part
of the Arduino core. As KIIV puts it in a comment, it uses
`TIMER0_OVF_vect` for timekeeping (`millis()`, `micros()` and
`delay()`).

You have two options for solving this:

* you can use the other timer (Timer 1) in your sketch, and leave Timer
  0 for the Arduino core
* since you are not using the Arduino core anyway, you can get rid of it
  by simply defining `main()` in your sketch instead of `setup()` and
  `loop()`.


body:
I am creating library for GPS to use in my project. I am using Adafruit GPS and its library to create my own library in which I am using `millis()` function to display the GPS Location after 1 minute (60s). So when I created my inline code the function works very well and also displays location after 60s. But I created `header` and `cpp` file for my own library, in which it doesn't gives any error but the results(location) is not displayed. Doesn't shows any output. So I printed the time which is 0 (attached the output screenshot)[![enter image description here][1]][1]

My code updates the GPS every 30s and prints the location every 1 minute.It also checks the if old location is equal to new location in every 1minute.

I think there is problem with my libaray or with the millis() function. I am new to Arduino programming , please help me with this.

My inline code is:

    #include <Adafruit_GPS.h>
    #include <SoftwareSerial.h>

    SoftwareSerial mySerial(11, 10);
    Adafruit_GPS GPS(&mySerial);

    #define GPSECHO  true
    uint32_t timer = millis();
    float old_lat,old_lon,new_lat,new_lon;

    void setup()
    {

      Serial.begin(9600);
      delay(1000);
      Serial.println("Adafruit GPS library basic test!");
      GPS.begin(9600);
      GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
      GPS.sendCommand("$PMTK220,30000*1F");
      mySerial.println(PMTK_Q_RELEASE);
    }

    void loop()                     // run over and over again
    {
      char c = GPS.read();
      if (GPS.newNMEAreceived()) {
        //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
        if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
          return;  // we can fail to parse a sentence in which case we should just wait for another
      }

    if (GPS.fix) {

          old_lat = GPS.latitudeDegrees;
          old_lon = GPS.longitudeDegrees;
          if (timer > millis())  timer = millis();
          if (millis() - timer > 60000) {
            timer = millis();
              Serial.println("Location 1 minute:");
              displaytime();
              new_lat = GPS.latitudeDegrees;
              new_lon = GPS.longitudeDegrees;

              if (new_lat == old_lat){
                new_lat = old_lat;
              }
              else{
                new_lat = GPS.latitudeDegrees;
              }
              Serial.print("Final Latitude: ");
              Serial.println(new_lat,6);

              if (new_lon == old_lon){
                new_lon = old_lon;
              }
              else{
                new_lon = GPS.longitudeDegrees;
              }
              Serial.print("Final Longitude: ");
              Serial.println(new_lon,6);

    }
    }
    }

    void displaytime(){
        Serial.print("\nTime: ");
        if (GPS.hour < 10) { Serial.print('0'); }
        Serial.print(GPS.hour, DEC); Serial.print(':');
        if (GPS.minute < 10) { Serial.print('0'); }
        Serial.print(GPS.minute, DEC); Serial.print(':');
        if (GPS.seconds < 10) { Serial.print('0'); }
        Serial.print(GPS.seconds, DEC); Serial.print('.');
        if (GPS.milliseconds < 10) {
          Serial.print("00");
        } else if (GPS.milliseconds > 9 && GPS.milliseconds < 100) {
          Serial.print("0");
        }
        Serial.println(GPS.milliseconds);
    }

My header file is :

    /*
     * GPS.h - library used to show Latitude and Longitude
     */

     #ifndef GPS_Loc_h
     #define GPS_Loc_h

     #include "Arduino.h"

    class SoftwareSerial;
    class Adafruit_GPS;

     class GPS_Loc
     {
      public:
        GPS_Loc();
        void displaytime();
        void displayloc();
        uint32_t timer;
        float old_lat,old_lon,new_lat,new_lon;
     };

     #endif

My cpp file is:

    /*
     * GPS_Loc.cpp - library used to show Latitude and Longitude
     */

     #include "Arduino.h"
     #include "GPS_Loc.h"

     #include "Adafruit_GPS.h"
     #include "SoftwareSerial.h"

     #define GPSECHO  true

    SoftwareSerial mySerial(11,10);
    Adafruit_GPS GPS(&mySerial);

    GPS_Loc::GPS_Loc()
    {
      timer = millis();
      old_lat = old_lat;
      old_lon = old_lon;
      new_lat = new_lat;
      new_lon = new_lon;
    }

    void GPS_Loc::displayloc(){
      //Serial.println("Adafruit GPS library basic test!");
      GPS.begin(9600);
      GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
      GPS.sendCommand("$PMTK220,30000*1F");
      mySerial.println(PMTK_Q_RELEASE);
      char c = GPS.read();
      if (GPS.newNMEAreceived()) {
        //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
        if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
          return;  // we can fail to parse a sentence in which case we should just wait for another
       }

    if (GPS.fix) {

          old_lat = GPS.latitudeDegrees;
          old_lon = GPS.longitudeDegrees;
          if (timer > millis())  timer = millis();
          if (millis() - timer > 60000) {
            timer = millis();
              Serial.println("Location 1 minute:");
              displaytime();
              new_lat = GPS.latitudeDegrees;
              new_lon = GPS.longitudeDegrees;

              if (new_lat == old_lat){
                new_lat = old_lat;
              }
              else{
                new_lat = GPS.latitudeDegrees;
              }
       Serial.print("Location lat: ");
              Serial.println(new_lat,6);

              if (new_lon == old_lon){
                new_lon = old_lon;
              }
              else{
                new_lon = GPS.longitudeDegrees;
              }

              Serial.print("Location long: ");
              Serial.println(new_lon,6);

    }
    }
    }

    void GPS_Loc::displaytime(){
        Serial.print("\nTime: ");
        if (GPS.hour < 10) { Serial.print('0'); }
        Serial.print(GPS.hour, DEC); Serial.print(':');
        if (GPS.minute < 10) { Serial.print('0'); }
        Serial.print(GPS.minute, DEC); Serial.print(':');
        if (GPS.seconds < 10) { Serial.print('0'); }
        Serial.print(GPS.seconds, DEC); Serial.print('.');
        if (GPS.milliseconds < 10) {
          Serial.print("00");
        } else if (GPS.milliseconds > 9 && GPS.milliseconds < 100) {
          Serial.print("0");
        }
        Serial.println(GPS.milliseconds);
    }

My demo code using my own library is:

    #include <GPS_Loc.h>

    GPS_Loc bgps;

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

    }

    void loop() {
      // put your main code here, to run repeatedly:
      bgps.displaytime();
      bgps.displayloc();
    }

Output of inline code[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/ykGiV.png
  [2]: https://i.stack.imgur.com/F49ov.png

title: millis() function works with inline code and gives output but when creating own library it doesn't works

Answers: 1

body:
I think Gerben is on to something.  If you re-initialize the gps at every loop and then never give it time to acquire the gps signal then your if (GPS.fix) condition is never true and you never print out any other data.  All your timing code is inside the GPS.fix condition which doesn't happen until you have a fix.
Try putting the init code inside your contructor for your class. Somethink like :
```
GPS_Loc::GPS_Loc()
{
  timer = millis();
  old_lat = old_lat;
  old_lon = old_lon;
  new_lat = new_lat;
  new_lon = new_lon;

  //Serial.println("Adafruit GPS library basic test!");
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand("$PMTK220,30000*1F");
  mySerial.println(PMTK_Q_RELEASE);
}

void GPS_Loc::displayloc(){
  delay(100); // short delay to stop a no-fix runaway
  char c = GPS.read();
  if (GPS.newNMEAreceived()) {
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
    }

if (GPS.fix) {
````
It might also be useful to put a small delay somewhere in the code so that it won't loop like crazy before getting a fix.


body:
I would like to know how to set the current position for the DC motors to zero and store the current position in an array. after that I would like it to loop in the array to run all steps that was stored in the array?

Am using Genuino UNO board, I have 4 DC motors and each 2 wheels are connected to an H-bridge.

I have an application that have a "save" button and a "Run" button.
For the save button, I would like it to set the current position for each wheel to zero first then store the positions of each wheel in an array.
For the run button, I would like it to loop in the array that was made by the save button and show the output on each wheels.

basically what am trying to achieve is to make the robotic car that can move any direction I tell it to move in the same time  I can control the wheel speed.
all that move are being sent via Bluetooth as numbers.

I hope it's clear now

here is my code

    #include <SoftwareSerial.h>

    SoftwareSerial Bluetooth(0, 1); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX)

    // Define the motors and the pins
    // Motor A1

    int enA1 = 2;
    int in11 = 3;
    int in21 = 4;

    // Motor B1

    int enB1 = 5;
    int in31 = 6;
    int in41 = 7;

    //other H-bridge

    // Motor A2

    int enA2 = 8;
    int in12 = 9;
    int in22 = 10;

    // Motor B2

    int enB2 = 11;
    int in32 = 12;
    int in42 = 13;

    int wheelSpeed = 125;
    int dataIn, m;
    //lbw left back wheel / lfw left fron wheel / rbw right back wheel / rfw right front wheel
    int lbw[50], lfw[50], rbw[50], rfw[50]; // for storing positions/steps
    int index = 0;

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

      Bluetooth.begin(9600); // Default baud rate of the Bluetooth module
      Bluetooth.setTimeout(1);
      Serial.print("connected");
      Serial.print("-------------------");
      delay(20);

      pinMode(enA1, OUTPUT);
      pinMode(enB1, OUTPUT);
      pinMode(in11, OUTPUT);
      pinMode(in21, OUTPUT);
      pinMode(in31, OUTPUT);
      pinMode(in41, OUTPUT);
      pinMode(enA2, OUTPUT);
      pinMode(enB2, OUTPUT);
      pinMode(in12, OUTPUT);
      pinMode(in22, OUTPUT);
      pinMode(in32, OUTPUT);
      pinMode(in42, OUTPUT);
    }

    void loop() {
      // Check for incoming data

     if (Bluetooth.available() > 0) {
        dataIn = Bluetooth.read();  // Read the data

        if (dataIn == 0) {
          m = 0;
        }
        if (dataIn == 1) {
          m = 1;
        }
        if (dataIn == 2) {
          m = 2;
        }
        if (dataIn == 3) {
          m = 3;
        }
        if (dataIn == 4) {
          m = 4;
        }
        if (dataIn == 5) {
          m = 5;
        }
        if (dataIn == 6) {
          m = 6;
        }
        if (dataIn == 7) {
          m = 7;
        }
        if (dataIn == 8) {
          m = 8;

        }
        if (dataIn == 9) {
          m = 9;
        }
        if (dataIn == 10) {
          m = 10;
        }
        if (dataIn == 11) {
          m = 11;
        }

        if (dataIn == 12) {
          m = 12;
        }
        if (dataIn == 14) {
          m = 14;
        }
        // Set speed
        if (dataIn >= 16) {
          wheelSpeed = dataIn * 10;
          Serial.println(wheelSpeed);
        }
      }
      if (m == 4) {
        moveSidewaysLeft();
      }
      if (m == 5) {
        moveSidewaysRight();
      }
      if (m == 2) {
        moveForward();
      }
      if (m == 7) {
        moveBackward();
      }
      if (m == 3) {
        moveRightForward();
      }
      if (m == 1) {
        moveLeftForward();
      }
      if (m == 8) {
        moveRightBackward();
      }
      if (m == 6) {
        moveLeftBackward();
      }
      if (m == 9) {
        rotateLeft();
      }
      if (m == 10) {
        rotateRight();
      }

      if (m == 0) {
        stopMoving();
      }
      //Serial.println(dataIn);
      // If button "SAVE" is pressed
      if (m == 12) {
        if (index == 0) {
            digitalWrite(in11, LOW);
            digitalWrite(in21, LOW);
            digitalWrite(in31, LOW);
            digitalWrite(in41, LOW);
            digitalWrite(in12, LOW);
            digitalWrite(in22, LOW);
            digitalWrite(in32, LOW);
            digitalWrite(in42, LOW);

        }

        // save position into the array
      }
      //if (m == 14) {
       // runSteps();
        //if (dataIn != 14) {
          //stopMoving();
          // Clear the array data to 0
       // }
      //}

    }

    //method to read the array from what was saved by the save button and run it step by step
    //void runSteps() {}

    void moveForward() {
            digitalWrite(in11, HIGH);
            digitalWrite(in21, LOW);
            digitalWrite(in31, HIGH);
            digitalWrite(in41, LOW);
            digitalWrite(in12, HIGH);
            digitalWrite(in22, LOW);
            digitalWrite(in32, HIGH);
            digitalWrite(in42, LOW);
            Serial.println("Motor: move Forward");
    }

    void moveBackward() {
            digitalWrite(in11, LOW);
            digitalWrite(in21, HIGH);
            digitalWrite(in31, LOW);
            digitalWrite(in41, HIGH);
            digitalWrite(in12, LOW);
            digitalWrite(in22, HIGH);
            digitalWrite(in32, LOW);
            digitalWrite(in42, HIGH);
            Serial.println("Motor: move Backward");
    }

    void moveSidewaysLeft() {
            digitalWrite(in11, HIGH);
            digitalWrite(in21, LOW);
            digitalWrite(in31, LOW);
            digitalWrite(in41, HIGH);
            digitalWrite(in12, LOW);
            digitalWrite(in22, HIGH);
            digitalWrite(in32, HIGH);
            digitalWrite(in42, LOW);
            Serial.println("Motor: move Sideways Left");
    }
    void moveSidewaysRight() {
            digitalWrite(in11, LOW);
            digitalWrite(in21, HIGH);
            digitalWrite(in31, HIGH);
            digitalWrite(in41, LOW);
            digitalWrite(in12, HIGH);
            digitalWrite(in22, LOW);
            digitalWrite(in32, LOW);
            digitalWrite(in42, HIGH);
            Serial.println("Motor: move Sideways right");
    }

    void moveRightForward() {
            digitalWrite(in11, LOW);
            digitalWrite(in21, LOW);
            digitalWrite(in31, HIGH);
            digitalWrite(in41, LOW);
            digitalWrite(in12, HIGH);
            digitalWrite(in22, LOW);
            digitalWrite(in32, LOW);
            digitalWrite(in42, LOW);
            Serial.println("Motor: move Right Forward");
    }

    void moveLeftBackward() {
            digitalWrite(in11, LOW);
            digitalWrite(in21, LOW);
            digitalWrite(in31, LOW);
            digitalWrite(in41, HIGH);
            digitalWrite(in12, LOW);
            digitalWrite(in22, HIGH);
            digitalWrite(in32, LOW);
            digitalWrite(in42, LOW);
            Serial.println("Motor: move left Back ward");
    }

    void moveLeftForward() {
            digitalWrite(in11, LOW);
            digitalWrite(in21, LOW);
            digitalWrite(in31, LOW);
            digitalWrite(in41, HIGH);
            digitalWrite(in12, LOW);
            digitalWrite(in22, HIGH);
            digitalWrite(in32, LOW);
            digitalWrite(in42, LOW);
            Serial.println("Motor: move Left Forward");
    }

    void moveRightBackward() {
            digitalWrite(in11, LOW);
            digitalWrite(in21, HIGH);
            digitalWrite(in31, LOW);
            digitalWrite(in41, LOW);
            digitalWrite(in12, LOW);
            digitalWrite(in22, LOW);
            digitalWrite(in32, LOW);
            digitalWrite(in42, HIGH);
            Serial.println("Motor: move Right Backward");
    }

    void rotateLeft() {
            digitalWrite(in11, HIGH);
            digitalWrite(in21, LOW);
            digitalWrite(in31, LOW);
            digitalWrite(in41, HIGH);
            digitalWrite(in12, HIGH);
            digitalWrite(in22, LOW);
            digitalWrite(in32, LOW);
            digitalWrite(in42, HIGH);
            Serial.println("Motor: rotate Left");
      }

    void rotateRight() {
            digitalWrite(in11, LOW);
            digitalWrite(in21, HIGH);
            digitalWrite(in31, HIGH);
            digitalWrite(in41, LOW);
            digitalWrite(in12, LOW);
            digitalWrite(in22, HIGH);
            digitalWrite(in32, HIGH);
            digitalWrite(in42, LOW);
            Serial.println("Motor: rotate Right");
      }

    void stopMoving() {
            digitalWrite(in11, LOW);
            digitalWrite(in21, LOW);
            digitalWrite(in31, LOW);
            digitalWrite(in41, LOW);
            digitalWrite(in12, LOW);
            digitalWrite(in22, LOW);
            digitalWrite(in32, LOW);
            digitalWrite(in42, LOW);
            Serial.println("Motor: off");
      }

title: How to set current position for the DC motor to zero + store current positions in an array and run it?

Answers: 1

body:
As I understood it from your comments, your aim is not really to store the actual positions of the wheels or your robot, but to save and repeat the actions, that the robot did. (Meaning you don't have a "position" here, but only a measurement of wheel speed)

If that is true, then you can save this in a 2-dimensional array with the element form `{speed_wheel_1, speed_wheel2, duration}`. So each action is defined by the speeds of both wheels and the duration of the action, for example:

    Driving forward at full speed for 3s, turn on the spot to the left with half speed for 1.5s, drive a curve with motor left full speed and motor right half speed for 5s

This would translate to the following elements:

    {100, 100, 3000}
    {-50, 50, 1500}
    {100, 50, 5000}

The speeds have to be read in percent here and the durations in milliseconds.

----

Obviously you are controlling the robot over serial. I don't completely understand your code (also as you didn't show us the full code), so I will give some hints, how you can go on from here:

You are obtaining the speeds from serial into the variable `wheelSpeed`. We cannot see, how you are using this variable later, but you can use it in some way to set the speed fields of a new array element.

Then you need the duration. The Arduino framework has a function for that: `millis()`. It will return the number of milliseconds since the startup, much like a clock. When an action starts (when the corresponding serial command is received), you have to set a timestamp:

    unsigned long timestamp;
    ...
    timestamp = millis();

When the action ends (either because it actually only had a limited duration, or because another command is received), you calculate the difference between the current millis value and the timestamp. This is the duration.

So the corresponding code parts will look like this:

    unsigned long timestamp = 0; // Define timestamp at global scope
    unsigned int current_element = 0; // A variable to keep track of the current array element
    int actions[10][3]; // Array to hold up to 10 actions

    void start_action(byte speed_left, byte speed_right){
        actions[current_element][0] = speed_left;
        actions[current_element][1] = speed_right;
        timestamp = millis();
        // Start the action with the provided speeds here
    }

    void end_action(unsigned int element_index){
        actions[current_element][2] = millis() - timestamp;
        current_element++;
        if(current_element >= 10){
            // Do something to prevent more actions. Maybe just disable recording.
    }

For repeating the actions, you just have to cycle over the array and set the corresponding speeds for the corresponding time.

If you want to go fancy, you can ditch the 2-dimensional array and instead define a struct for an action:

    struct Action{
        int speed_left;
        int speed_right;
        unsigned long duration;
    };

Then you can create a simple array of the `Action` objects and reference the fields by name:

    Action actions[10];
    ...
    actions[1].duration = millis() - timestamp;


body:
I’d like to protect my arduino make with a unique serial number for every device I make.
What are the proper ways to do it? Probably there are kind of best practices…
Keep it in EEPROM is obviously a bad idea.

I believe that there is some chip that can be added to the circuitry.

The general idea is the following.
Circuitry has a hardware which gives a unique id (serial number). Distributor/seller generates the signature using unique id and put it to the eeprom. Arduino program verifies this signature using hardware serial number. Arduino program is distributed in binary or within the device.

title: Protect the Arduino make with Unique Id

Answers: 2

body:
I found a way! I can use DS2401 or DS2411.

These devices are 64-bit read only memory (ROM) "silicon serial number" devices which are programmed by the manufacturer with a unique 48 bit serial number, an 8 bit product family code, and an 8 bit CRC.

body:
I still suggest using the eeprom.
It is the firmware's job to handle whether or not data in eeprom can be written.
You could implement wrapper functions for the arduino which can only read/write after a defined offset. You can set this read-only data with the .eep-file when you upload your sketch. The eeprom file then may be generated programmatically.

Once you have to flash several individual devices with a final firmware version, there are no benefits in using the arduino ide. You can upload the firmware and the eeprom file using avrdude:

    avrdude -P YOUR_PORT -b 115200 -p ATmega328P -e -U flash:w:YOUR_FIRMWARE.hex -U eeprom:w:YOUR_EEPROM.eep

It's up to you how to generate the eeprom file (bash/batch, make, pyhton,...).


body:
I need to operate 2 different sensors by Arduino UNO: GPS module and Ultrasonic sensor. I have managed to run each one of them separately and I don't know how to manipulate the code;

## GPS MODULE ##

    #include <TinyGPS++.h>
    #include <SoftwareSerial.h>

    static const int RXPin = 4, TXPin = 3;
    static const uint32_t GPSBaud = 9600;

    // The TinyGPS++ object
    TinyGPSPlus gps;

    // The serial connection to the GPS device
    SoftwareSerial ss(RXPin, TXPin);

    void setup()
    {
      Serial.begin(9600);
      ss.begin(GPSBaud);
    }

    void loop()
    {
      // This sketch displays information
      // every time a new sentence is correctly encoded.
      while (ss.available() > 0)
      {
        gps.encode(ss.read());
        if (gps.location.isUpdated())
        {
          Serial.print("Latitude= ");
          Serial.print(gps.location.lat(), 6);
          Serial.print(" Longitude= ");
          Serial.println(gps.location.lng(), 6);
        }
      }
    }

###ULTRASONIC SENSOR###

    // defines pins numbers
    const int trigPin = 9;
    const int echoPin = 10;

    // defines variables
    long duration;
    int distance;
    void setup()
    {
      pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
      pinMode(echoPin, INPUT); // Sets the echoPin as an Input
      Serial.begin(9600); // Starts the serial communication
    }

    void loop()
    {
      // Clears the trigPin
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);

      // Sets the trigPin on HIGH state for 10 micro seconds
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);

      // Reads the echoPin, returns the sound wave travel time in microseconds
      duration = pulseIn(echoPin, HIGH);

      // Calculating the distance
      distance= duration*0.034/2;

      // Prints the distance on the Serial Monitor
      Serial.print("Distance: ");
      Serial.println(distance);
    }

title: Can i combine an ultrasonic sensor and gps together?

Answers: 1

body:
That's easy. I have no possibility to try it. But if your code has been working, this will also. (Just copy/paste.) I had to change the while loop into a if block, because I was not sure, if the while blocks for a longer time. It could have been that the GPS sends and sends and sends ... That would block the ultrasonic sensor.

    #include <TinyGPS++.h>
    #include <SoftwareSerial.h>

    static const int RXPin = 4, TXPin = 3;
    static const uint32_t GPSBaud = 9600;

    // The TinyGPS++ object
    TinyGPSPlus gps;

    // The serial connection to the GPS device
    SoftwareSerial ss(RXPin, TXPin);

    const int trigPin = 9;
    const int echoPin = 10;

    long duration;
    int distance;

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

      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
    }

    void loop()
    {
      // This sketch displays information
      // every time a new sentence is correctly encoded.
      if (ss.available() > 0)
      {
        gps.encode(ss.read());
        if (gps.location.isUpdated())
        {
          Serial.print("Latitude= ");
          Serial.print(gps.location.lat(), 6);
          Serial.print(" Longitude= ");
          Serial.println(gps.location.lng(), 6);
        }
      }

      // Clears the trigPin
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);

      // Sets the trigPin on HIGH state for 10 micro seconds
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);

      // Reads the echoPin, returns the sound wave travel time in microseconds
      duration = pulseIn(echoPin, HIGH);

      // Calculating the distance
      distance= duration*0.034/2;

      // Prints the distance on the Serial Monitor
      Serial.print("Distance: ");
      Serial.println(distance);
    }


body:
I have the following circuit

It has a simple dc motor that is OFF, and switches ON once a day for 2 seconds.

I use MOSFET IRF540N as a switch

I use L7805CV as a voltage regulator

I would like to have a review and to ask whether it is safe to connect this circuit to a 9v 1A (center+) DC wall plug.

I have measured the dc motor and it takes 60 mA when it is on with 5V.

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

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

title: arduino circuit review/ safety review

Answers: 3

body:
In general your circuit is fine, but the parts are pretty overpowered.
If there is a reasonable voltage drop at the IRF540N you better choose a mosfet with a lower gate-source threshold voltage, if it works I'd say it's fine.

body:
The "Arduino" part of your schematic looks OK. 9 VDC to VIN on the Uno is OK. Connecting the MOSFET directly to the Arduino is OK.

Personally, I would connect a 1000 ohm resistor in series between the Arduino pin and the gate of the MOSFET. If you like to live dangerously like I do, and change wiring connections with power supplied to your Arduino, then a 1k resistor will limit the maximum current flow to around 5 mA. This is not going to "fry" anything if you inadvertently connect an output to power or ground.

The question about the L7805CV is off-topic, but a quick look at the datasheet suggests an input and output capacitor should be used.

I’m sorry to be the bearer of bad news, but the IRF540N is a poor choice as a MOSFET to use with a micro-controller. While it’s true that you are only drawing 60 mA, the VGS specified for this MOSFET is at 10 VDC, not the 5 VDC supplied by the Uno. A "logic level" MOSFET would be better suited for your application.

For more information regarding MOSFETs, please read: [How to control a 12V solenoid valve with a mosfet?][1]

  [1]: https://electronics.stackexchange.com/questions/29065/how-to-control-a-12v-solenoid-valve-with-a-mosfet

body:
You should not use a "naked" L7805CV. That voltage regulator requires a couple of capacitors in order to build a functioning voltage regulator out of it. You should be able to find instructions online for how to build one. Search on "L7805CV circuit" and you should find quite a few sample circuits.

That said, 9V is a good unregulated voltage to provide to the Vin line on the Arduino. Its built-in voltage regulator should be able to regulate that to 5V quite well, even with "bobble" caused by motor. (The built-in voltage regulator is able to handle input voltages from 7.5V to 12V, although if you feed it 12V and draw a lot of current out of the 5V line you may have overheating problems.)

You should also use a "logic level" MOSFET that can be driven with a 5V gate voltage.


body:
I am trying to publish `JSON` data to mqtt with following code snippet

    #include <Arduino_JSON.h>
    JSONVar data;
    data["temperature"] = temperature;
    data["humidity"] = humidity;
    data["pressure"] = pressure;
    data["chipId"] = chipId;

    String jsonString = JSON.stringify(data);
    client.publish("esp32/data", jsonString);

But getting following error

    /home/ubuntu/Arduino/libraries/PubSubClient/src/PubSubClient.h:144:12: note:   candidate expects 4 arguments, 2 provided
    Multiple libraries were found for "PubSubClient.h"
     Used: /home/ubuntu/Arduino/libraries/PubSubClient
    Multiple libraries were found for "Wire.h"
     Used: /home/ubuntu/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/Wire
    Multiple libraries were found for "Adafruit_BME280.h"
     Used: /home/ubuntu/Arduino/libraries/Adafruit_BME280_Library
    Multiple libraries were found for "Adafruit_Sensor.h"
     Used: /home/ubuntu/Arduino/libraries/Adafruit_Unified_Sensor
    Multiple libraries were found for "SPI.h"
     Used: /home/ubuntu/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/SPI
    Multiple libraries were found for "Arduino_JSON.h"
     Used: /home/ubuntu/Arduino/libraries/Arduino_JSON
    Multiple libraries were found for "WiFi.h"
     Used: /home/ubuntu/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/WiFi
     Not used: /opt/arduino-1.8.10/libraries/WiFi
    exit status 1
    no matching function for call to 'PubSubClient::publish(const char [11], String&)'

Whats is wrong here ?

title: publish json data to mqtt

Answers: 1

body:
What's your last error message?
```
no matching function for call to 'PubSubClient::publish(const char [11], String&)'
```

[Read the documentation][1] for the `publish()` method in `PubSubClient`:

> int publish (topic, payload)
>
> Publishes a string message to the specified topic.
>
> Parameters
>
>   topic - the topic to publish to (const char[])
>
>   payload - the message to publish (const char[])

Look at the parameters you're using. You're passing a `String` as `payload`. `publish()` expects `payload` to be a `char[]` (essentially the same thing as a `char*`) - a C language string. This is the error you're seeing.

[Read the documentation][2] for `String`. How do you get a `char*` from a `String`? The `c_str()` method.

You need to change
```
client.publish("esp32/data", jsonString);
```

to
```
client.publish("esp32/data", jsonString.c_str());
```

As for your other warnings, it looks like your Arduino libraries are a mess with multiple conflicting libraries installed; if you want to get rid of the warnings, clean up your libraries.

  [1]: https://pubsubclient.knolleary.net/api.html#publish1
  [2]: https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/


body:
I followed a [guide][1] to control my arduino uno using a python web server API ([flask][2]), and it works like a charm using the COM port on my PC. I would like to extend this over the network with an ESP8266 module so i can have a web server handling my project's event scheduling and hard work using python/html/css/js (anything supported/needed) and have the arduino as a client receiving the server data and acting accordingly. I am not limited to this method as it seems pretty hard to generalize over the network (Use a virtual COM port on the server side and forward the arduino using the router?//i  have to specify where the arduino port is located) so any other way to setup a Web server handling the event triggering and sending the ON/OFF information to my arduino (i just need to trigger a relay) is accepted.

  [1]: https://www.instructables.com/id/Controlling-Arduino-with-python-based-web-API-No-p/
  [2]: https://www.palletsprojects.com/p/flask/

title: Extend Pyduino over wireless network

Answers: 0


body:
I am successfully communicating with my SIM800L from my UNOR3 aside form some errors. But the biggest problem is with the serial monitor.

Responses from the SIM800L are somewhat obfuscated in that some characters are randomly wrong. See a snippet below:
```
Initializing...

OK

+C⸮T'⸮⸮b⸮j

OK

88l4110068165694746f

O⸮

+CQEG:Y⸮⸮H⸮⸮*⸮⸮C⸮
ERROR
⸮> H⸮⸮*⸮⸮
F⸮ROR
H⸮⸮
ERRO
H⸮⸮*⸮⸮

```

My code is also below.
```
#include <SoftwareSerial.h>

//Create software serial object to communicate with SIM800L
SoftwareSerial mySerial(11,10); //SIM800L Tx & Rx is connected to Arduino #3 & #2

void setup()
{

  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(115200);

  //Begin serial communication with Arduino and SIM800L
  mySerial.begin(115200);

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

  mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
  updateSerial();
  mySerial.println("AT+CSQ"); //Signal quality test, value range is 0-31 , 31 is the best
  updateSerial();
  mySerial.println("AT+CCID"); //Read SIM information to confirm whether the SIM is plugged
  updateSerial();
  mySerial.println("AT+CREG?"); //Check whether it has registered in the network
  updateSerial();
  mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
  updateSerial();
  mySerial.println("AT+CNMI=1,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
  updateSerial();
  mySerial.println("AT+CMGS=\"+447518103652\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
  updateSerial();
  mySerial.print("System on!"); //text content
  updateSerial();
  mySerial.write(26);

  delay(1000);
}

int milli = millis();
void loop()
{
  if (digitalRead(2) == HIGH) {
    digitalWrite(3, HIGH);
  mySerial.println("AT+CMGS=\"+447518103652\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
  updateSerial();
  mySerial.print("Button Pressed!"); //text content
  updateSerial();
  mySerial.write(26);
  } else {
    digitalWrite(3, LOW);
  }

  if (milli <= millis() - 500) {
    updateSerial();
    milli = millis();
  }
}

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

The SIM800L runs off a separate power supply with a decoupling cap of 100n and the grounds are commoned.

title: Somewhat Obfuscated Serial With SIM800L and Uno R3

Answers: 1

body:
Here is a good documentation: https://lastminuteengineers.com/sim800l-gsm-module-arduino-tutorial/ --

Did you add a voltage divider to the RX pin?
If Arduino drive 5 Volt to the module's pin, the module might be destroyed.

The module has an automatic baud rate detection, so 115200 baud should be OK.
Do you configured your terminal with 115200 baud for the serial communication?

While sending, the Software Serial switches off all interrupts to make the micro clock more accurate. That might distort a timer interrupt for the hardware serial (but I don't really know, whether it needs one).

You changed the pins 2 and 3 for software serial (as from the example) to `SoftwareSerial mySerial(11,10);` Did you add the connections to the right pins. (RX?? <--> TX??)?

And last but not least. The axample uses 9600 baud for both serial interfaces. Perhaps your decision 115200 is too high.


body:
    if (!MDNS.begin("esp8266")) {
        Serial.println("Error setting up MDNS responder!");
        while (1) {
          delay(1000);
        }
      }

I know this will result in an infinite loop if the `if` conditional is never satisfied, however I was wondering if this code would still result in an infinite loop if say, after 3 iterations the `if` conditional is satisfied?

Or if something like:

    while(!MDNS.begin("esp8266")) {
       delay(1000);
    }

is different?

Code from: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266mDNS/examples/mDNS_Web_Server/mDNS_Web_Server.ino (line 58)

title: while(1) inside if conditional

Answers: 2

body:
In the first case, the first time, that the outer if statement becomes true, the code will go into the `while(1)` loop and will be stuck there forever.

The second code is different, since the `while` loop will check at each start of it's iteration, if the condition is still met. If not, it will exit, so not necessarily an infinite loop.

---

Going into an infinite loop, if something fails to initialize is often done in the microcontroller world, especially when initializing external hardware. A reset loop (restarting until it works) is mostly not fitting there, because often it is not just waiting for a resource to become free. Often this is used for serious problems, for example external hardware not being there or functioning. Imagine trying to use an external GPS chip, but the chip is not there. It should be there, since the device is build this way. Why should a reset loop be better here? The problem won't get away with time. Or imagine, that the initialization fails, because the GPS chip is broken. Trying to interface such a broken chip repeatedly might break even more things. Either way, someone has to look at this, to fix the problem. It will not go away by itself.

I would say, that the failed initialization in the library above is such a situation.

body:
This is likely a case where the original code needs to be inspected to understand the purpose of the infinite loop.  In the original code we see this:

      if (!MDNS.begin("esp8266")) {
        Serial.println("Error setting up MDNS responder!");
        while (1) {
          delay(1000);
        }
      }
      Serial.println("mDNS responder started");

Here, it can be inferred the infinite loop is used to preserve the error message on the serial monitor.  By doing so prevents subsequent messages from announcing the Domain Name Server has started.  Which may confuse the user.

As mentioned in other answers, infinite loops are often used to purposely reset a processor.  However, this approach depend on an actively running [watch dog][1] feature.  A feature that is not normally active or even supported in the Arduino development environment.  Perhaps because the watch dog feature is considered an intermediate to advanced topic.

  [1]: https://en.wikipedia.org/wiki/Watchdog_timer


body:
I've been trying to follow a few tutorials on how to get the 7 segment to display simple output but none seem to work 100%.

It starts out fine. It increments the number across the screen and then writes 8s to all of them and then reverses. After a few loops however it starts to act weird. Here's a video link where it acts a bit weird (a few digits don't write correctly and fix themselves) and then at the end, it only displays half of the 8 digit display before it goes to 8s and crashes. https://youtu.be/LD_C7I_bGyc

Here's the code:

    //We always have to include the library
    #include "LedControl.h"

    // pin 4 is connected to the DIN pin
    // pin 2 is connected to the CLK pin
    // pin 3 is connected to the CS pin
    // 1 as we are only using 1 MAX7219
    LedControl lc = LedControl(4, 2, 3, 1);

    void setup(){
        // the zero refers to the MAX7219 number, it is zero for 1 chip
        lc.shutdown(0, false);// turn off power saving, enables display
        lc.setIntensity(0, 0);// sets brightness (0~15 possible values)
        lc.clearDisplay(0);// clear screen
    }

    void loop(){
        // numbers 7 to 0
        for (int a = 0; a < 8; a++){
            lc.setDigit(0, a, a, false);
            delay(100);
        }
        delay(1000);
        // display number 8 on all segments
        for (int a = 0; a < 8; a++){
            lc.setDigit(0, a, 8, false);
            delay(100);
        }
        delay(1000);

        for (int a = 8; a >= 0; a--){
            lc.setDigit(0, a, a, false);
            delay(100);
        }
    }

Hardware:
   Arduino Uno: https://www.jaycar.com.au/duinotech-uno-r3-development-board/p/XC4410
   8 digit display: https://www.jaycar.com.au/8-digit-7-segment-display-module/p/XC3714

At this stage it's hard to tell if it's a hardware issue or if it's setup related. If someone could please give me some insight or maybe run it if they have the same hardware that would be fantastic.

Thanks!

title: 8 digit 7 segment display issues

Answers: 2

body:
The last loop exceeds the limits of 8 Digits. You iterate 9 times (0-8).

       for (int a = 7; a >= 0; a--){
            lc.setDigit(0, a, a, false);
            delay(100);
        }

body:
This was an unexpected result. @Dougie was pretty on to it. I didn't know how to adjust the timings as I was pretty sure the library took care of it, so the only thing I could think of was to redo all the wiring again. That's when I noticed that the ground wire pin into the board was half sticking out.

In the video you can see the ground pin at the top right. So it was making a connection (otherwise the whole thing wouldn't work), but after replacing the wire it runs fine. So that would have messed up the timings if the connection was unstable.


body:
I checked the [AT45DB321D datasheet](https://www.adestotech.com/wp-content/uploads/doc3597.pdf) and it says it operates at either 66 MHz oder 33 MHz. Both of these speeds are higher than what an Arduino Nano supports (my google fu fails me here, but according to the [Arduino SPI doc](https://www.arduino.cc/en/Reference/SPISetClockDivider) it's probably on the order of 4 MHz).

According to the datasheet

> Data can be clocked in from the input pin (SI) into either buffer 1 or buffer 2. To load data into the standard DataFlash buffer (528 bytes), a 1-byte opcode, 84H for buffer 1 or 87H for buffer 2, must be clocked into the device, followed by three address bytes comprised of 14 don’t care bits and 10 buffer address bits (BFA9-BFA0). The 10 buffer address bits specify the first byte in the buffer to be written. [...] Data will continue to be loaded into the buffer until a low-to-high transition is detected on the CS pin.

Which means to write a single byte I would need

- 1 opcode byte
- 3 address bytes
- 1 data byte

totaling 5 bytes or 40 bits which at 4 MHz yields 10 µs.

My code, as below, yields roughly 48 µs per byte (outputs a duration of ~12380 µs for transfering 256 bytes). I'm using the [DataFlash](https://github.com/BlockoS/arduino-dataflash) library.

```
#include <SPI.h>
#include "DataFlash.h"

static const int csPin    = 10;
static const int resetPin = 8;
static const int wpPin    = 7;

DataFlash dataflash;

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

  SPI.begin();

  dataflash.setup(csPin, resetPin, wpPin);
  dataflash.begin();

  long start = micros();
  dataflash.bufferWrite(0, 0);
  for(int i = 0; i <= 255; i++) {
    SPI.transfer(i);
  }
  long afterBuffer = micros();

  Serial.print("Writing 256 values to buffer: ");
  Serial.println(afterBuffer - start);
}

void loop()
{
  // nothing
}
```

It's very likely I'm missing something, but especially if I want to transfer larger chunks of data at once I'd like to speed up that process a bit. Creating a 256 byte buffer and writing it all at once

```
// outside time measurement
uint8_t buffer256[256];
for(int i = 0; i <= 255; i++) {
  buffer256[i] = i;
}
// inside time measurement
SPI.transfer(buffer256, 256);
```
takes roughly the same time.

__tl;dr:__ Is everything working correctly/what am I doing wrong? How can I speed up writing to a flash chip using an Arduino Nano?

title: How fast should I be able to write to AT45DB321D flash memory?

Answers: 1

body:
> "Data will continue to be loaded into the buffer until a low-to-high
> transition is detected on the CS pin."

The `dataflash.bufferWrite` command writes the opcode and address bytes and then in the `for` loop you write 256 data bytes. The data bytes are written at once, without preceding each single one with the opcode and the address. (So it does already what you want to do.)

It doesn't matter whether you write the byte at once or each with a single SPI write. SPI can only send them sequentially. And the initial opcode and address is only send once with the `dataflash.bufferWrite` command.

BTW: There are two buffers to write to 1 and 2. So I'm curious why the command `dataflash.bufferWrite(0, 0);` works. IMHO that should be `dataflash.bufferWrite(1, 0);` or `dataflash.bufferWrite(2, 0);`.

You also not start the internal writing to the pages. There is no command e.g. `dataflash.bufferToPage(1, 7);`. The data are only transfered into the flash's buffer.

Because data is not written into a memory page, you'll lose it, if you switch off the power.

**UPDATE**

I fear I understood your question not completely. As I now see, you wondered why you need 48 µs in average for 256 Bytes when the SPI Bus is driven with 4MHz.

I looked a little in the codes and docs. And that's what I found:

The DataFlash lib selects a different Clock divider:

    /* Setup SPI */
    SPI.setDataMode(SPI_MODE3);
    SPI.setBitOrder(MSBFIRST);
    SPI.setClockDivider(SPI_CLOCK_DIV2);

`SPI_CLOCK_DIV2` results after some computation to a frequency of Fosc/2. The computation are very difficult to follow, because they use an 8 bit number which is divided into 2 nibbles each of them defines a part of a register content. But I'm quite sure the result is Fosc/2. But that would result in a clock frequency of 8 MHz. That can not explain your observed timings.

BTW: There is also in interesting deprecation note about setting the clock speed this way. ;-)

      // This function is deprecated.  New applications should use
      // beginTransaction() to configure SPI settings.
      inline static void setClockDivider(uint8_t clockDiv) {
        SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);
        SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);
      }

But then I saw another thing that could be a problem. There are to single value transfer functions. One for bytes (uint8_t) and one for integers (uint16_t). Your count variable is an integer so the two byte transfer method is used, resulting in two byte per transfer and therefor 512 bytes. But that also no explanation for the observations. And writing buffers works only with uint8_t[] so ??.

What else could have happened?

The MCU could be clocked by a lower frequency then 16MHZ. I think there are fuses that can be configured to reduce the master clock speed for using the MCU with lower voltage (like 3.6 Volt).

The missing beginTransaction / endTransaction (DataFlash doesn't use this) of the SPI bus could have impact on the interrupts which could distort the timing. (But that's a very wild guess ;-))

The observation that, transferring twice the amount of data with the single int transfer method does take roughly the same time than the buffered method gives us a hint, that possibly the SPI speed is not the problem.

In the function `dataflash.bufferWrite(0, 0);` there is e.g. a wait function
`waitUntilReady();` that could cause a long delay of ~12 milli seconds. You can easily try that, by taking the `dataflash.bufferWrite(0, 0);` out of the timing.

    void DataFlash::waitUntilReady()
    {
        while(!isReady()) {};
    }

    uint8_t DataFlash::isReady()
    {
        return status() & AT45_READY;
    }

    uint8_t DataFlash::status()
    {
        uint8_t status;
        reEnable();     // Reset command decoder.
        SPI.transfer(DATAFLASH_STATUS_REGISTER_READ);
        status = SPI.transfer(0);
        disable();
        return status;
    }


body:
I am trying to get data from this type of scale
https://acaia.co/products/pearl. It does not show up under discover-able Bluetooth devices on a computer or phone, but it does have an app which it connects to automatically when turned on; the app can then display the weight in real time. This is my first time working with Bluetooth devices and am unsure as to how it is connecting to the app without showing up on other devices. Any information as to what is going on and possibly steps in the right direction would be greatly appreciated.

title: Get data from Bluetooth scale

Answers: 1

body: What you need to do is do some bluetooth sniffing to find out how the device is communicating with the phone. Here is a good article on doing that : http://nilhcem.com/iot/reverse-engineering-simple-bluetooth-devices


body:
I realize this gets asked a lot, but I feel like I've applied the most common fixes without success. I have 10 10k potentiometers plugged in to an arduino via a custom shield. 2 are wired directly to the MC via A2 and A3. The other 8 are plugged in via a 74HC4051 multiplexer. The 2 plugged in directly work great. The other 8 show a ton of cross talk and don't seem to vary as much as they should. Here is some example output on the arduino serial plotter:

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

Things I have tried:

 1. I put a delay between the pin selection and the read.
 2. I'm reading twice (with a delay in between) and discarding the first read.

I'd use an MCP2308 if I were doing this again, but in the mean time is there anything else I can try?

Here is my schematic:

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

Each pot is plugged in to 5V and ground, with the wiper wired directly to the pin, all via jumper cables to the shield. Here's a picture of how this works (apologies for the mess):

[![Board Picture][3]][3]

The pin blocks have, per row, one pin each feeding in to a multiplexer input, and another attached to the GND and +5V planes on the PCB. These are attached to +5V and GND on the arduino:

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

Here is my code:

    const int selectPins[3] = {8, 12, 13}; // S0, S1, S2
    const int zInput = A1; // Connect common (Z) to A1 (analog input)
    const int DIMp = A2;
    const int bDIMp = A3;
    void setup()
    {
      Serial.begin(9600); // Initialize the serial port
      // Set up the select pins as outputs:
      for (int i=0; i<3; i++)
      {
        pinMode(selectPins[i], OUTPUT);
        digitalWrite(selectPins[i], HIGH);
      }
      pinMode(zInput, INPUT);
      pinMode(DIMp, INPUT);
      pinMode(bDIMp, INPUT);
    }

    // The selectMuxPin function sets the S0, S1, and S2 pins
    // accordingly, given a pin from 0-7.
    void selectAMuxPin(byte pin)
    {
      for (int i=0; i<3; i++)
      {
        if (pin & (1<<i))
          digitalWrite(selectPins[i], HIGH);
        else
          digitalWrite(selectPins[i], LOW);
      }
    }

    void loop()
    {
      // Loop through the hard wired dimmers
      Serial.print(String(analogRead(DIMp))+" ");
      Serial.print(String(analogRead(bDIMp))+" ");
      // Loop through all eight pins.
      for (byte pin=0; pin<=7; pin++)
      {
        selectAMuxPin(pin); // Select one at a time
        delayMicroseconds(500); // delay after pin select
        int inputValueb = analogRead(zInput); // read Z
        delayMicroseconds(150); //delay after first read
        inputValueb = analogRead(zInput); // read Z again
        Serial.print(String(inputValueb) + " ");
      }
      Serial.println();
    }

  [1]: https://i.stack.imgur.com/U7FkJ.png
  [2]: https://i.stack.imgur.com/vNLbK.png
  [3]: https://i.stack.imgur.com/MQxnz.png
  [4]: https://i.stack.imgur.com/0BOnT.png

title: Can't figure out source of interference reading 10k POTs with 74HC4051

Answers: 0


body:
I want to split a received binary data into two binary data.

Take the following received binary data for instance:

    uint32_t data = 0xFFFF0001;

In binary format it is: 11111111111111110000000000000001

If we need to split this above binary into two new binary data how could it be done?

As an example from the 0xFFFF0001, how can we obtain the first 17-bit as as data1 = 11111111111111110 and then the remaining 15-bit as data2 = 000000000000001 ?

title: How to split a binary data to form two split binary data?

Answers: 1

body:
You can use the `bit shift` and `and` operator, like:

    uint32_t data = 0xFFFF0001;

The following line will shift all bits 15 places to the right, meaning the least significant 15 bits will be removed, and the other bits shifted to the right.

    uint32_t dataLeft = data >> 15;

    11111111111111110000000000000001
    >>>>>>>>>>>>>>>11111111111111110000000000000001
    | Bit shift   || orig. bits    ||Removed bits |

For the other 15 bits,  you can use the `and` operator, which just makes all 1's 0's for those bits not in the bit mask (0x7FFF).

    uint16_t dataRight = data & 0x7FFF;

    value:              11111111111111110000000000000001
    bit mask (0x7FFF):  00000000000000000111111111111111
                        -------------------------------- & / AND
                        00000000000000000000000000000001


body:
can someone tell me why my L led on arduino uno glowing continuously I tried restarting my pc, changing USB port
I also tried uploading an empty file and resetting the  Arduino board but nothing seems to work. Does it mean I have to buy a new one?

title: Arduino L led glows continuously

Answers: 1

body:
Don't let that pin float undefined: If undefined (INPUT), pull it to GND to have the led OFF.

If ever possible, try to use the LED_BUILTIN pin as an OUTPUT pin.

And signal some information there. On an UNO (or other 328-based Arduino), this hint might collide with the SPI_SCK pin, which is D13 (PB5 on an atmega328). But as an SPI Master, this pin is at least OUTPUT (and thus will signal SPI activity).


body:
I am not super experienced with c++ and I know that the syntax for C++ and the code written/compiled by the arduino IDE are slightly different.

----------

I would like to be able to write code, compile it the same way the arduino IDE does, and run it, without uploading it to a board.

----------

I dont need to test any code that interacts with any hardware. I simply want to be able to test basic syntax to make sure my concepts work before integrating with the full program.

I have written a few Arduino programs and I think the most complicated thing I've used were pointer functions, but I'd like to be able to test out code without needing to upload to a board for every change, while relying on Serial.print.

I have found alternatives that help with debugging and although that is helpful, I'd like to avoid the need to upload to a board every time I want to test changes for basic concepts

title: Alternative IDE for compiling and running arduino code?

Answers: 2

body:
You can use any C++ IDE you like, best when bundled with a compiler, for example Code::Blocks. Assuming you're using Windows: A combination of a decent editor like Notepad++ and some good compiler chain like MinGW will do, too. If you absolutely have to you could also use MS Visual Studio, I don't bother.

Then create standard console programs with this `main()`:

    void setup();
    void loop();

    int main()
    {
        setup();
        for (;;)
        {
            loop();
        }
    }

And append your hardware-less Arduino code.

body: [PlatformIO](https://platformio.org/platformio-ide) is a plugin for Visual Studio Code that has support for many embedded device, including most Arduinos


body:
My cat feeder works like that:

  1. LCD shows real time clock
  2. Press a push button
  3. LCD shows you to put the feeding time
  4. You put the feeding time through a matricial keyboard
  5. When feeding time is reached, a servo motor open the food container

The problem with my project is when the feeding time is reached, the servo motor doesn't open the food container! I'll put my code below, can you guys help me!! It's a project for college!!

    #include  DS3231.h>
    #include  Servo.h>
    Servo microservo9g;
    #include  LiquidCrystal.h>
    #include  Keypad.h>
    #include  Wire.h>

    const byte ROWS = 4; // Four rows
    const byte COLS = 4; // Three columns

    // Define the Keymap

    char hexaKeys[ROWS][COLS] = {
      {'1','2','3','A'},
      {'4','5','6','B'},
      {'7','8','9','C'},
      {'*','0','#','D'}
    };

    // Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.

    byte rowPins[ROWS] = {2, 3, 4, 5};

    // Connect keypad COL0, COL1 and COL2 to these Arduino pins.

    byte colPins[COLS] = {6, 7, 8, 9};

    //  Create the Keypad
    Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS );
    DS3231  rtc(A4, A5);
    LiquidCrystal lcd(A0, A1, A2, 11, 12, 13); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7)
    Time t;

     //int angle = 0;
    // int potentio = A0;      // initialize the A0analog pin for potentiometer
     int t1, t2, t3, t4, t5, t6;

    boolean feed = true; // condition for alarm

     char key;
     int r[6];

     void setup()
     {
      microservo9g.attach(10);
      lcd.begin(16,2);
      microservo9g.write(0);
      Serial.begin(9600);
      rtc.begin();
      pinMode(A0, OUTPUT);
      pinMode(A1, OUTPUT);
      pinMode(A2, OUTPUT);
     }

     void loop()
     {
    lcd.clear();
    lcd.setCursor(0,0);
    int buttonPress;
    buttonPress = digitalRead(A3);

    if (buttonPress==1)
     setFeedingTime();
     char customKey = customKeypad.getKey();

    //Serial.println(buttonPress);

     lcd.print("Time:  ");
     String t = "";
     t = rtc.getTimeStr();
     t1 = t.charAt(0)-48;
     t2 = t.charAt(1)-48;
     t3 = t.charAt(3)-48;
     t4 = t.charAt(4)-48;
     t5 = t.charAt(6)-48;
     t6 = t.charAt(7)-48;

     lcd.print(rtc.getTimeStr());
     lcd.setCursor(0,1);
     lcd.print("Date: ");
     lcd.print(rtc.getDateStr());

     if (t1==r[0] && t2==r[1] && t3==r[2] && t4==r[3]&& t5<1 && t6<3 && feed==true)
     {
      microservo9g.write(90);
     //command to rotate the servo to the specified angle

      delay(400);
      microservo9g.write(0);
      feed=false;
     }
     }

    void setFeedingTime()
    {
      feed = true;
       int i=0;

      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Set feeding Time");
      lcd.clear();
      lcd.print("HH:MM");
      lcd.setCursor(0,1);

      while(1){

    key = customKeypad.getKey();

      char j;

     if(key!=NO_KEY){

      lcd.setCursor(j,1);

      lcd.print(key);

       r[i] = key-48;
        i++;
        j++;

     if (j==2)
        {

      lcd.print(":"); j++;
        }

       delay(500);
      }

     if (key == '*')

     {key=0; break; }
      }
    }

title: Arduino cat feeder

Answers: 0


body: I'm wondering if one needs to assign a bit-stream of 78 bits to a variable(later on to be processed), what datatype can be used? What is the max bit can be stored into a variable in C?

title: What kind of data type can be use store a binary bit-stream which is more than 64-bits?

Answers: 1

body:
There is no builtin data type that can store 78 bits. However, it depends a bit what you want to store. Like the following cases:

- If the 78 bits are one 'entity' (e.g. one really big value), you can store it as an array of bytes (10 bytes of 8 bits = 80 bits, leaving 2 bits unused)
- If the 78 bits can be split up in smaller parts, you can:
  - Create a structure or class to contain the sub elements into fields (instance variables), using for each sub type a normal type (e.g. signed/unsigned 8, 16 or 32 bits).
  - Create bit fields to save some memory if there are small items and memory space is an issue.
  - Or a combination of the above

If you have many of these items and you want to save space (thus the 2 unused bits of each 80 bits), you can create a big array that contains many items, and use bit operations to get each item. E.g. the first element will be in the first 10 bytes, where the last 2 bits are not part of the element. The second item will use the remaining 2 bits and the following 78 - 2 = 76 bits, etc. This saves only 2/80 * 100% = 2.5% so only use this when really needed.


body:
I have an Arduino AT MEGA 2560 circuit. I want to buy 1 Nema-17 bipolar stepper motors, 3 M49SP-2K stepper motors, 3 KY-032 sensors to do my project but i dont know how to connect them to my Arduino.
Is there any Arduino shield for my purpose? Can I use Ramps 1.4 Arduino shield?

title: How can i connect 4 stepper motors and 3 sensors to an Anduino?

Answers: 1

body:
Take a look at the Ramps V1.6, it is what I use. It plugs onto the AT Mega board.

https://reprap.org/wiki/RAMPS_1.6

The 1.6 has a few improvements. I like the solder in power connectors rather than the plug in ones. More reliable.

Because I already had the AT Mega board I decided to try the ramps. There are better boards now, with 32 bit processors. But as a starting point the Ramps combo is the simplest to get going and it does the job.

Other boards may work out a little better, but the firmware is a bigger issue. Still in development.


body:
I am making a police light and siren but the delay on light (); affects the buzzers  delay tone

This is the code:
```
//PIN 9 - Buzzers
int f,d;
int t =0;

void setup()
{
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
}

void loop()
{
    buzzer ();

}

void buzzer () {

  for(f=635;f<=912;f++)
    {
        tone(9, f);
        delay(d);
        d=10;

        light ();
    }

    for(f=911;f>=634;f--)
    {

        light ();
        tone(9, f);
        delay(d);
            d=9;

    }

}

void light() {
 digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  delay(t);

  digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  delay(t);

  digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  delay(t);

  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

  digitalWrite(5,HIGH);
  digitalWrite(6,HIGH);
  digitalWrite(7,HIGH);

  delay(t);

  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
  digitalWrite(7,LOW);

  delay(t);

  digitalWrite(5,HIGH);
  digitalWrite(6,HIGH);
  digitalWrite(7,HIGH);

  delay(t);

  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
  digitalWrite(7,LOW);

  delay(t);

  digitalWrite(5,HIGH);
  digitalWrite(6,HIGH);
  digitalWrite(7,HIGH);

  delay(t);

  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
  digitalWrite(7,LOW);

  delay(t);

  digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

  digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

  digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

  digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

}

```

title: How to run led and buzzer at the same time?

Answers: 2

body: Don't use `delay()`. You'll need to rewrite your sketch to use the `millis()` function to decide when the desired amount of time has passed. Search on "Arduino Blink Without Delay" for information.

body:
The following Code is not tested. You can take it as an example. If you find errors, it would be nice to report them, so I can correct my prog.

    // here I just guess (10msec), I think you don't want a delay
    // of 0 as in your code.
    int   blinkDelay        = 10;
    long  lastBlinkTime     =  0;
    int   patternSequence[] = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 2, 1, 2, 1, 2, 1, 2 };

    int   patternSize     = 17;
    int   actPattern      =  0;
    int   delActive       = -1;

    int  frequency     = 635;
    int deltaFreq      =   1;
    int  toneDelay     =  10;
    long lastBuzzTime  =   0;

    void setup()
    {
      pinMode( 5, OUTPUT ) ;
      pinMode( 6, OUTPUT ) ;
      pinMode( 7, OUTPUT ) ;

      ledsOff();
      buzzer( frequency );
    }

    void loop()
    {
      int actTime = millis();

      if ( ( actTime - lastBlinkTime ) > blinkDelay )
      {
        if ( delActive > 0 )
        {
          ledsOff();
        }
        else
        {
          actPattern++;
          if( actPattern > ( patternSize - 1) ) actPattern = 0;
          pattern( patternSequence[ actPattern ] );
        }
        delActive *= -1;

        lastBlinkTime = actTime;
      }

      if ( ( actTime - lastBuzzTime ) > toneDelay )
      {
        frequency += deltaFreq;

        if ( frequency > 911 ) deltaFreq = -1;
        if ( frequency < 636 ) deltaFreq = 1;

        buzzer( frequency );
        lastBuzzTime = actTime;
      }

    }

    void buzzer( int freq )
    {
      //PIN 9 - Buzzer
      tone(9, freq);
    }

    void ledsOff()
    {
      digitalWrite( 5, LOW );
      digitalWrite( 6, LOW );
      digitalWrite( 7, LOW );
    }

    void pattern( int num )
    {
       switch ( num )
       {
          case 0:
            ledsOff();
            break;

          case 1:
            digitalWrite( 5, HIGH );
            break;

          case 2:
            digitalWrite( 7, HIGH );
            break;

          case 3:
            digitalWrite( 5, HIGH );
            digitalWrite( 6, HIGH );
            digitalWrite( 7, HIGH );
            break;
       }
    }

**Update**

I've tested the code at home on my esplora. It worked, but not for a long time. I had to change the timing logic, by using the method `millis()`directly. Now it works. Below is the new code; tested this time. I also introduced some constants on top, because the their names act as documentation ;-). And I experimented with the values. The actual values are my preferences, But I'm by far no Bethoven and can not say if this relly sounds like a police siren. At least, it sounds not like a german police siren which I know better. (No I'm meither a policement nor his/her customer ;-))

Because I tested the code on my Esplora, I had to change the Pin assignments  (now out commented). In this copy I changed back to the original ones.

    int   blinkDelay        = 100;
    long  lastBlinkTime     =  0;
    int   patternSequence[] = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 2, 1, 2, 1, 2, 1, 2 };

    int   patternSize     = 17;
    int   actPattern      =  0;
    int   clearActive       = -1;

    int  lowerFreq       = 680;
    int  higherFreq      = 840;
    int  deltaFreq       =   2;
    int  toneDelay       =  20;
    int  toneDelayOffset =  -1;
    long lastBuzzTime    =   0;

    int  actFreqStep   = deltaFreq;
    int  actFreq       = lowerFreq;

    // orig pins
    int col1Pin   =  5;
    int col2Pin   =  6;
    int col3Pin   =  7;
    int buzzerPin =  9;

    // esplora pins
    // int col1Pin   =  5;
    // int col2Pin   = 10;
    // int col3Pin   =  9;
    // int buzzerPin =  6;

    void setup()
    {
      pinMode( col1Pin, OUTPUT ) ;
      pinMode( col2Pin, OUTPUT ) ;
      pinMode( col3Pin, OUTPUT ) ;

      // initialize LEDs off
      ledsOff( );

      // and buzzer to the act frequency
      buzzer( actFreq );
    }

    void loop()
    {
      if ( ( millis() - lastBlinkTime ) > blinkDelay )
      {
        if ( clearActive > 0 )
        {
          ledsOff();
        }
        else
        {
          actPattern++;
          if( actPattern > ( patternSize - 1) ) actPattern = 0;
          pattern( patternSequence[ actPattern ] );
        }

        clearActive     *= -1;
        lastBlinkTime  = millis();
      }

      if ( ( millis() - lastBuzzTime ) > ( toneDelay + toneDelayOffset ) )
      {
        actFreq += actFreqStep;

        if ( actFreq >= higherFreq )
        {
          actFreqStep   = -1 * deltaFreq;

          // down sweep is slower
          toneDelayOffset = -1;
        }

        if ( actFreq <= lowerFreq )
        {
          actFreqStep   =  deltaFreq;
          toneDelayOffset =  0;
        }

        buzzer( actFreq );
        lastBuzzTime = millis();
      }

    }

    void buzzer( int freq )
    {
      tone( buzzerPin, freq );
    }

    void ledsOff()
    {
      digitalWrite( col1Pin, LOW );
      digitalWrite( col2Pin, LOW );
      digitalWrite( col3Pin, LOW );
    }

    void pattern( int num )
    {
       switch ( num )
       {
          case 0:
            ledsOff();
            break;

          case 1:
            // red
            digitalWrite( col1Pin, HIGH );
            break;

          case 2:
            // blue
            digitalWrite( col3Pin, HIGH );
            break;

          case 3:
            // white
            digitalWrite( col1Pin, HIGH );
            digitalWrite( col2Pin, HIGH );
            digitalWrite( col3Pin, HIGH );
            break;
       }
    }


body:
**Question (TL;DR): what is the optimal method to deep sleep (to run an ATtiny45 or ATmega on batteries for 1+ year) but still be able to detect a button press?** Is it possible to deep sleep *until* a button is pressed?

I'm using a classic "debounce" method to detect a button press:

~~~
int buttonState;
int lastButtonState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

void setup() {
  pinMode(2, INPUT);
}

void loop() {
  int reading = digitalRead(2);
  if (reading != lastButtonState) { lastDebounceTime = millis(); }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == HIGH) {
         // Button pressed, do something here!
         // In my actual code, it sends a packet via RF 433 Mhz
      }
    }
  }
  lastButtonState = reading;
  // snore(20);          // TinySnore here
}
~~~

My ATtiny45 should run during 1 year on 3 AA batteries, so I added a deep sleep using [TinySnore](https://github.com/connornishijima/TinySnore/blob/master/src/tinysnore.cpp). It works, and made the consumption go from more than 1mA to 0.2mA (@1 Mhz).

I know it's possible to go down to 5 µA if I `snore(1000);` but then obviously it won't be able to detect a button press.

I tried various sleep values: `snore(10);`, `snore(20);`, `snore(50);`, etc. but I didn't get consistent results.

Thus the question: **how to deep sleep *until* a button is pressed?**

____

I was thinking about using [`attachInterrupt()`](https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/) but then what kind of sleep should we use? `snore()`? `delay()`?

title: How to deep sleep ATtiny/ATmega (to run for years with batteries) but still detect a button press?

Answers: 3

body:
First I was [unable to make the intterupt work for multiple pins](https://arduino.stackexchange.com/questions/70292/how-to-assign-an-interrupt-to-a-button-press-with-an-attiny-interrupt-not-fire), but finally here is a working code:

~~~
#include <avr/interrupt.h>
#include <avr/sleep.h>

ISR(PCINT0_vect) {
  if (digitalRead(0) == LOW)           // # PB0 = pin 5 pressed => LED on
    digitalWrite(4, HIGH);
  else if (digitalRead(1) == LOW)      // # PB1 = pin 6 pressed => LED off
    digitalWrite(4, LOW);
  else if (digitalRead(2) == LOW)      // # PB2 = pin 6 pressed => LED on
    digitalWrite(4, HIGH);
}

void setup() {
  pinMode(4,OUTPUT); // LED
  pinMode(0,INPUT_PULLUP);
  pinMode(1,INPUT_PULLUP);
  pinMode(2,INPUT_PULLUP);
  ADCSRA = 0; // ADC disabled
  GIMSK = 0b00100000;  // General Interrupt Mask Register, / Bit 5 – PCIE: Pin Change Interrupt Enable / When the PCIE bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin change interrupt is enabled. Any change on any enabled PCINT[5:0] pin will cause an interrupt. The corresponding interrupt of Pin Change Interrupt Request is executed from the PCI Interrupt Vector. PCINT[5:0] pins are enabled individually by the PCMSK0 Register. / see https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf
  PCMSK = 0b00000111;
}

void loop() {
  sleep_enable();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_cpu();
}
~~~

Note: [PCINTs are handled by a single PCINT_vect](https://arduino.stackexchange.com/questions/70348/pcint0-pcint1-pcint2-etc-on-attiny45-85/70351#70351) here.

PS: as mentioned by Maximilian in a comment, this post gives nice solutions: [Detecting key presses on a keypad whilst asleep](https://www.gammon.com.au/forum/?id=11497&reply=4#reply4).

body:
ATTINY's are designed to easily do this since they can wake from `power down` sleep mode by a pin change...

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

Basically you want to...

1. Connect a normally-open push button between an IO pin and ground.
2. Enable the pull-up on the IO.
3. Enable the pin change interrupt on the IO pin.
4. Enable interrupts.
5. Enter "power down" sleep mode.

When the button is pushed, it will connect the IO pin to ground, which will cause a pin change interrupt, which will wake the chip from sleep.

Note that you do not need to do anything in the pin change ISR (you can use the `EMPTY_INTERRUPT` compiler macro). If the ISR is empty, execution will pick up on the line after the sleep upon waking.

While in deep sleep, the chip will use an astonishingly small amount of power.  For example, an ATTINY25/45/85 running off of a 3V coin cell at room temp will use less than 0.2uA...

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

A typical CR2032 coin cell is rated for 235mAh to 2V, so at this rate we'd expect to be able to wait for a button press like this for [100+ years][3].

IRL the battery will likely self discharge and physically deteriorate long before then (rated at 1% per year), but still not too shabby.

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

  [1]: https://i.stack.imgur.com/8dnWb.png
  [2]: https://i.stack.imgur.com/2BkpN.png
  [3]: https://frinklang.org/fsp/frink.fsp?fromVal=(235 milli amp hours) / (0.2 microamp)&toVal=years#calc
  [4]: https://i.stack.imgur.com/26ahf.png

body: I would put the MCU in deep sleep and then use the reset button.


body:
I am 100% new to Arduino.  I am using the Pro Mini 328P 3.3v 8mhz board.  I can successfully write to the board once with the Blink program. I set the FTDI to 3.3v jumper. It works.  Then if I try to upload again (I changed the timing on the blink) I get the getsync error.  I tried two boards they both fail after the first upload.  I am using Win 10.

This is the error I see:
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xaf

title: Can only program Pro Mini board once then error getsync()

Answers: 0


body:
I'm using a NEMA 17 stepper motor with A4988 motor driver and Arduino Uno board. I have used full microstepping (1/16th, so one revolution = 3200 steps).

I'm coming across this strange problem. Whenever I upload any code, for example

    void loop()
    {  delay(20);
       digitalWrite(stepPin, HIGH);
       delayMicroseconds(100);
       digitalWrite(stepPin, LOW);
       delayMicroseconds(100);
    }

the motor spins rapidly for about 1000 steps clockwise (before "avrdude done. Thank you." appears), and then executes the code. When a similar code is placed in void steup() with an empty void loop (), the same thing happens - motor spins rapidly, executes what's written and then stops. The initial rapid spinning is always the same speed and direction, no matter what code is uploaded.

When I upload empty code -

    void setup() {}
    void loop() {}

the motor continuously spins rapidly with the same speed, same direction. If I add a delay(1000) anywhere in the above program, same thing happens. When I long/short press the reset button on the board, same thing happens. When I upload programs unrelated to the motor, like the example Blink program, same thing happens. Buddy of mine told me to upload the eeprom_clear program from Examples, same thing happened.

I tried uploading this program -

    void setup(){
    for (int i=0; i<=13; i++)
      {pinMode(i,OUTPUT);
      digitalWrite(i,LOW);

      }

    }
    void loop(){}
and motor spun like crazy while uploading (same ~1000 steps, clockwise direction) and then stopped. Uploading any program after this has same behaviour. If it an empty/delay only program, motor spins crazily forever. If it is a specific program (example - run for 1000 steps), it spins crazily while uploading, executes the main program, then stops.

As I'm typing this, the motor is spinning like a crazed maniac even though I just uploaded an empty `void setup() {} void loop() {}` program.

I've tried changing the computer that the Arduino is connected to, I've changed the motor driver and plugged in a brand new one, I've changed the USB cable, I've changed the motor and I've reset all Arduino and breadboard connections. I went to Device Manager > Ports (COM & LPT) > USB-SERIAL CH340(COM5) and updated driver. Current Arduino IDE is Arduino 1.8.10 on Windows 10.

No change in outcome. This problem has been spoiling my sleep for the past few nights as I can't upload anything to the board without the Arduino either spinning crazily endlessly or spinning crazily just while uploading and then behaving properly.

Any solutions? Thanks a lot!

Edit - Added schematic of the electronics connections. Original image from www.lastminuteengineers.com

[![Schematic of the electronics connections. Original image from www.lastminuteengineers.com ][1]][1]

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

title: Motor keeps spinning crazily after UNO board reset

Answers: 0


body:
*([Here](https://arduino.stackexchange.com/questions/70284/how-to-deep-sleep-attiny-atmega-to-run-for-years-with-batteries-but-still-dete/70289#70289) is finally a solution)*.

I'm using the following code on a ATtiny45 to **assign an interrupt to a button press** (pin #7, PB2, INT0). However the LED doesn't blink when the button is pressed, as if the interrupt is not working. **Why?**

Note: I'd like to use the least power when no interrupt happens, to [have a current in the order of magnitude of ~ 1 µA, to run from batteries for years](https://arduino.stackexchange.com/questions/70284/how-to-deep-sleep-attiny-atmega-to-run-for-years-with-batteries-but-still-dete/70296#70296).

~~~
#include <avr/sleep.h>

void setup()
{
  pinMode(4, OUTPUT);  // LED
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);      // pin #7 = PB2
  digitalWrite(4, HIGH); delay(100); digitalWrite(4, LOW);  // LED blink, working here
}

void wake()
{
  sleep_disable();
  detachInterrupt(0);
  digitalWrite(4, HIGH);  // LED not working here when pressing the button
}

void loop()
{
  sleep_enable();
  ADCSRA = 0;
  attachInterrupt(0, wake, CHANGE);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_cpu();
}
~~~

Note:

* I'm using Arduino IDE with [damellis' attiny](https://github.com/damellis/attiny), I also tried with Spence Konde's ATtinyCore but it's the same

* In my real code, I have 3 buttons, on pin #5, #6, #7, so eventually I'd like to have interrupts for all these three pins.

* I've read https://gammon.com.au/forum/?id=11497 but using `noInterrupts()` / `interrupts()` did not change anything in my case.

* I've tried "Sketch J" from https://gammon.com.au/forum/?id=11497 but `EIFR = bit (INTF0);` gives an `error: 'EIFR' was not declared in this scope` (I'm compiling from Arduino IDE); probably this works on an ATmega but not ATtiny.

---

**Edit: Here is a working code of deep sleep, with an interrupt when the pin #5 (PB0) changes...**

~~~
#include <avr/interrupt.h>
#include <avr/sleep.h>

ISR(PCINT0_vect) {
  if (digitalRead(0) == LOW)
    digitalWrite(4, HIGH);
  else
    digitalWrite(4, LOW);
}

void setup() {
  pinMode(4,OUTPUT); // LED
  pinMode(0,INPUT_PULLUP);
  pinMode(1,INPUT_PULLUP);
  pinMode(2,INPUT_PULLUP);
  ADCSRA = 0; // ADC disabled
  GIMSK = 0b00100000;  // General Interrupt Mask Register, / Bit 5 – PCIE: Pin Change Interrupt Enable / When the PCIE bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin change interrupt is enabled. Any change on any enabled PCINT[5:0] pin will cause an interrupt. The corresponding interrupt of Pin Change Interrupt Request is executed from the PCI Interrupt Vector. PCINT[5:0] pins are enabled individually by the PCMSK0 Register. / see https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf
  PCMSK = 0b00000111;  // Pin-change interrupt for PB0, PB1, PB2
}

void loop() {
  sleep_enable();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_cpu();
}
~~~

**...but for an unknown reason, if I add this code:**

    ISR(PCINT1_vect) {
      if (digitalRead(1) == LOW)
        digitalWrite(4, HIGH);
      else
        digitalWrite(4, LOW);
    }

the pin-change interrupt for PB0 still works (PCINT0), but not the interrupt for PB1 (PCINT1). Why?

title: How to assign an interrupt to a button press with an ATtiny? (interrupt not fired with my code)

Answers: 1

body:
Look at the datasheet of the ATtiny45. In the section “Sleep Modes”,
there is a table that lists the wake-up sources available for each sleep
mode. For the mode “power-down”, INT0 is listed as a possible wake-up
source, but there is a small footnote:

> For INT0, only level interrupt.

This means that the `CHANGE` mode you are trying to use will not wake-up
the MCU out of power-down. You have to instead

```c++
attachInterrupt(0, wake, LOW);
```

> In my real code, I have 3 buttons, on pin #5, #6, #7, so eventually
> I'd like to have interrupts for all these three pins.

You may then have to look into the “pin-change” interrupt. This is
something different from the INT0 you are using here, and is not
generally supported by the Arduino core. You will have to either get
some pin-change-interrupt library, or work with no library using the
information from the datasheet (not that hard). Pin-change interrupt is
also a wake-up source for power-down.

------------------------------------------------------------------------

**Edit**: Answering extra questions from comments.

> How did you know that "only level interrupt" means only "LOW"?

The [Arduino documentation][arduino-doc] states that the `mode`
parameter of `attachInterrupt()` can be either `LOW`, `CHANGE`, `RISING`
or `FALLING`. A few boards also support `HIGH`, but the ATtinies are not
among them. A “level” can be either `LOW` or `HIGH`, whereas `CHANGE`,
`RISING` and `FALLING` are “edges”.

This is corroborated by the [ATtiny45 datasheet][datasheet]: “The INT0
interrupts can be triggered by a falling or rising edge or a low level.”

> Is pin-change interrupt `PCINT`?

Yes.

> why do you think it isn't supported by the Arduino core?

The `attachInterrupt()` API only really makes sense for INT0, INT1,
etc... not for PCINT. You can also look at [the source code][source].

> Isn't it standard to interrupt when a pin changes states?

If you wish, you can configure INT0 to interrupt on a rising edge, a
falling edge, or any logical change. But this uses an edge-detection
logic which relies on the main clock, and thus does not work in
power-down mode.

For more details on INT0 vs. PCINT, their differences, and how to use
them, please refer to the datasheet, specifically to the “External
Interrupts” section I linked to above.

[arduino-doc]: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/#_parameters
[datasheet]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf#G1.1738372
[source]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.1/cores/arduino/WInterrupts.c#L69

------------------------------------------------------------------------

**Addendum**: Extra question:

> why it doesn't work [with `ISR(PCINT1_vect) {...}`]?

Gcc tells me “**warning: ‘PCINT1\_vect’** appears to be a misspelled
signal handler”. And indeed, there is no such interrupt vector on the
ATtiny45: there is only PCINT0\_vect, and this interrupt is shared by
all the pins that can generate a pin change interrupt. If you want to
know which pin triggered the interrupt, you will have to figure that out
within the interrupt handler itself.

This is the single point that makes the PCINTs trickier to work with
than INT0 and co.: each PCINT interrupt is shared by a group of pins. On
the ATtiny45, there is only one such group, and `PCINT0_vect` is the
only interrupt handler. Larger AVRs have more groups (3 on the
Uno/ATmega328P), and `PCINT1_vect` makes sense on them.

Also beware of the somewhat confusing naming scheme. Avr-libc defines
some macros `PCINTn`, where `n` is a number. These macros expand to bit
numbers, and are meant to be used in code like this:

```c++
PCMSK = _BV(PCINT0)   // sense changes in pin PCINT0 = PB0...
      | _BV(PCINT1)   // and PCINT1 = PB1...
      | _BV(PCINT2);  // and PCINT2 = PB2
```

In these macros, the number `n` identifies an _individual pin_. Avr-libc
also defines the macros `PCINTm_vect` for defining interrupt handlers.
In these macros, the number `m` identifies a _pin group_.


body:
I am using the File/Examples/Adafruit MQTT Library/mqtt_ESP8266 example as a model for my code.  In the example, the mqtt object is created as a global variable, and everything works fine.  However, I need to create the mqtt object in setup(), because the constructor parameters are not known until then.  If I move the constructor call

    Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

from the global namespace to inside setup(), I can no longer see it from inside loop().

I have tried declaring a pointer to mqtt in the global namespace, but don't know how to change it to point to the mqtt object that is created in setup().  How can I do this?

David

title: How do I change the scope of an object?

Answers: 1

body:
In general there is several ways to do it, none of them is the perfect one...

 1. pointer to mqtt at global scope `Adafruit_MQTT_Client * mqtt_ptr;` and initialize it by `mqtt_ptr = new Adafruit_MQTT_Client(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);` in setup. Then you have to use arrow operator instead dot to access its methods. Or you can make an alias in loop (or whenever you need it) by `Adafruit_MQTT_Client& mqtt = *mqtt_ptr;` and access it in the same way as before.
 2. returning reference to static variable created inside of function (singleton), but you have to provide parameters every time, even they're needed only for the first time. The static variable gets constructed only for the first call of function.
 3. For esp8266 there might be available `std::optional` template. It's similar to pointer, but you don't have to use arrow `->` operator. But there might be extraneous copy when you assign (create) it's value.
 4. You can also extend 1. or 2. by own class to hold parameters and then return instance of `Adafruit_MQTT_Client`