text:
Arduino RFID with motor and limit switches
Thanks for looking into my Arduino code.
I'm building an automated sliding draw, and I'm trying to activate the motor with a RFID scanner. The scanner waits for the token, and once it detects a token the motor turns and waits for a limit switch to be detected and stops the motor, then it does the same thing when it detects another RFID token but instead the motor travels in the opposite direction and waits for the opposite limit switch to be hit.
I have 2 sets of code. One is just the RFID scanner code which works fine, but it only switches a relay on and off. The other code is for the motor with 2 limit switches with a activation button. That code works too, and the draw opens and closes when you press a button, but it doesn't work with a RFID scanner. So my goal is to implement the RFID scanner code into the automated draw code in order to have a motor that turns and reverses with a RFID token and stops with a limit switch. I'm using an Arduino UNO board, 2 limit switches, a L298N H Bridge motor driver, and a MFRC522 RFID scanner.
Here is a schematic picture:

Here is the code for the automated draw using 3 buttons (2 limit switch, 1 activation button) and the DC motor:
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 4;     // the number of the pushbutton pin
const int buttonPin3 = 1;     // the number of the pushbutton pin
const int buttonPin2 = 2;     // the number of the pushbutton pin
const int motorPin =  5;      // the number of the LED pin
const int motorPin2 =  6;      // the number of the LED pin

// variables will change:
boolean buttonState = 0;         // variable for reading the pushbutton status
boolean buttonState2 = 0;         // variable for reading the pushbutton status
boolean buttonState3 = 0;   // variable for reading the pushbutton status

int drawPosition = 2;  // Tells progam what position the draw is in

/**
 *  setup inputs for switches and outs for motor pins
 *  serial begin to read the switches to test for errors
 */
void setup() {
    // initialize the pin as an inputs:
    pinMode(motorPin, OUTPUT);
    pinMode(motorPin2, OUTPUT);
    // initialize the pushbutton pin as an input:
    pinMode(buttonPin, INPUT);
    pinMode(buttonPin2, INPUT);
    pinMode(buttonPin3, INPUT);
    Serial.begin(9600);
}

/**
 * this function turns motor foward
 */
void drawForward() {
     // turn motor foward:
     digitalWrite(motorPin, LOW);
     digitalWrite(motorPin2, HIGH);
}

/**
 * this function turns motor backwards
 */
void drawBackward() {
     // turn motor in other direction:
     digitalWrite(motorPin, HIGH);
     digitalWrite(motorPin2, LOW);
}

/**
 * Stop the motor form moving
 */
void stopDrawFromMoving() {
  digitalWrite(motorPin, LOW);
  digitalWrite(motorPin2, LOW);

}

/**
 *
 */
void loop() {
   // read the state of the pushbutton value:
     buttonState = digitalRead(buttonPin);
     buttonState2 = digitalRead(buttonPin2);
   buttonState3 = digitalRead(buttonPin3);

   // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
   if (buttonState == HIGH) {
      drawPosition = 2;
      Serial.println(F("Front button state is high draw is open"));
      stopDrawFromMoving();
   }else if (buttonState2 == HIGH) {
      drawPosition = 1;
      stopDrawFromMoving();
  }

  if (buttonState3 == HIGH) {
    if( drawPosition  == 1 ){
      drawBackward();
      delay(100);
      drawPosition = 2;
      delay(100);
    }else if (drawPosition == 2 ) {
      delay(100);
      drawForward();
      delay(100);
      drawPosition = 1;
    }

  }
}

And that code you just read works fine, but it only activates the motor with a push button, but I'm trying to use RFID scanners.
Here is the code where I attempted to put the RFID code and the automated draw code together:
#include <EEPROM.h>     // We are going to read and write PICC's UIDs from/to EEPROM
#include <SPI.h>        // RC522 Module uses SPI protocol
#include <MFRC522.h>  // Library for Mifare RC522 Devices

//setting up inputs for limit switches and outputs for H Bridge motor driver
const int buttonPin = 4;     // the number of the pushbutton pin
const int buttonPin2 = 2;     // the number of the pushbutton pin
const int motorPin =  6;      // the number of the motors H Bridge (L298N) pin
const int motorPin2 =  5;      // the number of the motors H Bridge (L298N) pin

// variables for the state of the limit switches
boolean buttonState = 0;
boolean buttonState2 = 0;
int drawPosition = 2;  // Tells progam what position the draw is in

//this is the function to be called inside the loop. it makes the motor turn foward
void drawForward() {
  // turn H Bridge motor driver on in the foward polarity
  digitalWrite(motorPin, LOW);
  digitalWrite(motorPin2, HIGH);
}
// and this function turns the motor backwards
void drawBackward() {
  // turn H Bridge on with the REVERSED polarity
  digitalWrite(motorPin, HIGH);
  digitalWrite(motorPin2, LOW);
}
//This function is called when the motor needs to STOP moving
void stopDrawFromMoving() {
  //turn H Bridge motor driver OFF by turning both pins to LOW
  digitalWrite(motorPin, LOW);
  digitalWrite(motorPin2, LOW);
}

// Just stuff for the RFID to work
boolean match = false;          // initialize card match to false
boolean programMode = false;  // initialize programming mode to false
int successRead;    // Variable integer to keep if we have Successful Read from Reader
byte storedCard[4];   // Stores an ID read from EEPROM
byte readCard[4];   // Stores scanned ID read from RFID Module
byte masterCard[4];   // Stores master card's ID read from EEPROM
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.

///////////////////////////////////////// Setup ///////////////////////////////////
void setup() {
  // Setting up the digital read for limit switches
  buttonState = digitalRead(buttonPin);
  buttonState2 = digitalRead(buttonPin2);

  //Protocol Configuration for RIFD scanner
  Serial.begin(9600);  // Initialize serial communications with PC
  SPI.begin();           // MFRC522 Hardware uses SPI protocol
  mfrc522.PCD_Init();    // Initialize MFRC522 Hardware
  // This sets the RFID range to Maximum
  mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);
  Serial.println(F("BlueCore Tech Acces Control"));   // For debugging purposes

  // Check if master card defined, if not let user choose a master card
  if (EEPROM.read(1) != 143) {
    Serial.println(F("No Master Card Set"));
    Serial.println(F("Scan A RFID Card to Set as Master Card"));
    do {
      successRead = getID();            // sets successRead to 1 when we get read from reader otherwise 0
    }
    while (!successRead);                  // Program will not go further while you not get a successful read
    for ( int j = 0; j < 4; j++ ) {        // Loop 4 times
      EEPROM.write( 2 + j, readCard[j] );  // Write scanned PICC's UID to EEPROM, start from address 3
    }
    EEPROM.write(1, 143);                  // Write to EEPROM we defined Master Card.
    Serial.println(F("Master Card Set"));
  }
  Serial.println(F("-------------------"));
  Serial.println(F("Master Card's UID = "));
  for ( int i = 0; i < 4; i++ ) {          // Read Master Card's UID from EEPROM
    masterCard[i] = EEPROM.read(2 + i);    // Write it to masterCard
    Serial.print(masterCard[i], HEX);
  }
  Serial.println("");
  Serial.println(F("-------------------"));
  Serial.println(F("Everything Ready"));
  Serial.println(F("Waiting for Keys or cards to be scanned"));
  cycleLeds();    // Everything ready lets give user some feedback by cycling leds
}
///////////////////////////////////////// Main Loop ///////////////////////////////////
void loop () {

//this first chunk of "if" is always setting the variable from iether "1" or "2" depending on what limit switch is closed, this allows the program to REMEMBER what the position of the draw is.
  if (buttonState == HIGH) {   //if the back limit switch is closed, the draw is in the closed (or backward) position
    drawPosition = 2;    //sets the variable to "2" meaning the draw is in the closed position
    Serial.println(F("Front button state is high so draw is open"));
    stopDrawFromMoving();  //this also stopes the motor form moving foward any further
  } else if (buttonState2 == HIGH) { // same principle applies here but its just reversed:
    drawPosition = 1;
    Serial.println(F("Back button state is high draw is open"));
    stopDrawFromMoving();
  }

// THERE IS A ERROR HERE I CANNOT FIX ////////////////////////////////////////////////////////////////////////////THERE IS A ERROR HERE I CANNOT FIX/////////////////////////////////////////THERE IS A ERROR HERE I CANNOT FIX///////////////////////////////////////
//   'getID' was not declared in this scope exit status 1      this happens anywhere inside the loop where there is a mention of the 'getID' function. I though this only happens if you calling a function but it doesnt exist, but it clearly does exist becuase its at the bottom
  do {
    successRead = getID();  // sets successRead to 1 when we get read from reader otherwise 0
    if (programMode) {
    }
    else {
      normalModeOn();     // Normal mode, blue Power LED is on, all others are off
    }
  }
  while (!successRead);   //the program will not go further while you not get a successful read
  if (programMode) {
    if ( isMaster(readCard) ) { //If master card scanned again exit program mode
      Serial.println(F("Master Card Scanned"));
      Serial.println(F("Exiting Programming Mode"));
      Serial.println(F("-----------------------------"));
      programMode = false;
      return;
    }
    else {
      if ( findID(readCard) ) { // If scanned card is known delete it
        Serial.println(F("I know this key, removing..."));
        deleteID(readCard);
        Serial.println("-----------------------------");
      }
      else {                    // If scanned card is not known add it
        Serial.println(F("I do not know this key, adding..."));
        writeID(readCard);
        Serial.println(F("-----------------------------"));
      }
    }
  }
  else {
    if ( isMaster(readCard) ) {   // If scanned card's ID matches Master Card's ID enter program mode
      programMode = true;
      Serial.println(F("Hello Master - Entered Programming Mode"));
      int count = EEPROM.read(0);   // Read the first Byte of EEPROM that
      Serial.print(F("I have "));     // stores the number of ID's in EEPROM
      Serial.print(count);
      Serial.print(F(" record(s) in DATABASE"));
      Serial.println("");
      Serial.println(F("Scan a Card or key to ADD or REMOVE"));
      Serial.println(F("-----------------------------"));
    }
    else {
      if ( findID(readCard) ) {  // If not, see if the card is in the EEPROM
        Serial.println(F("Welcome, Acces Granted"));
        //this is another part from the other code that im trying to implement into the RFID code
        if ( drawPosition  == 1 ) { //if the variale is saying the draw is currently in the FOWARD position
          drawBackward();  //then return it to the BACKWARD position
          delay(100);
          drawPosition = 2;  //then make the variable a "2" so the code remembers what the position of the draw is for next time the RFID scanner is activated
          delay(100);
        } else if (drawPosition == 2 ) {  //same principle under here but its just reversed for when the draw is found in the opposite position and needs to return to the opposite position
          delay(100);
          drawForward();
          delay(100);
          drawPosition = 1;
        }
      }
      else {   // If the token is unknown, show that the ID was not valid and dont do anything else
        Serial.println(F("Acces Denied!"));
      }
    }

  }
  ///////////////////////////////////////// Get PICC's UID ///////////////////////////////////
  int getID() {
    // Getting ready for Reading PICCs
    if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
      return 0;
    }
    if ( ! mfrc522.PICC_ReadCardSerial()) {   //Since a PICC placed get Serial and continue
      return 0;
    }
    // There are Mifare PICCs which have 4 byte or 7 byte UID care if you use 7 byte PICC
    // I think we should assume every PICC as they have 4 byte UID
    // Until we support 7 byte PICCs
    Serial.println(F("Scanned KEY's UID:"));
    for (int i = 0; i < 4; i++) {  //
      readCard[i] = mfrc522.uid.uidByte[i];
      Serial.print(readCard[i], HEX);
    }
    Serial.println("");
    mfrc522.PICC_HaltA(); // Stop reading
    return 1;
  }
  ///////////////////////////////////////// Show reader details ///////////////////////////////////
  void ShowReaderDetails() {
    // Get the MFRC522 software version
    byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
    Serial.print(F("MFRC522 Version: 0x"));
    Serial.print(v, HEX);
    if (v == 0x91)
      Serial.print(F(" = v1.0"));
    else if (v == 0x11)
      Serial.print(F(" = BlueCore Tech. RFID Acces v2.0"));
    else
      Serial.print(F(" (unknown)"));
    Serial.println("");
    // When 0x00 or 0xFF is returned, communication probably failed
    if ((v == 0x00) || (v == 0xFF)) {
      Serial.println(F("WARNING: Communication failure, is the RFID-MFRC522 properly connected?"));
      while (true); // do not go further
    }
  }
  //////////////////////////////////////// Read an ID from EEPROM //////////////////////////////
  void readID( int number ) {
    int start = (number * 4 ) + 2;    // Figure out starting position
    for ( int i = 0; i < 4; i++ ) {     // Loop 4 times to get the 4 Bytes
      storedCard[i] = EEPROM.read(start + i);   // Assign values read from EEPROM to array
    }
  }
  ///////////////////////////////////////// Add ID to EEPROM   ///////////////////////////////////
  void writeID( byte a[] ) {
    if ( !findID( a ) ) {     // Before we write to the EEPROM, check to see if we have seen this card before!
      int num = EEPROM.read(0);     // Get the numer of used spaces, position 0 stores the number of ID cards
      int start = ( num * 4 ) + 6;  // Figure out where the next slot starts
      num++;                // Increment the counter by one
      EEPROM.write( 0, num );     // Write the new count to the counter
      for ( int j = 0; j < 4; j++ ) {   // Loop 4 times
        EEPROM.write( start + j, a[j] );  // Write the array values to EEPROM in the right position
      }
      successWrite();
      Serial.println(F("Succesfully added ID record to DATABASE"));
    }
    else {
      failedWrite();
      Serial.println(F("Failed! There is something wrong with ID or bad DATABASE"));
    }
  }
  ///////////////////////////////////////// Remove ID from EEPROM   ///////////////////////////////////
  void deleteID( byte a[] ) {
    if ( !findID( a ) ) {     // Before we delete from the EEPROM, check to see if we have this card!
      failedWrite();      // If not
      Serial.println(F("Failed! There is something wrong with ID or bad DATABASE"));
    }
    else {
      int num = EEPROM.read(0);   // Get the numer of used spaces, position 0 stores the number of ID cards
      int slot;       // Figure out the slot number of the card
      int start;      // = ( num * 4 ) + 6; // Figure out where the next slot starts
      int looping;    // The number of times the loop repeats
      int j;
      int count = EEPROM.read(0); // Read the first Byte of EEPROM that stores number of cards
      slot = findIDSLOT( a );   // Figure out the slot number of the card to delete
      start = (slot * 4) + 2;
      looping = ((num - slot) * 4);
      num--;      // Decrement the counter by one
      EEPROM.write( 0, num );   // Write the new count to the counter
      for ( j = 0; j < looping; j++ ) {         // Loop the card shift times
        EEPROM.write( start + j, EEPROM.read(start + 4 + j));   // Shift the array values to 4 places earlier in the EEPROM
      }
      for ( int k = 0; k < 4; k++ ) {         // Shifting loop
        EEPROM.write( start + j + k, 0);
      }
      successDelete();
      Serial.println(F("Succesfully removed ID record from DATABASE"));
    }
  }
  ///////////////////////////////////////// Check Bytes   ///////////////////////////////////
  boolean checkTwo ( byte a[], byte b[] ) {
    if ( a[0] != NULL )       // Make sure there is something in the array first
      match = true;       // Assume they match at first
    for ( int k = 0; k < 4; k++ ) {   // Loop 4 times
      if ( a[k] != b[k] )     // IF a != b then set match = false, one fails, all fail
        match = false;
    }
    if ( match ) {      // Check to see if if match is still true
      return true;      // Return true
    }
    else  {
      return false;       // Return false
    }
  }
  ///////////////////////////////////////// Find Slot   ///////////////////////////////////
  int findIDSLOT( byte find[] ) {
    int count = EEPROM.read(0);       // Read the first Byte of EEPROM that
    for ( int i = 1; i <= count; i++ ) {    // Loop once for each EEPROM entry
      readID(i);                // Read an ID from EEPROM, it is stored in storedCard[4]
      if ( checkTwo( find, storedCard ) ) {   // Check to see if the storedCard read from EEPROM
        // is the same as the find[] ID card passed
        return i;         // The slot number of the card
        break;          // Stop looking we found it
      }
    }
  }
  ///////////////////////////////////////// Find ID From EEPROM   ///////////////////////////////////
  boolean findID( byte find[] ) {
    int count = EEPROM.read(0);     // Read the first Byte of EEPROM that
    for ( int i = 1; i <= count; i++ ) {    // Loop once for each EEPROM entry
      readID(i);          // Read an ID from EEPROM, it is stored in storedCard[4]
      if ( checkTwo( find, storedCard ) ) {   // Check to see if the storedCard read from EEPROM
        return true;
        break;  // Stop looking we found it
      }
      else {    // If not, return false
      }
    }
    return false;
  }
  ///////////////////////////////////////// Write Success to EEPROM   ///////////////////////////////////
  void successWrite() {
    Serial.println(F("Write to EEPROM is Succsusful"));
  }
  ///////////////////////////////////////// Write Failed to EEPROM   ///////////////////////////////////
  void failedWrite() {
    Serial.println(F("Failed to write to EEPROM"));
  }
  ///////////////////////////////////////// Success Remove UID From EEPROM  ///////////////////////////////////
  void successDelete() {
    Serial.println(F("Removed from EEPROM"));
  }
  ////////////////////// Check readCard IF it is masterCard   ///////////////////////////////////
  // Check to see if the ID passed is the master programing card
  boolean isMaster( byte test[] ) {
    if ( checkTwo( test, masterCard ) )
      return true;
    else
      return false;
  }

So there's 2 main errors in the second code (the code implementing RFID with my limit switch logic and motor functions.)
The first one was quite obvious in the code when I said "ERROR HERE" and the error is a "exit status 1 getID was not declared in this scope." Not sure why this happens, I cant make sense of it.
Once that's fixed I can look at the main issue, and that's actually making it work. I have tested the code before I was getting that exit status error and the logic wasn't working. There is probably a better way of putting these to bits of code together but I'm fairly new to programing and I cant figure it out.
Thanks so much for your help  ( :

The getid issue has been fixed, i simply moved all the functions to the top of the code so the compiler reads them before it gets to the loop code. But the code still isn't working in practice. The tokens are not read at all, but the master card is. The code is trying to turn the motor and do all that code once it detects a token that is known. Any help would be great.

C++ and C only reads function declarations and globals from top to bottom, it will not look ahead to see if any others were defined.
You can put a declaration of the functions you want to use above where you want to use it.
//...
int getID();
///////////////////////////////////////// Main Loop ///////////////////////////////////
void loop () {
//...

Usually the Arduino IDE will attempt to generate declarations automatically.

thanks, ill try to put them all on top and let you know how it goes


text:
Can't turn off fan using PWM and analogWrite(x, 0)
I'm trying to make PWM Signal Generator with Arduino Uno.
I'm trying to control 230V 50hz "NRG118" combi boiler fan.  The fan powered by AC and have 3pins for PWM control. "vcc,gnd,pwm" Wired them to arduino "5v, GND, 11" pins.
I can control the card on the arduino "0to100% with a simple code below but I can't turn it off.
I tried digitalWrite nothing changed. Tried different pins 5-6-9-11 nothing changed. Tried to wire gnd+vcc to outsource powersuply nothing changed.
Also I have a simple PWM generator "HW-723 XY-LPWM PWM Signal Generator Module". The "HW-753" can control the fan without any other component but it may have builtin special component like a NPN but im not sure about it.
In description I found this and maybe its a requirement but I have no idea about electronic components:
"The PWM output pin on the microcontroller drives an NPN MMBT3904 type transistor which in turn drives the PWM output pin of the module.  The transistor has a series 1K resistor tied to VIN+, so the PWM signal will swing between ground and the module supply voltage on the VIN+ pin."
With the HW-753; at startup the fan is not running but when I wire to my arduino it starts with 100% power and when i set "analogWrite(x, 0)" dutycycle reducing but fan still running at %1 speed and I read 0.07volt with multimeter on "PWM+GND" pins.
Most people can not run, I cant stop.... It's killing me people...
What am I doing wrong?
void setup() {
  pinMode(6, OUTPUT);
}
void loop() { //the code only for test. Using loop is dumb.
  //digitalWrite(6, LOW);
   analogWrite(6, 0);
   delay(5000);
}

Can you look at the PWM signal with a scope when driven by the HW-753 and when driven by the Arduino? What happens when you wire PWM and GND together?

I can't. I'm just a developer who has nothing about electronics. I have only a Multimeter.:)
I didn't wire PWM and GND together. What is the logic behind this?

If you short PWM and GND (remove PWM from any Arduino pin!), you make sure that you have the lowest possible value. Now check how your fan is doing.

Thanks I will try that. Also I figured out that if the PWM pin is not using it means 0 volt but the fan works with highest speed. So PWM pin shouldn't be 0volt. Maybe I need to give a special voltage to stop it? In this diagram it looks 0.8-2volt. https://www.allaboutcircuits.com/uploads/articles/voltage-tolerance-of-ttl-gate-inputs.jpg

So to stop the motor I need to give special PWM voltage. I think analogWrite(6, X);  the X should be between 50-100. How can I learn what PWM output needs the fan to turn-off?

Looking at some datasheets, I think, anything less than 20% duty cycle means OFF. Which would X < 50 (and X>0).

Considering a common 4-pin PC fan (I know, that's not what you have) it is not possible to switch off. All my 4-pin fans are running at ficed rpm when PWM is below ~20%. To make it stop I need to cut Vcc. Posdibly your fab behaves the same way

If I wire 5V to FAN controller card,  PWM+GND fan can stop the fan. But if I directly wire Fan's "5V, GND" to a adapter then PWM has no effect on arduino. If I wire "5V, GND" to arduino then PWM can drive the fan between %10-70 DutyCycle with "analogWrite(PWM_PIN, 0-255);" but can not stop the fan. What should I do?

If you are working with the AC motor, then it is probably works even PWM cable is not attached. In this case there is no reason to use "analogWrite(PIN, 0)".  It will not work.
"An external resistor divider connected to the VMIN input sets the minimum fan speed by fixing the minimum PWM duty cycle (1.25V to 2.65V = 0% to 100%, typical).  It depends on controler card manufacturer. check datasheet"
If you cant find datasheet like me then check how others do. There is diagram of "HW-753 Signal Generator Module" below. As you can see between VIN+ and PWM there is 1k Resistor and both wired to an NPN, also the mid leg of NPN passing 1k resistor while going to pwm to protect the card. Also 3rd leg is wired to gnd. So it is not the same thing I was doing before. If you work with AC then you must always consider that and just forget what people say. Do not drown like me. I hope it will helps someone.

Am I missing something, AC motors are typically controlled with phase control, not PWM.  Just a SWAG as the AC portion circuit is not posted. Typically on AC the motor will be driven with a Triac or SCR. Timing for firing is from the zero cross, once for each 1/2 cycle.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Device Signature Error uploading to ATMEGA168PA
I keep getting a device signature error and can't program my Atmega168pa chip.
I'm using the board from: https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json
I've pasted the error below from an attempt to upload a new sketch:
void setup() {
  // put your setup code here, to run once:

}

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

}

Arduino: 1.8.13 (Linux), Board: "ATmega168, No bootloader, EEPROM retained, 168P / 168PA, BOD disabled, LTO Disabled, Internal 8 MHz"

Sketch uses 412 bytes (2%) of program storage space. Maximum is 16384 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 1015 bytes for local variables. Maximum is 1024 bytes.
/home/rick/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/home/rick/.arduino15/packages/MiniCore/hardware/avr/2.0.7/avrdude.conf -v -patmega168p -cstk500v1 -P/dev/ttyUSB0 -b19200 -Uflash:w:/tmp/arduino_build_51999/sketch_nov15a.ino.with_bootloader.hex:i

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/home/rick/.arduino15/packages/MiniCore/hardware/avr/2.0.7/avrdude.conf"
         User configuration file is "/home/rick/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/ttyUSB0
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega168P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no        512    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     16384  128    128  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000 (retrying)

An error occurred while uploading the sketch
Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.

Pictures of my wiring:

I have:

D13 -> (PCINT0/CLKO/ICP1) PB0 [Pin 14]
D12 -> PB4 (MISO/PCINT4) [Pin 18]
D11 -> PB3 (MOSI/OC2A/PCINT3) [Pin 17]
D10 -> (PCINT14/RESET) PC6 [ Pin 1]

I have a 100n capacitor between vcc & gnd and between avcc & gnd. I have a 10 uF capacitor between “Reset” and “Ground” pins on the Arduino. Power is fed via the 5v pin from Arduinio.
I know this nano works (I programmed an ATTiny84 with it before and after my attempts on the Atmega). I've checked pwr & gnd. I'm not 100% sure of the wiring. These chips are new from China so I'm not sure if they are configured for internal or external clock, although I believe they are set to internal by default.

ISP pins are usually all next to each other. That D13 to PB0 is unlikely to be correct. It should be PB5

@KIIV, I just noticed your comment here.  Write it up as an answer and I'll vote my answer for deletion.

The ISP pins are usually all next to each other. The connection D13 to PB0 is unlikely to be correct. It should be connected to PB5.
You can check your connections here: https://www.arduino.cc/en/Tutorial/BuiltInExamples/ArduinoToBreadboard (there is UNO, but pin numbering/wiring is exactly the same as for Nano)
Another possible mistake is burning wrong fuses (with bootloader) for external xtal setting (also mentioned in the article)

The issue was the D13 to PB0 connection, it should have been PB5. After I moved that everything worked perfectly. Thanks!

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Controlling a Stepper Motor - sending to specific positions on a 'buttonPushCounter ==' cue, forwards and backwards
I am working on a project using an Arduino control a Stepper Motor. The motor drives a lead screw which moves coloured filters to specific positions along a linear track - forwards and backwards.
The movements are triggered by another device that counts its revolutions (using a sensor. The Arduino reads the inputs and activates the motor on specific revs ie. at 10 move 70mm forwards, at 30 move 70mm backwards.
I can control the Stepper to execute precise moves repeatedly one after another, independently of the counter. I can link the Arduino to the counter and switch on/off an LED at specified counts. But when I try to run the motors from the counter, it's triggered but only moves in tiny discontinuous steps, and only goes one way. Here is that Sketch below. Any help very welcome. Thanks.

// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 7;       // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <AccelStepper.h>

Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

void forwardstep1() {
  myMotor->onestep(FORWARD, DOUBLE);
}
void backwardstep1() {
  myMotor->onestep(BACKWARD, DOUBLE);
}

AccelStepper Astepper1(forwardstep1, backwardstep1);

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
  AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz
  TWBR = ((F_CPU / 500000l) - 16) / 2; // Change the i2c clock to 400KHz
  Astepper1.setAcceleration(6000.0);
  Astepper1.setMaxSpeed(600);
  Astepper1.setSpeed(600);    // rpm
  //  while (switchIsOff) {
  //turn servo one direction -
  //tell servo this is 0
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  if (buttonPushCounter == 10) {
    digitalWrite(ledPin, HIGH);
    Astepper1.moveTo(600);
    Astepper1.setSpeed(600);
    Astepper1.run();
  }

  if (buttonPushCounter == 30) {
    digitalWrite(ledPin, LOW);
    Astepper1.moveTo(200);
    Astepper1.setSpeed(600);
    Astepper1.run();
  }

  }
}

I think the problem is that Astepper.run() doesn't wait for the motor to reach it's target position. It is supposed to be called very frequently and will do a step, when it's the right time to, and returns when it is not. In your code it moves exactly until the counter is incremented the next time, because then you don't call the run method anymore. I'm currently not sure. Will write an answer, when I have time to check the source code

Thanks. Your description of the fault makes sense to me. As you point out blocking would be a problem as I need the counter to continue to be registering while the movement is being executed. I've revised the script as you suggest - inside the loop but outside the if statement - have I done as you meant? But the same problem occurs - the motor advances in single steps.

// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 7;       // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <AccelStepper.h>

Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

void forwardstep1() {
  myMotor->onestep(FORWARD, DOUBLE);
}
void backwardstep1() {
  myMotor->onestep(BACKWARD, DOUBLE);
}

AccelStepper Astepper1(forwardstep1, backwardstep1);

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
  AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz
  TWBR = ((F_CPU / 500000l) - 16) / 2; // Change the i2c clock to 400KHz
  Astepper1.setAcceleration(6000.0);
  Astepper1.setMaxSpeed(600);
  Astepper1.setSpeed(600);    // rpm
  //  while (switchIsOff) {
  //turn servo one direction -
  //tell servo this is 0
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // save the current state as the last state, for next time through the loop
    lastButtonState = buttonState;

    if (buttonPushCounter == 10 ) {
      digitalWrite(ledPin, HIGH);
      Astepper1.moveTo(20000);
      Astepper1.setAcceleration(6000.0);
      Astepper1.setSpeed(600);
      //Astepper1.setSpeed(600);
      Astepper1.run();
    }
    Astepper1.run();//this command moved out of an 'if' statement, but still within the 'loop'

    if (buttonPushCounter == 30) {
      digitalWrite(ledPin, LOW);
      Astepper1.moveTo(200);
      Astepper1.setSpeed(600);
    }
    Astepper1.run();//this command moved out of an 'if' statement, but still within the 'loop'

  }

There are several run-like methods in the AccelStepper library.
The one you are using, run(), is intended to be called at EVERY pass through loop(), and it will only cause a step if one is necessary, based on the internal state of the library (i.e., current position, target position, acceleration profile, etc.) It is safe to call so often -- it will determine itself if there is any motion needed.
You could move the run() call to a place inside loop(), but outside of any if statements.
Alternatively, there is a runToPosition() function, which is blocking -- it will stop all execution of your code until the stepper is at the target position. This would be fine for your current code as posted, but if you wish to monitor the revolution counter also, then this would not be the best option to take.


text:
OLED shield for wemos d1 mini pro not staying on
I recently bought a wemos d1 mini pro to toy with wifi and bought a oled shield with it. I've been looking on youtube and github for software and I finally found the software and got it to load onto the board. however, the shield is only on for a fraction of a second and I don't know why.
here is the code
#include "SPI.h"
#include "Wire.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"

#define OLED_RESET 0  // GPIO0
Adafruit_SSD1306 display(OLED_RESET);

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

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
// init done

display.display();
delay(2000);

// Clear the buffer.
display.clearDisplay();

// text display tests
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,10);
display.println("Hello");
display.println("World");

display.display();
delay(10000);
display.clearDisplay();
}

void loop() {

}

here is what it says when uploading
Build options changed, rebuilding all
Sketch uses 278084 bytes (26%) of program storage space. Maximum is 1044464
bytes.
Global variables use 27432 bytes (33%) of dynamic memory, leaving 54488
bytes for local variables. Maximum is 81920 bytes.
esptool.py v2.6
2.6
esptool.py v2.6
Serial port COM5
Connecting....
Chip is ESP8266EX
Features: WiFi
MAC: b4:e6:2d:53:19:6b
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Auto-detected Flash size: 16MB
Flash params set to 0x0290
Compressed 282240 bytes to 204639...

Writing at 0x00000000... (7 %)
Writing at 0x00004000... (15 %)
Writing at 0x00008000... (23 %)
Writing at 0x0000c000... (30 %)
Writing at 0x00010000... (38 %)
Writing at 0x00014000... (46 %)
Writing at 0x00018000... (53 %)
Writing at 0x0001c000... (61 %)
Writing at 0x00020000... (69 %)
Writing at 0x00024000... (76 %)
Writing at 0x00028000... (84 %)
Writing at 0x0002c000... (92 %)
Writing at 0x00030000... (100 %)
Wrote 282240 bytes (204639 compressed) at 0x00000000 in 4.8 seconds
(effective 467.5 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

and this is the monitor
0⸮~?⸮4⸮!⸮⸮⸮⸮OCAG⸮⸮

thank you for your time

How is it all being powered?

through a usb from my computer

you set io 0 as reset. to which D pin on the board did you wire the reset pin of the display? D0 (io 16) or D3 (io 0)?

did you try to remove the last two lines of setup()?

I assume I wired the reset pin to the reset pin on the wemos mini pro due having soldered all 16 male pins on the oled shield going into all 16 female pins on the top half of the wemos mini pro. I did remove the cleardisplay() line but not the second to last. I'll try that tomorrow morning

sorry. It is a shield so you don't wire it. I found the schematics

i tried removing the last 2 lines from the setup code but it did nothing. I also have a dc power shield which i just tried and it doesn't help

I fixed the problem. I was the one who did the soldering so i decided to make the soldering better and now it works. thank you juraj for your time


text:
Servo Motor in function
I have a project with 9 servo, I want to make a function to control each separate. Only that he is not accepting the servo as a parameter.
Can someone tell me if it is possible to pass the servant as a parameter, and how? Thank you!!
Example:
Servo s1,s2,s3;

void toMove(Servo obj,int inPosition, int forPosition){
var i = 0;
  for(i = inPosition; i<forPosition; i++){
    obj.write(i);
  }
}

void loop(){
  if(true){
     toMove(s1,0,180);
     toMove(s2,0,180);
  }
}

Where is the rest of your sketch? The servo include is missing, setup is missing, and var i = 0; looks like JavaScript, not "Arduino code".

try void toMove(Servo& obj,int inPosition, int forPosition){

It doesn't make sense to write all values from inPosition to forPosition in increments to the servo. Since the period of the pulsed signal to the servo is much longer (multiple orders of magnitude) than the time the for-loop needs, the servo will (almost) never see any intermediate values. You can just write the forPosition to the servo.

Yes, it is possible, and you've done it almost right. I made a minor correction in the toMove() function ("int" instead of "var"), and supplied the setup() function which you didn't show. It compiles without error. I didn't check it for correct operation as it looks like you had reduced your code to the minimum example necessary to demonstrate your question -- and thanks for that! Here is what I compiled:
#include <Servo.h>

#define SERVO1      9
#define SERVO2      10

/*****< External and Global Declarations >*****/
Servo s1, s2;
void toMove(Servo obj, int inPosition, int forPosition);

/*****< Local Function Prototypes >*****/

void toMove(Servo obj,int inPosition, int forPosition){
int i = 0;
  for(i = inPosition; i<forPosition; i++){
    obj.write(i);
  }
}

void setup()
{
    s1.attach(SERVO1);
    s2.attach(SERVO2);
}

void loop() {
   toMove(s1, 0, 180);
   toMove(s2, 0, 90);
}

a function prototype a line before the function definition? (and a line before the comment about it?)

As noted by Juraj in a comment to the original question, it would be better to pass a reference to the servo, rather than copying the whole object: void toMove(Servo &obj, int inPosition, int forPosition);.

Yeah, that was an editing 'oops'. Originally I'd put toMove() below loop(). Clearly, the declaration is no longer needed.

I am simulating in Tinkercad, I copied its code and set up the project, with the arduino and the servo, it continues giving error, the Servo is not identified as type of variable for the function.
Would you like to help me, the link to the project is: https://www.tinkercad.com/things/2w0xPqGEqI0-smooth-vihelmo/editel?tenant=circuits?sharecode=Asr_eiFyOe07v5aViePWyad3yNYuyASikZSkzwspaoU=
Anyway thank you!

Have you tried @juraj & @ EdgarBonet's suggestion of passing by reference ( '&obj' instead of 'obj' in the function parameter list)? The compiler will accept it either way (at a 58 byte code penalty for passing the whole object), but perhaps Tinkercad won't accept passing the entire object (I couldn't try it - the link fails for me).

You have not use attach() function:
 s1.attach(pin_1);
 s2.attach(pin_2);

See how to use servo motor


text:
SyslogAppender for log4esp
I'd like to "merge" two Arduino libraires, namely log4Esp on one side and Syslog on the other, hence creating a syslog appender for log4esp.
My problem is that log4esp's Appender prototype expects a method to return an instance of Print to which it'll write the message.
Syslog can't be used in this way.
==> Question : How to create a "Print buffer" / where can I find which class extends Print?

Cerber, question for you https://arduino.stackexchange.com/questions/58502/library-mixing-log4esp-syslog-for-esp8266

Class Print is a base class of Arduino streaming. Stream is a derived class and adds reading capability. Print has only one abstract method write to write one byte to output or buffer. It is easy to implement a derived custom class.
The classes derived from Stream are classes for hardware and software serial like HardwareSerial for Serial singletons and different software serial implementations. From Stream is derived class File of the SD and SPIFFS library, TwoWire class for Wire singleton object, etc.
Class Client is derived from class Stream and is a base class for Arduino standard TCP networking. Examples of derived classes are EthernetClient, WiFiClient. For UDP, class UDP is derived from Stream, of course with implementations like EthernetUDP, WiFiUDP.
You can see this in the source code in local source file folders or in GitHub repositories.

perfect answer, very clear ! Thanks @juraj


text:
No ttyACM0 with Pro Micro on Ubuntu 18.04
I am trying to determine the dev path of a USB keyboard running an Arduino Pro Micro on my Ubuntu 18.04 system. The files /dev/ttyACM0 and /dev/ttyUSB0 do not exist.
When I run dmesg I get:
[  410.770931] usb 3-3: new full-speed USB device number 3 using xhci_hcd
[  410.962180] usb 3-3: New USB device found, idVendor=feed, idProduct=3060, bcdDevice= 0.01
[  410.962184] usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  410.962187] usb 3-3: Product: Dactyl-Manuform (5x6)
[  410.962189] usb 3-3: Manufacturer: tshort
[  410.962191] usb 3-3: SerialNumber: 0
[  411.006440] input: tshort Dactyl-Manuform (5x6) as /devices/pci0000:00/0000:00:07.1/0000:11:00.3/usb3/3-3/3-3:1.0/0003:FEED:3060.0008/input/input27
[  411.063192] hid-generic 0003:FEED:3060.0008: input,hidraw0: USB HID v1.11 Keyboard [tshort Dactyl-Manuform (5x6)] on usb-0000:11:00.3-3/input0
[  411.089097] input: tshort Dactyl-Manuform (5x6) Mouse as /devices/pci0000:00/0000:00:07.1/0000:11:00.3/usb3/3-3/3-3:1.1/0003:FEED:3060.0009/input/input28
[  411.147172] input: tshort Dactyl-Manuform (5x6) System Control as /devices/pci0000:00/0000:00:07.1/0000:11:00.3/usb3/3-3/3-3:1.1/0003:FEED:3060.0009/input/input29
[  411.147297] input: tshort Dactyl-Manuform (5x6) Consumer Control as /devices/pci0000:00/0000:00:07.1/0000:11:00.3/usb3/3-3/3-3:1.1/0003:FEED:3060.0009/input/input30
[  411.147395] hid-generic 0003:FEED:3060.0009: input,hidraw1: USB HID v1.11 Mouse [tshort Dactyl-Manuform (5x6)] on usb-0000:11:00.3-3/input1

Dactyl-Manuform is the keyboard so it seems to recognize the device. The command lsusb returns several usb devices. The entry with no title is the keyboard (based on doing watch lsusb):
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 003: ID feed:3060
Bus 003 Device 002: ID 045e:02d1 Microsoft Corp. XBOX One Controller for Windows
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 1e7d:2c2e ROCCAT
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

I have installed arduino and arduino-core from the official repos.
However, I still cannot get a ttyACM0 or ttyUSB0 to appear, and in the Arduino IDE the "Serial Port" option is greyed out (even when using sudo).
What can I check for to either 1) get the ttyACM0 file to exist for my Arduino device or 2) find some other dev port to use as the serial port?

What makes you think it should have a CDC/ACM endpoint at all?

A Pro Micro will only give a /dev/ttyACMx device node if the firmware installed on it creates a CDC/ACM interface.  That device obviously is running custom firmware which only provides the interfaces that the manufacturer wants to provide - in this case keyboard and mouse interfaces.
To use it as an Arduino you will first have to install the Arduino bootloader. That will then remove the existing manufacturer firmware, and you will have to write your own to make it act as a keyboard again.


text:
Can't connect to my ESP32 board via serial
I'm completely new to electronics work.
Today I've received the ESP32 board that I ordered. (It's a WROOM-32.) I followed the instructions here. I connected the board to my computer via USB and I successfully installed the CP210x drivers and got a new serial port COM3, but when I tried to connect to the board with that serial port, I got nothing. I'm on Windows 7.
I tried with Tera Term, and it just shows an empty screen.
I tried type COM3 in the shell, but got an empty string.
I tried doing esptool.exe --chip esp32 -p com3 erase_flash, but I get "Failed to connect to ESP32: Timed out waiting for packet header".
I tried playing with the two buttons on the WROOM32 board, but that didn't help.
Any idea what I'm doing wrong? I'm a complete newbie so it's likely that I'm forgetting something basic.

What do you think you would expect to see on the serial of a blank chip?

@Majenko Okay, so let's say it's supposed to be blank. The esptool is supposed to run without errors when flashing it, right?

Only if it's set to reset the board into flashing mode. Install the Arduino IDE. Install the ESP32 core. Select the right board. Load an example. Program it. Then, and only then, should you go on to advanced topics like programming from the command line.

@Majenko Okay, I did everything you said. Installed Arduino IDE with the ESP32 core. Loaded the AnalogReadSerial. Pressed upload. It failed. Looks like the ESP32 core is using esptool internally, cause the error from Arduino IDO is the exact same one I got in my question: Failed to connect to ESP32: Timed out waiting for packet header

the tutorial linked in question is about Lua

@Juraj Is that really the reason for this failure though?

I don't know why you followed that tutorial. Do you have a Doit ESP32 devkit board with Lua? Do you want to use Lua?

@Juraj I didn't realize that the Doit ESP32 and the WROOM-32 are distinct things. I have this: https://www.ebay.com/itm/Espressif-ESP32-WLAN-Dev-Kit-Board-Development-Bluetooth-Wifi-v1-WROOM32-NodeMCU/253059783728?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649

If you have a better tutorial to send me, I'll be happy to try that

WROOM-32 is the module mounted to the developement board https://www.mouser.sk/images/espressifsystems/lrg/ESP32-WROOM-32_new_SPL.jpg (a tutorial will not help you with the COM port problem)

The issue is that the Serial port on the ESP32-WROOM setup is not like like on the Arduino. It seems that the initialisation will 'miss' the USB enumeration after reboot.
To fix this add a delay in your setup() function of 10 to 15-seconds before initialising the serial.
For example:
void setup() {
  delay(10000);
  Serial.begin(115200);

  Serial.println("Setting up Access Point...");
  .
  .
  .

This works for me, but I hope there is a more elegant solution out there.


text:
Esp8266 Web based code and real button
0
I wrote a code in the Arduino IDE. With this code, i can control 4 leds on and off from the web page. In the web page 9 buttons.
2 buttons for led-1 on and off. 2 buttons for led-2 on and off. 2 buttons for led-3 on and off. 2 buttons for led-4 on and off. 1 button for toggle all leds on and off.
I want also add a real button to the circuit. When i press this button, i want to run that toggle code. How can i do that?
This is my code;
#include <ESP8266WiFi.h>

const char* ssid = "UnderSpeed";
const char* password = "q1w2e3r4t5__";
const char* host = "192.168.1.185"; //it will tell you the IP once it starts up
                                        //just write it here afterwards and upload
int r0 = D0;
int r1 = D1;
int r2 = D2;
int r3 = D3;
int btn0 = D5;

WiFiServer server(301); //just pick any port number you like

void setup() {
  Serial.begin(115200);
  delay(10);
Serial.println(WiFi.localIP());
  // prepare GPIO2
  pinMode(r0, OUTPUT);
  pinMode(r1, OUTPUT);
  pinMode(r2, OUTPUT);
  pinMode(r3, OUTPUT);
  pinMode(btn0, INPUT_PULLUP);
  digitalWrite(r0, HIGH);
  digitalWrite(r1, HIGH);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, HIGH);

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

  WiFi.begin(ssid, password);

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

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

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

void loop() {
  // Check if a client has connected

  WiFiClient client = server.available();
  if (!client) {
    return;
  }

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

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

  // Match the request
  if (req.indexOf("") != -10) {  //checks if you're on the main page

    if (req.indexOf("/r0-OFF") != -1) { //checks if you clicked OFF
      digitalWrite(r0, HIGH);
      Serial.println("Relay-0 OFF");
    }
    if (req.indexOf("/r0-ON") != -1) { //checks if you clicked ON
      digitalWrite(r0, LOW);
      Serial.println("Relay-0 ON");
    }

    if (req.indexOf("/r1-OFF") != -1) { //checks if you clicked OFF
      digitalWrite(r1, HIGH);
      Serial.println("Relay-1 OFF");
    }
    if (req.indexOf("/r1-ON") != -1) { //checks if you clicked ON
      digitalWrite(r1, LOW);
      Serial.println("Relay-1 ON");
    }

    if (req.indexOf("/r2-OFF") != -1) { //checks if you clicked OFF
      digitalWrite(r2, HIGH);
      Serial.println("Relay-2 OFF");
    }
    if (req.indexOf("/r2-ON") != -1) { //checks if you clicked ON
      digitalWrite(r2, LOW);
      Serial.println("Relay-2 ON");
    }

    if (req.indexOf("/r3-OFF") != -1) { //checks if you clicked OFF
      digitalWrite(r3, HIGH);
      Serial.println("Relay-3 OFF");
    }
    if (req.indexOf("/r3-ON") != -1) { //checks if you clicked ON
      digitalWrite(r3, LOW);
      Serial.println("Relay-3 ON");
    }

    if (req.indexOf("/btn0") != -1) { //checks if you clicked OFF
      buton_islemi();
    }

  }

  else {
    Serial.println("invalid request");
   client.stop();
    return;
  }

  // Prepare the response
  String s = "HTTP/1.1 200 OK\r\n";
  s += "Content-Type: text/html\r\n\r\n";
  s += "<!DOCTYPE HTML>\r\n\r\n";

  s += "
<input type=\"button\" name=\"rly0-on\" value=\"Relay-0 ON \" onclick=\"location.href='/r0-ON'\">";
  s += "
";
  s += "
<input type=\"button\" name=\"rly0-off\" value=\"Relay-0 OFF\" onclick=\"location.href='/r0-OFF'\">";

  s += "

";

  s += "
<input type=\"button\" name=\"rly1-on\" value=\"Relay-1 ON \" onclick=\"location.href='/r1-ON'\">";
  s += "
";
  s += "
<input type=\"button\" name=\"rly1-off\" value=\"Relay-1 OFF\" onclick=\"location.href='/r1-OFF'\">";

  s += "

";

  s += "
<input type=\"button\" name=\"rly2-on\" value=\"Relay-2 ON \" onclick=\"location.href='/r2-ON'\">";
  s += "
";
  s += "
<input type=\"button\" name=\"rly2-off\" value=\"Relay-2 OFF\" onclick=\"location.href='/r2-OFF'\">";

  s += "

";

  s += "
<input type=\"button\" name=\"rly3-on\" value=\"Relay-3 ON \" onclick=\"location.href='/r3-ON'\">";
  s += "
";
  s += "
<input type=\"button\" name=\"rly3-off\" value=\"Relay-3 OFF\" onclick=\"location.href='/r3-OFF'\">";

  s += "

";

  s += "
<input type=\"button\" name=\"btn0\" value=\"Button-0 \" onclick=\"location.href='/btn0'\">";
  s += "
";

  s += "\n";

  client.flush();

  // Send the response to the client
  client.print(s);
  delay(1);
}

void buton_islemi() {
  digitalWrite(r0, !digitalRead(r0));
  delay(500);
  digitalWrite(r1, !digitalRead(r1));
  delay(500);
  digitalWrite(r2, !digitalRead(r2));
  delay(500);
  digitalWrite(r3, !digitalRead(r3));
  Serial.println("Button Pressed");
}

you really should use the built-in http lib to make it simpler, more readable, and more flexible, like turning on and off many pins per request, like if(server.arg("r1")=="OFF")

@dandavis could you write simple example? I’m newbie.

i can't do it much better than the examples at File > Examples > ESP8266WebServer >

Just add your button check into the section where you're not handling a client. For example:
static uint8_t buttonState = LOW;
if (!client) {

  uint8_t bs = digitalRead(BUTTON_PIN);
  if (bs != buttonState) {
    buttonState = bs;
    if (buttonState == HIGH) {
      buton_islemi();
    }
  }

  return;
}

Thank you so much, it's working!!


text:
Arduino String: use a non-null-terminated char array?
I'm using a library that takes a String as it's parameter (https://github.com/gmag11/painlessMesh)
I want to pass char arrays that is binary (UTF-8) data that also contains null-bytes (0x00). Right now, the resulting String is cut off at the first null-byte as expected. I know the full length of the char array, is it possible to construct an Arduino String while passing the arbitrary length, so that the full String also contains the null-bytes including the data that follows after, up until the pre-set length?
I had this problem before and then I solved it by converting the UTF-8 data to hex and then add a null-byte. I was hoping there is a more elegant way, since this forces me to double the data-size.
Thanks!

A "String" can't have null characters inside it, so why do you need to pass in data that is not a "String"? Is it because you need to send a message payload that is not a "String"?

The only zero byte the UTF-8 encoding produces is the null character. If the zero byte is anywhere but at the end, then it's not UTF-8.

@josecanuc I don't want to use a String, it's just that the library asks me to pass one.

Assuming you are talking about the function
bool painlessMesh::sendBroadcast( String &msg, bool includeSelf = false)

Then you'll see that ultimately, the library passes msg into the function buildMeshPackage where it constructs a JSON message (see here)
String ICACHE_FLASH_ATTR painlessMesh::buildMeshPackage(uint32_t destId, uint32_t fromId, meshPackageType type, String &msg) {
    debugMsg(GENERAL, "In buildMeshPackage(): msg=%s\n", msg.c_str());

    DynamicJsonBuffer jsonBuffer;
    JsonObject& root = jsonBuffer.createObject();
    root["dest"] = destId;
    //root["from"] = _nodeId;
    root["from"] = fromId;
    root["type"] = (uint8_t)type;

    switch (type) {
    case NODE_SYNC_REQUEST:
    case NODE_SYNC_REPLY:
    {
        JsonArray& subs = jsonBuffer.parseArray(msg);
        if (!subs.success()) {
            debugMsg(GENERAL, "buildMeshPackage(): subs = jsonBuffer.parseArray( msg ) failed!");
        }
        root["subs"] = subs;
        break;
    }
    case TIME_SYNC:
        root["msg"] = jsonBuffer.parseObject(msg);
        break;
    default:
        root["msg"] = msg;
    }

    String ret;
    root.printTo(ret);
    return ret;
}

Even if you did construct a String with null terminators in it, the moment it gets put into the JSON string it destroys everything. JSON by default doesn't support binary data strings (reference).
So, the library is a problem because it happily passes data as JSON messages, and that's bad if you want binary data transported. You could use Base64 or the more efficient http://base91.sourceforge.net/ encoding though to mitigate this a little bit, or search for a different lib.

Wow! Thanks for the fast answer. Alright, I guess I have to settle for non-binary then.. Thanks!

The key part of this answer is to encode your "binary" data. This has been done for ages, and email messages still commonly have base64-encoded "text" for binary file attachments. If the framework takes Strings, then you must convert your binary data to something that looks like a string.

I would've upvoted your answer if I could :) (low rep blocks that at the moment)


text:
4 consecutive bytes in buffer to unsigned long
I wonder if there's a smarter way to get these 4 consecutive bytes from a buffer, concatenated in a unsigned long.
// the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:

unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
Serial.print("Seconds since Jan 1 1900 = ");
Serial.println(secsSince1900);

Seems overkill to me, thinking these 4 bytes are already consecutive in the buffer.
Result should be unchanged i.e. having the value in a variable.

It depends if they are in the same endian order (i.e., little-endian) as the Arduino's long type. Judging by your current method they aren't.

I ended up doing this:
unsigned long ntp_time = 0;
for (byte i = 0; i < 4; i++){
  ntp_time = ntp_time << 8 | (byte) packetBuffer[40 + i];
}

This is what I would have used on a high level language and my first attempt before asking — which failed because it lacked casting to byte.
I still have to understand why it failed, being packetBuffer declared as
const byte *packetBuffer

which to me seems addressing bytes already...
Thanks to Majenko for help, his solution still cast all buffer bytes to 4 bytes, I prefer mine that keeps down to bytes.

The cast to byte is useless. If it failed without the cast, that must be because of some unrelated issue that you fixed around the same time you added the cast. That's the kind of situation when version tracking software can help.

If they were in the same endian order as a long (little-endian on an Arduino, which they don't appear to be) you could just point to them:
uint32_t *l = (uint32_t *)&packetBuffer[40];

Then use *l to access the content as a long.
However since they look to be in a big-endian order it's not that simple. The simplest thing you can do is just re-combine them with bit-shifting:
uint32_t l = ((uint32_t)packetBuffer[40] << 24) | ((uint32_t)packetBuffer[41] << 16) |
             ((uint32_t)packetBuffer[42] << 8) | (uint32_t)packetBuffer[43];

If I add the last line of your code then do Serial.println(secsSince1900, HEX); Serial.println(secsSince1900, HEX); I get DEAAC142 and FFFFC142. Any clue?

Actually, on a little 8-bitter you may need to cast the values to 32 bit before bitshifting to prevent clipping. Been a while since I used little chips like these.

Indeed. If both int and the type of packetBuffer[40] are less than 32 bits, then packetBuffer[40] << 24 invokes undefined behavior.

Thanks for your answers, you helped me finding what was wrong in my code.

An alternative is to use union and struct, and let the compiler do the work:
static inline uint32_t bswap32(uint32_t x)
{
        union {
                uint32_t x;
                struct {
                        uint8_t a;
                        uint8_t b;
                        uint8_t c;
                        uint8_t d;
                } s;
        } in, out;
        in.x = x;
        out.s.a = in.s.d;
        out.s.b = in.s.c;
        out.s.c = in.s.b;
        out.s.d = in.s.a;
        return out.x;
}

uint32_t sinceEpoch = bswap32(*(uint32_t*) &packetBuffer[40]);

Ref. http://lists.nongnu.org/archive/html/avr-gcc-list/2006-12/msg00076.html
A cleaner rewrite for the packet buffer would be:
static inline uint32_t bswap32(uint8_t* buf)
{
        union {
                uint32_t x;
                struct {
                        uint8_t a;
                        uint8_t b;
                        uint8_t c;
                        uint8_t d;
                } s;
        } in, out;
        out.s.a = buf[3];
        out.s.b = buf[2];
        out.s.c = buf[1];
        out.s.d = buf[0];
        return out.x;
}

uint32_t sinceEpoch = bswap32(&packetBuffer[40]);

Here is an AVR machine code version:
inline uint32_t bswap32(uint32_t value)
{
  asm volatile("mov __tmp_reg__, %A0"   "\n\t"
           "mov %A0, %D0"       "\n\t"
           "mov %D0, __tmp_reg__"   "\n\t"
           "mov __tmp_reg__, %B0"   "\n\t"
           "mov %B0, %C0"       "\n\t"
           "mov %C0, __tmp_reg__"   "\n\t"
           : "=r" (value)
           : "0" (value)
           );
  return (value);
}

Ref. Cosa/Types.h, https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/Types.h#L553, and Cosa-NTP/NTP.cpp, https://github.com/mikaelpatel/Cosa-NTP/blob/master/NTP.cpp#L56


text:
PWM should be applied to ENA or IN1/IN2 for L298N board for speed control
I am new to the Arduino stuff and I am using L298N to drive two DC motors. When I searched online for sample code, I noticed that there are two types of design.
One type uses analogWrite(pin, pwmOutput) to control PWM on IN1/IN2 pin to adjust speed, and the other uses digitalWrite(pin, HIGH/LOW) to control IN1/IN2 but use analogWrite(enA, pwmOutput) to control speed.
I guess probably both can work, but I just feel it is not right to apply PWM on the enable pin. Any suggestion from the experts?
One more thing, many people say L298N is obsolete. Would anyone please recommend a replacement motor drive module?

I'd use PWM on EN input. Motor will be driven in HIGH and left floating in LOW. The other method means it'll be shorted (= full on brake).
L298N is based on bipolar transistors. That means relatively big voltage drop between drivers Emitter and Collector (about 2V on each transistor), so there are big power losses (= heat).
Maybe something like LMD18200 could be used as unipolar replacement.

Thanks for your reply, but I don't think the other method means shorted. For examle, IN1 = LOW (one bridge lower arm ON) and IN2 is PWM (the other bridge upper arm PWM), or vice versa, is the common way used in discrete MOSFET H-bridge circuit.

So you have one pin connected to the 0V and second one is alternating between 0V and 12V (I've omitted voltage drops) - what happen, if your motor rotates and you connect both ends to the 0V? Well, with voltage drops that big as in L298N it's not such a big short, but still.

If both ends are connected to 0V, the motor terminals are temperarily connected together through the lower arms of the H-bridge. It is a short brake effect, but it shouldn't be a problem.

@roTor-roTor Except for lower efficiency, bigger losses on transistors... It might be interesting to measure RPMs vs current, minimal pulse width to start rotation from zero RPM ....


text:
Port manipulation
My UNO having some stability issues because of  heavy memory use, I'm now optimizing the code
now looking to reduce the digital read memory use with the help of port manipulation. I got the code for      'digitial write' but no idea for the digital read pinMode(powerStatus, INPUT);digitalRead(powerStatus)
Thanks

how can direct port manipulation instead of digitalWrite/Read reduce dynamic memory use?

Did you read the Arduino tutorial on the subject?

for optimizing my code

@EdgarBonet yes

So you have already read the answer to your question. If you tell us what specific part of that tutorial you found confusing (maybe add a quote), we could try to help clearing up the confusion.

less code will free flash, but not SRAM. even 100% use of flash will not create stability issues

"Heavy memory use" as you put it does NOT cause "stability issues".  What EXACTLY do you mean by "stability issues" here?  If you mean that the part doesn't run reliably and resets itself, it's more likely you have a power supply issue.  If would really help if you would edit your question and indicate exactly what you are doing, what problem you are seeing, etc.  General terms like "stability" and "heavy use" really mean nothing.

Stop using String in your code. That will cure 99% of all memory stability issues.

To read a pin you simply read the port the pin is part of then mask out which pin within that port you want to read.
For example to read pin D11 you need to read bit 3 of port B.
if (PINB & (1 << 3)) {
    // HIGH
} else {
    // LOW
}

However this doesn't address the underlying problems you're having with your sketch.  Saving on flash memory by optimizing your code will not fix instabilities (if anything it will introduce new instabilities from new untested code).
Instabilities related to memory are due to a lack of (or fragmentation of) SRAM not flash.  Optimizing code like this will save flash, but won't directly affect your SRAM usage at all.
Instead you need to optimize your SRAM usage by:

Make sure all string literals are kept in PROGMEM by using the F() macro where appropriate
Avoid use of String and instead stick to char * with pre-allocated buffers.
Don't use new and delete or malloc and free as this will fragment your heap and cause instability (this is the underlying problem with String).


text:
DHT11 thermometer connected to a LCD and 2 servos connected to joysrick
Im trying to find a way to run two codes from the one arduino me being an absolute begginer doesnt even know where to start the DHT11 thermometer is connected to a LCD showing temperature and humidity and uses a "DHTlib" library whereas the joystick controlling 2 servos has no library. I have two seperate working codes but putting them together and getting them to work is a big problem.
The concept is to control a space rover for my school project there will be a camera attathced to the servos so it can move along 2 axes and the thermometer is to prove the rover can gather imformation.

Welcome, I proposed to close it because it's probably helpful to read the duplicated question (which is more generic). In case you have further question, you need to be more specific.
Also I suggest you first try out the components one by one before trying to combine them, especially if you are a beginner.

you are thinking about this incorrectly ... there is no DHT11 connected to LCD ... there is no servos connected to joystick ... these are separate actions ... read temperature from DHT11 and read joystick value and display data on LCD and move servo   .... try to write a sketch that does each of these separately ... read temperature an send the value to serial monitor ... same with joystick ... display "hello world" on LCD ... move servo1 to 90 degrees ... move servo2 to 170 degrees ..... when that all works, then add code to use the temperature value as input to LCD code .. etc.


text:
Multiple definition error when linking firmware.elf
I just can't wrap my head around on how to properly work with multiple files. My code has been getting quite big so I decided to split all the classes into one file each. So I'm left with 6 files:
dataHandler.cpp
fileHandler.cpp
header.cpp
main.cpp
request.cpp
sensorData.cpp

header.cpp includes all the header files, and main.cpp the setup() and loop() functions.
Visual Studio Code shows me no errors while compiling. The includeguards have the name convention: CLASSNAME_INCG
So in my main.cpp for example I have something like:
#ifndef HEADER_INCG
#include "header.cpp"
#define HEADER_INCG
#endif

#ifndef SENSORDATA_INCG
    #include "SensorData.cpp"
    #define SENSORDATA_INCG
#endif

#ifndef DATAHANDLER_INCG
    #include "DataHandler.cpp"
    #define DATAHANDLER_INCG
#endif

setup()
{
    ...
}

...

When going into a class-file I have it defined in the following way (fileHandler.cpp):
#ifndef HEADER_INCG
#include "header.cpp"
#define HEADER_INCG
#endif

#ifndef FILEHANDLER_INCG
#define FILEHANDLER_INCG

class FileHandler{
    ...
}

#endif

So in summary I include the headerfile into every file, with includeguards arround. If I wouldn't include it I would get errors that crucial libaries like Serial etc. are missing. But when including the header into every file compiliing works just fine, but when it comes to linking the files togehter I get an error of multiple definitions.
So how can I define the headerfile just once for all files albeit I need it in every file?

you use the guards wrong. see some library for correct use and use .h files

Rule #1:
Header file extension is ".h". Files with ".cpp" are ususally compiled as separate compilation units into the object file. If you have any function definition (= declaration + implementation) or any global variable in more object files, it'll fail to link.
Rule #2:
No definitions in headers - variables and functions will cause this error if you include .h file into more .cpp files. If you need super global variable, you have to use declaration with extern modifier and you have to define it in one of the .cpp files. But only one! Also there can be only function prototypes (declarations) in header file. Implementation have to be only once in one of the ".cpp" files.

It's usually in the first chapter of books about learning C/C++.
Really short example:
// myLib.h
#ifndef _myLib_h_guard_
#define _myLib_h_guard_

void myFunction(); // function prototype (declaration)

extern int mySuperGlobalVariable;  // variable declared as extern, there must be definition somewhere

class MyClass {
public:
  int someMethod(); // method declaration

  int anotherMethod() { return 1; }  // definition inside of class works, but sometimes is less readable
};

#endif

// myLib.cpp
#include "myLib.h"

void myFunction() { // function implementation (definition)
  // do something...
}

int mySuperGlobalVariable; // definition

int MyClass::someMethod() { return 2; } // method definition

// main.cpp
#include <myLib.h>

int main() {

  mySuperGlobalVariable = 10;

  myFunction();

  MyClass instance;
  int first = instance.someMethod();
  int second = instance.anotherMethod();
}

Could you maybe give me an example on how to do this properly? I'm sure this sounds trivial to you but I hardly understand what you've said.

Thanks a lot :) I tried to declare and initialize it in myLib.cpp and forgot the extern-keyword in myLib.h.

you can use #pragma once instead of the old fashioned #ifndef _myLib_h_guard_ :p


text:
Low power error with serial connection
So I want to create an application where I can send data with a SIM-Module, and when it's not needed it should fall into a "standby-mode" because it's battery powered. But I always get this exact output, and I have no clue why:

wakeup condition fulfilled
Tes

When it wants to print out "Testing ..." it always stops after three letters.
Here's my code:
/*
 *  PINOUT:
 *
 *  UNO >> SIM800L
 *  RX (8) >> TX
 *  TX (9) >> RX
 *
*/

#include <BareBoneSim800.h>

BareBoneSim800 sim800("hologram"); //APN of the carrier

void sendData(char *url)
{
  sim800.enterSleepMode(false);
  Serial.println("Testing GSM module For GPRS Connectivity");
  delay(8000); // this delay is necessary, it helps the device to be ready and connect to a network

  Serial.println("Should be ready by now");
  bool deviceAttached = sim800.isAttached();
  if (deviceAttached)
    Serial.println("Device is Attached");
  else
    Serial.println("Not Attached");

  // Connecting the the GPRS APN Network
  Serial.println(" Connecting to APN");
  bool netConnect = sim800.gprsConnect();
  if (netConnect)
    Serial.println("Connected to Network");
  else
    Serial.println("An Error Occured");

  if (netConnect)
  {
    Serial.println("Making HTTP Get Request");
    String result = sim800.sendHTTPData(url);
    Serial.println("Received Info: ");
    Serial.println(result);

    Serial.println("Current time utc+0: ");
    Serial.println(sim800.getTime());
  }

  sim800.closeHTTP(); // disconnect from server
  sim800.gprsDisconnect();
  sim800.enterSleepMode(true);
}

void wakingUp()
{
  //hardware interrupt measurement goes here
}

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

  while (!Serial)
    ;

  //Save Power by writing all Digital IO LOW - note that pins just need to be tied one way or another, do not damage devices!
  for (int i = 0; i < 20; i++)
  {
    if (i != 8 && i != 9 && i != 2)
    {
      // pin 2 is for waking the arduino up from deep sleep

      //pin 8 and 9 are used to connect with the sim module,
      //these pins must be exluded from power saving
      pinMode(i, OUTPUT);
    }
  }

  attachInterrupt(0, wakingUp, FALLING); //interrupt for waking up

  /*
      various flags for turning stuff down when not needed
based on this very good tutorial https://www.youtube.com/watch?v=urLSDi7SD8M

  */
  //SETUP WATCHDOG TIMER
  WDTCSR = (24);      //change enable and WDE - also resets
  WDTCSR = (33);      //prescalers only - get rid of the WDE and WDCE bit
  WDTCSR |= (1 << 6); //enable interrupt mode

  //Disable ADC - don't forget to flip back after waking up if using ADC in your application ADCSRA |= (1 << 7);
  //ADCSRA &= ~(1 << 7);

  //ENABLE SLEEP - this enables the sleep mode
  SMCR |= (1 << 2); //power down mode
  SMCR |= 1;        //enable sleep

  //BOD DISABLE - this must be called right before the __asm__ sleep instruction
  //MCUCR |= (3 << 5);                      //set both BODS and BODSE at the same time
  //MCUCR = (MCUCR & ~(1 << 5)) | (1 << 6); //then set the BODS bit and clear the BODSE bit at the same time
  __asm__ __volatile__("sleep"); //in line assembler to go to sleep
}

void loop()
{
  //do nothing, use ISR instead
}

char targetURL[] = "http://www.example.com/restAPI/";

ISR(WDT_vect)
{
  //DON'T FORGET THIS!  Needed for the watch dog timer.  This is called after a watch dog timer timeout - this is the interrupt function called after waking up
  //todo, turn on adc conversion again

  int halfHourCounter = 0; //30 minutes => 225 8sec intervals

  bool wakeUpCondition = (halfHourCounter % 225 == 0);

  if (wakeUpCondition)
  {
    Serial.println("wakeup condition fulfilled");
    //reset counter
    halfHourCounter = 0;

    //ADCSRA |= (1 << 7); // turn analog digital conversion back on

    //... measure data and send it away :)
    sendData(targetURL);

    //ADCSRA &= ~(1 << 7); // disable ADC again
  }
  else
  {
    Serial.println("wakeup condition not fulfilled");
  }

  halfHourCounter += 1;

} // watchdog interrupt

I'm using an Arduino Uno in combination with a SIM800L evaluation board. If I call the sendData()-function without any standby-flags enabled everything works fine. Vice versa if I call just a print function for debugging with all the standby flags enabled

Can your battery provide enough current? You didn't specify, what battery you are using and how it is connected

Right! Sorry I forgot about that. At the moment I'm just using a normal USB-Connection for power and reading the serial port.

It seems, that the Sim800 module is drawing too much current, when you start it again. The voltage drops and the Arduino/Sim800 stops working.
This datasheet of the Sim800 states, that it can draw up to 2A when doing a sending burst. An USB port on a computer can provide up to 500mA and you can draw between 200mA to 1A from the Arduino's 5V pin (depending on the version, that you use: Older Unos can provide 200mA, Uno r3 should be able to provide 1A). If you draw too much current through the Arduino from USB, you will fry the diode for voltage source seletion. Also you can fry the electronics of the USB port, if you draw too much current from it (though normally the port should go into shutdown, if you do that, and work again, if you restart the computer).
You have to provide the Sim800 module with enough power and not through the Arduino. You should choose a fitting battery for this. If you don't want to involve a battery at this point, since you are still testing, you can use an USB phone charger to provide enough current.

Thanks! I'll try it out :)


text:
Simulate pin behaviour based on PulseView recording
I have a bunch of PulseView recordings from an existing device. Currently to verify if my Arduino handles the input properly I always use the real device. However it would be great if I could somehow test my code with existing recordings. I am using platform.io. Perhaps there is some test framework that can mock a pin based on a recording? For example when I start the test, pin 8 should be high for 10μs then low for 7 and so on. Is there some framework to mock such things?

that is not an arduino specific question ... it applies to any microcontroller ... if you are talking about a hardware solution, then ask at https://electronics.stackexchange.com/questions

I've never heard of such a test framework and I doubt there is one, at least for hobbyists. Such a framework would need to include a lot of hardware to accommodate all the possible electrical test cases and also a rather complex software to control the hardware according to user input. So it is not really practical to have a general testing framework.
But you can build your own for your specific case. Using another Arduino and outputting the requested pulses should not be too difficult. In the simplest version just some digitalWrite()s and some delayMicroseconds() calls.


text:
Use lowpower-libary and still use serial connection and other things
I managed to get the LowPower libary working on my Arduino Micro. This code works perfectly:
#include <LowPower.h>

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                      // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                  // wait for a second
}

However. I also tried it with a serial connection, to put out some text periodically. But I think the lowpower-libary does - in order to save power - disable this function. So now I am worried that it also disables some other things I might have to use but won't work. Like OneWire or I2C. It also would be nice to work with a functioning standby-mode while developing where serial output is vital, altough it's not neccessary, because I can simulate it with a simple delay. So my question is: How can I use the lowpower-libary AND have a serial connection. And will this libary affect OneWire or I2C? If so: Is there a way on how to keep these "services" running? Or is there maybe another libary wich also saves power in a similar way, but where you have more abilities to customize what you want to have shut down?

Yes, activating low power does disable the UART - but only while it's sleeping.
To use serial you just need to ensure that you only use it while it's not sleeping - and due to the interrupt and buffered nature of the Serial driver it's not as easy as just printing.
However, it's simple to achieve: just flush the serial before sleeping. This ensures that any pending serial data is sent out through the serial port before you go to sleep:
void loop() {
  Serial.println("Turning LED on");
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  Serial.flush();
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                      // wait for a second
  Serial.println("Turning LED off");
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  Serial.flush();
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                  // wait for a second
}

If that doesn't help you may need to turn serial off and on yourself either side of your powerdown:
void loop() {
  Serial.begin(115200);
  Serial.println("Turning LED on");
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  Serial.flush();
  Serial.end();
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                      // wait for a second
  Serial.begin(115200);
  Serial.println("Turning LED off");
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  Serial.flush();
  Serial.end();
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                  // wait for a second
}

Update:
I just noticed you're using the Micro. That makes a big difference. The Micro and the Leonardo's Serial object is actually a USB CDC/ACM serial emulation, not UART.  You cannot sustain a USB connection while sleeping. So it will be killed.
To use communication while sleeping you will have to switch to a proper UART connection with a USB to TTL UART (e.g., FT232RL) adaptor to connect to the TX/RX pins and use Serial1 instead.

Unfortunately that didn't work. When looking into the device-manager of windows there isn't any COM-Port shown. Just when resetting the arduino it shortly appears, but then - in both code versions - it gets disabled. Then windows is already blocking my request accessing COMx, responding that there is no such port.

Ah, I see you've tagged it as you're using a Micro. That makes a big difference. That's USB, not UART. And yes, USB will be killed. You will need to use UART not USB.

Well CAN i use UART on the micro somehow??

Yes. I say how in the addendum to my answer.

Or just stick to Idle instead of going into Power-down. The savings will be less, but USB will stay up.


text:
Connect Arduino and ESP8266 NodeMCU
I want to connect multiple sensors and see their measurements via ESP8266 Web Server. But, the problem is that ESP8266 has only one analog pin and I can't connect multiple sensors to it, so i need to connect it to the Arduino. How can i do that?

you could use I2C ADC module with 4 or 8 analog pins

How to connect it?

what? the I2C module? like any other I2C module. usually to D1/D2

How can I connect the sensors to ESP8266 using I2C module? I'm a beginner, I'm sorry.

https://learn.adafruit.com/adafruit-4-channel-adc-breakouts/signal-connections

Thanks. Helped a lot.


text:
How can I set the SIM900a to Europe?
I got a chinese SIM900a module but it can't connect to the network (I live in Europe). Is there a way to get it work on Europe mobile networks?

Find a provider that still supports GSM. I know that in the USA they are phasing out GSM. Could you tell us the provider you are currently trying to connect to, and in which country?

I am in Croatia...

The SIM900A seems to be carrier locked, and will only work in Asia. It appears you can update the firmware to make it work, as described here https://www.allaboutcircuits.com/projects/how-to-flash-the-sim900a-module/

Thanks. Will check it out? Add reputation?

Here is a manual in Dutch with all the necessary tools. https://drive.google.com/drive/folders/1glNtS7zUH_dMQdc8O_W3YZX4h6nKtPWF?usp=sharing


text:
Stepper Motor is not working with A4988 board
So, I have been following this tutorial on how to run a stepper motor with Arduino using an A4988 Stepper Driver. This is the tutorial: How To Control a Stepper Motor with A4988 Driver and Arduino. I have connected the wires according to this schematic:

I have connected the wires exactly like this and triple-checked it! The problem is the stepper motor is not turning. This is the code(it's simple):
// defines pins numbers
const int stepPin = 3;
const int dirPin = 4;

void setup() {
  // Sets the two pins as Outputs
  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);
}

void loop() {
  digitalWrithe(dirPin,HIGH); // Enables the motor to move in a particular direction
  // Makes 200 pulses for making one full cycle rotation
  for(int x = 0; x < 200; x++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  }
  delay(500); // One second delay
}

One weird thing:

When I connect the sleep and reset pin on the A4988 board the stepper motor starts turning. Like why?

NOTE: I replaced the MEGA with a UNO because at the moment I'm just testing.

Have you tried pulling Sleep and Reset to HIGH, like shown on page 1 and 7 of the A4988 datasheet?

I have NOT. Because I didn't see it. Wait I'll try it out. Thanks!

I have the same problem. My motor is vibrating but not realy moveing. Can you help me?

@PurpleOwl See the answer below, that's what I tried and it worked for me. You essentially need to connect the sleep and reset pin together. If they still don't work, see the debugging options below.

You have to connect the sleep and reset pin together. I assume that you took this schema on how to mechatronics. In his video you see that the sleep and reset pins are connected. I don't know why but it has to be like that.
Then, if the motor vibrates or click, it may be one of these problems:

You didn't connect the motor properly
The current is set too low on the board (screw on the motor driver)
The battery (Vmot) isn't powerful enough

If it's not one of those problems, the A4988 chip might have an issue. I have a similar problem where it turn in one direction and only when the pwm signal goes throught the direction pin  instead of the step pin.

Thanks! The question is from about two years ago. So, I figured it out myself then. But appreciate your effort and am accepting it as an answer. Thanks again :)


text:
DC motors only run in one direction
I'm quite new to Arduino and am making my first proper project, an obstacle avoiding robot.
I'm using an Arduino Uno and a motor shield compatible with the Adafruit motor driver library. I'm trying to run the example code from here: https://learn.adafruit.com/adafruit-motor-shield/using-dc-motors, but with both motors running at once. This should run the motors forward for 1 sec, backward for 1 sec and then pause for 1 sec.
I'm getting inconsistent behaviour when I run the code. When I only connect 1 motor, it works fine. When the Arduino is connected to my laptop via USB, it works fine. However, when I use the 6V external power supply and both motors, they will only move in 1 direction and remain still during the second movement period. When I set them to move forward-backward-stationary, they only move forwards. When I set them to backward-forward-stationary, they only move backwards.
Any ideas what might be causing this / how I could fix it? Like I said, I'm pretty new to this so might be making a simple mistake.
Here's my setup:

I have 2 DC motors, one attached to port 1 and the other to port 4 on the motor shield. The power supply is 4 AA batteries (which I think is 6V?), which is also connected to the motor shield.
And here's my code:
#include <AFMotor.h>

AF_DCMotor leftMotor(1, MOTOR12_1KHZ);
AF_DCMotor rightMotor(4, MOTOR12_1KHZ);

void setup() {
  leftMotor.setSpeed(255);
  rightMotor.setSpeed(255);
}

void loop() {
  leftMotor.run(FORWARD);
  rightMotor.run(FORWARD);
  delay(1000);

  leftMotor.run(BACKWARD);
  rightMotor.run(BACKWARD);
  delay(1000);

  leftMotor.run(RELEASE);
  rightMotor.run(RELEASE);
  delay(1000);
}

Any help is much appreciated!

Possible hardware solution:
Consider using 2 battery packs.  One connected to the Arduino and the other connected to the motor drive board.  Remember to connect the grounds of the 2 battery packs together.
Possible software solution:
Software is often over looked when solving what appears to be a hardware issue.  Consider introducing a short pause between motor direction changes.  It may be that the power required to reverse the direction of a motor exceeds the capacity of the battery pack.  Likely it will take less power to first stop the motor, pause then start the motor in the opposite direction.

Your code looks pretty straightforward, and the fact that everything works properly with the laptop-USB connector makes me suspect that your problem lies with the battery pack.
When you said "When the Arduino is connected to my laptop via USB, it works fine.", did you mean that the 4-cell battery pack is still connected to the motor shield as shown, but the Arduino is being powered from the laptop via USB?
I suspect that what is going on is that during the transition from one direction to the other, the battery voltage temporarily drops below the Arduino's low-voltage cutoff point and everything stops, EXCEPT, when the Arduino is connected to the laptop via USB, the USB connection continues to power the Arduino through the dropout period and everything works.
Since you are starting to work with electronics and Arduino, you might want to consider getting a basic DVM (Digital Volt-AmpMeter) and a basic lab power supply. These two items would allow you to easily troubleshoot this problem.  A common desktop PC power supply with 5, 12 and (sometimes) 24V DC output makes a good bench power supply and are widely available and cheap.
Hope this helps,
Frank

4 AA batteries is 6 volts, which is the right amount of voltage for 2 DC motors. Like all the other answers on this page, the problem most likely has to do with your battery pack, although I am not sure how that would affect your motors. I can't really tell from the picture, but the problem would have to be with the wiring from your battery pack. If you have wires that go from the battery pack, to the motors, you should check to make sure that those are properly wired, as that would be a problem.
I hope this information helps, and the rest of your projects with Arduino go very smoothly!
-Simon


text:
Can the following materials be used to power up an attendance based sensor?
arduino uno, esp8266, rfid module rc522, sd card module, real time clock module, buzzer, led light and battery holder. I was planning to build a sensor that monitors attendance with the use of and RFID card, and I was planning to make it run on its own with the help of a battery instead of being connected to a computer. If not, is there another way that would be possible?

you only need a power supply to power up a sensor ... if you want to read data from the sensor, then you need a power supply,  an arduino and a sensor.... if you want to store the resulting data, then you need to add an SD card module ... if you want to add functionality, then you need to add a module for that functionality

start development with power supply, arduino and sensor

Possible? Yes, totally possible. You won't get really better answers with such a broad question. If this question is mainly about power, then we would need to know, what type of battery you want to use and also how you want to connect it (and everything else, since the Uno is 5V and an ESP is 3.3V)

I'm really new to this so I don't have much knowledge. I was thinking of using a 2 AA batteries connected to a battery holder to power it up because I heard that it would help it last long.

or using a 9 volt battery


text:
How to produce a .o file from code using Arduino IDE (primarily for LGPL3 compliance)
I spent a great deal of time looking for any posts regarding this and came up empty.
The reason I needed to do this is that I am working on some proprietary code that will be released in an embedded device, but makes use of an LGPL 3.0 licensed library which requires (4.d.0) that I release "corresponding application code in a form ... permit the user to recombine or relink the application with a modified version of the library."
Since the application is on an embedded device, the "corresponding application code" works out to the pre-link .o file which is normally well hidden in the Arduino process.

Owen DeLong, as in the Internet Engineering arena? Just curious... it's been a long time.

Just FYI, the Arduino core lib is also LGPL. https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/Arduino.h

To extract the .o produced during compilation in the Arduino IDE, do the following:

Go to the Arduino->Preferences menu item. This will open a preferences window.
In the preferences window find the line that says "Show verbose output during" and make sure that compilation is checked. (you can leave upload on or off as you prefer).
Click "OK" to close the preferences window.
Compile (or compile and upload) your Sketch.

You will get lots of extra output. In the white text, you will either see messages about files being compiled or about "using previously compiled file". In either case, there will be a path provided which will indicate where your Sketch was compiled. On my Mac environment this is /var/folders/<long random string>/T/arduino_build_<number>/sketch/<sketch_name>.ino.cpp.o
The line where your sketch is compiled is very long, but the path is also visible in most of the library lines and you can just work down into .../sketch/... instead of .../library/... instead of scrolling so far to the right on the exactly correct line.
To find the exact line where your sketch is compiled, look for the line directly below a line which simply says "Compiling sketch..."
I know this is rather basic (now that I know how to do it), but it took quite a bit of digging to find it and I figured others might want an answer that's searchable.

Note that the Arduino IDE defaults to compile with link-time optimization enabled, which will make it harder for another user to do the final link, as “bytecode files generated in one version of GCC do not work with an older or newer version of GCC.” I suggest you compile with -flto -ffat-lto-objects in order to alleviate this problem.