message:
RFID Door Lock Coding Errors

I am trying to recreate an RFID door lock that I saw on the Arduino project hub but have ran into several issues. I had to manipulate the code slightly to make sure it was including the correct libraries and I think that solved some issues but not all. If anyone could take a look at my code and help me out that'd be awesome, I am pretty new with coding and need all the help I can get.
Thank you!

Here are the error messages I receive when trying to upload the code to my arduino:
Arduino: 1.8.8 (Mac OS X), Board: "Arduino/Genuino Uno"

    rfid_based_door_automatic_management_system:66:17: error: expected unqualified-id before numeric constant
     #define SDA_D1O 9
                     ^
    /Users/gavinmiles/Documents/rfid_based_door_automatic_management_system/rfid_based_door_automatic_management_system.ino:70:9: note: in expansion of macro 'SDA_D1O'
     MFRC522(SDA_D1O, RESET_D1O);
             ^
    rfid_based_door_automatic_management_system:66:17: error: expected ')' before numeric constant
     #define SDA_D1O 9
                     ^
    /Users/gavinmiles/Documents/rfid_based_door_automatic_management_system/rfid_based_door_automatic_management_system.ino:70:9: note: in expansion of macro 'SDA_D1O'
     MFRC522(SDA_D1O, RESET_D1O);
             ^
    /Users/gavinmiles/Documents/rfid_based_door_automatic_management_system/rfid_based_door_automatic_management_system.ino: In function 'void setup()':
    rfid_based_door_automatic_management_system:120:10: error: expected unqualified-id before '.' token
       MFRC522.initial();
              ^
    /Users/gavinmiles/Documents/rfid_based_door_automatic_management_system/rfid_based_door_automatic_management_system.ino: In function 'void loop()':
    rfid_based_door_automatic_management_system:137:12: error: 'class MFRC522' has no member named 'isCard'
       if( rfid.isCard() )
                ^
    rfid_based_door_automatic_management_system:141:16: error: 'class MFRC522' has no member named 'readCardSerial'
           if( rfid.readCardSerial() )
                    ^
    rfid_based_door_automatic_management_system:152:33: error: 'class MFRC522' has no member named 'serNum'
                   Serial.print(rfid.serNum[i], HEX);
                                     ^
    rfid_based_door_automatic_management_system:154:30: error: 'class MFRC522' has no member named 'serNum'
                   lcd.print(rfid.serNum[i],HEX);
                                  ^
    rfid_based_door_automatic_management_system:165:42: error: 'class MFRC522' has no member named 'serNum'
                   if( My_RFID_Tag[i] != rfid.serNum[i] )
                                              ^
    rfid_based_door_automatic_management_system:274:8: error: 'class MFRC522' has no member named 'halt'
       rfid.halt();
            ^
    Multiple libraries were found for "LiquidCrystal.h"
     Used: /Users/gavinmiles/Documents/Arduino/libraries/LiquidCrystal
     Not used: /Applications/Arduino.app/Contents/Java/libraries/LiquidCrystal
    Multiple libraries were found for "Servo.h"
     Used: /Users/gavinmiles/Documents/Arduino/libraries/Servo
     Not used: /Applications/Arduino.app/Contents/Java/libraries/Servo
    exit status 1
    expected unqualified-id before numeric constant
    /Users/gavinmiles/Downloads/untitled_file.ino

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

    /*
     *  RFID Module RC522
     *  Simple Project:- Arduino will read RFID Tag and Display To the Serial Monitor!
     *
     *  RFID RC522 and Arduino Uno Pin Configuration
     *
     *  RFID RC522          Arduino Uno
     *  SS/SDA              D10
     *  SCK                 D13
     *  MOSI                D11
     *  MISO                D12
     *  IRQ                 Not Connected
     *  GND                 GND
     *  RST                 D9
     *  3.3V                3.3V
     *
     *  //Note: We connected LCD to the Analog Pins.
     *  Remember, Analog Pins can be act as a Digital Pins,
     *  But Digital Pins CAN NOT be act as a Analog Pins.
     *
     *  LCD(16x2) Connections
     *
     *  VSS pin to GND
     *  VCC pin to 5V
     *  //We are connecting "Contrast pin to GND for Maximum Brightness"
     *  //You can also connect it to 10K Pot if you wish to change the Brightness Of LCD.
     *  VEE pin to GND
     *  RS pin to Analog pin A0
     *  R/W pin to ground
     *  Enable pin to Analog pin A1
     *  D4 pin to Analog pin 5
     *  D5 pin to Analog pin 4
     *  D6 pin to Analog pin 3
     *  D7 pin to Analog pin 2
     *  LED+ pin to POWER
     *  LED- pin to GND
     *
     *  Servo is Connected to Digital Pin 5
     *
     *  RGB LED
     *  From RGB LED, We need Only Red and Green Color,
     *  So we are not connecting Blue pin of the RGB.
     *
     *  Red pin to Digital pin 6
     *  Green pin to Digital pin 7
     *
     *  Buzzer to Digital pin 8
     *
     *
     *  Note:- RFID uses SPI Protocol to transfer the information.
     *  I took the Melody(for the Buzzer) from,
     *  File -> Examples -> Digital -> ToneMelody
    */

    //Include sections
    #include <MFRC522.h>
    #include <SPI.h>
    #include <LiquidCrystal.h>
    #include <Servo.h>
    #include "pitches.h"

    //Define Component to Arduino Pins
    /* Define the DIO used for the SDA (SS) and RST (reset) pins. */
    #define SDA_D1O 9
    #define RESET_D1O 8

    /* Create an instance of the RFID library */
    MFRC522(SDA_D1O, RESET_D1O);
    #define SS_PIN 10
    #define RST_PIN 9

    #define SERVO_PIN 5

    #define Red_LED 6
    #define Green_LED 7

    #define Buzzer 8

    //initialize the library with the numbers of the interface pins
    LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
    Servo DoorLock;
    MFRC522 rfid(SS_PIN, RST_PIN );

    //Unique ID of RFID Tag, which you want to give access.
    int My_RFID_Tag[5] = {0x58,0x76,0x17,0x10,0x29};

    //variable to hold your Access_card
    boolean My_Card = false;

    // notes in the melody, taken from:
    //File -> Examples -> Digital -> ToneMelody
    int melody[] = {
      NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
    };

    // note durations: 4 = quarter note, 8 = eighth note, etc.:
    int noteDurations[] = {
      4, 8, 8, 4, 4, 4, 4, 4
    };

    void setup()
    {
      // put your setup code here, to run once:
      //set the pins as an input/output
      pinMode(Red_LED,OUTPUT);
      pinMode(Green_LED,OUTPUT);
      pinMode(Buzzer,OUTPUT);

      //Servo Connnected to pin Digital Pin 5
      DoorLock.attach(SERVO_PIN);
      //open the serial port at 9600 baudrate.
      Serial.begin(9600);
      //Initialise the LCD to 16x2 Character Format
      lcd.begin(16,2);
      //Initialise Servo and RFID
      SPI.begin();
      MFRC522.initial();
    }

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

      //First Assume detected card(Or tag) is My_Card,
      //Then later we will check is it My_Card or not!
      My_Card = true;
      DoorLock.write(0); //Servo at 0 Position, Door is Closed.
      lcd.clear();
      lcd.print("Robodia Technology");
      lcd.setCursor(0,1);
      lcd.print("gy Solutions!");

      //Check if any RFID Tags Detected or not?
      if( rfid.isCard() )
      {
          //if RFID Tag is detected, check for the Unique ID,
          //and print it on the Serial Window
          if( rfid.readCardSerial() )
          {
              lcd.clear();
              lcd.print("UNIQUE ID is:- ");
              delay(500);
              lcd.setCursor(0,1); //Set LCD Cursor to Second Row, First Character

          //Unique id is 5 Digit Number.
              //Printing in HEX for better Understanding
              for( int i = 0; i < 5; i++ )
              {
                  Serial.print(rfid.serNum[i], HEX);
                  Serial.print(" ");
                  lcd.print(rfid.serNum[i],HEX);
                  lcd.print(" ");
              }
              delay(500);

          //Compare this RFID Tag Unique ID with your My_RFID_Tag's Unique ID
              for(int i = 0; i < 5; i++)
              {
                  //if any one Unique ID Digit is not matching,
                  //then make My_Card = false and come out from loop
                  //No need to check all the digit!
                  if( My_RFID_Tag[i] != rfid.serNum[i] )
                  {
                    My_Card = false;
                    break;
                  }
              }
              Serial.println();
              delay(1000);

              //If RFID Tag is My_Card then give access to enter into room
              //else dont open the door.
              if(My_Card)
              {
                Serial.println("\nWelcome To Your Room, Robodia!");
                lcd.clear();
                lcd.print("Welcome to Your");
                lcd.setCursor(0,1);
                lcd.print("Room, Robodia!");
                delay(2000);

                //Turn on the Green LED as an indication of permission is given
                //to access the room.
                digitalWrite(Green_LED,HIGH);

                //Buzzer Config, taken from:
                //File -> Examples -> Digital -> ToneMelody
                // iterate over the notes of the melody:
                int i = 0;
                while(i < 2)
                {
                  for (int thisNote = 0; thisNote < 12; thisNote++)
                  {
                    // to calculate the note duration, take one second
                    // divided by the note type.
                    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
                    int noteDuration = 1000 / noteDurations[thisNote];
                    tone(8, melody[thisNote], noteDuration);
                    // to distinguish the notes, set a minimum time between them.
                    // the note's duration + 30% seems to work well:
                    int pauseBetweenNotes = noteDuration * 1.30;
                    delay(pauseBetweenNotes);
                    // stop the tone playing:
                    noTone(8);
                  }
                  i =  i + 1;
                  delay(500);
                }
                delay(1000);

                //Now, Open the Door with the help of Servo Motor
                DoorLock.write(180);
                delay(200);
                lcd.clear();
                lcd.print("Door is Open");
                lcd.setCursor(0,1);
                lcd.print("Now!");
                delay(2000);
                lcd.clear();

                //Give 10 Sec delay to enter into room
                //After that door will again closed!
                for(int i = 10; i > 0; i--)
                {
                  lcd.print("Door will close");
                  lcd.setCursor(0,1);
                  lcd.print("in ");
                  lcd.print(i);
                  lcd.print(" Sec.HurryUp!");
                  delay(1000);
                  lcd.clear();
                }

                //Now,Door is closed and Green LED is Turned-Off.
                DoorLock.write(0);
                digitalWrite(Green_LED,LOW);
                delay(200);
                lcd.clear();
                lcd.print("Door is Close");
                lcd.setCursor(0,1);
                lcd.print("Now!");
                delay(2000);
              }

              // If RFID Tag is not My_Card then
              // Do not open the Door and
              //Turn-On Red LED and Buzzer as an indication of Warning:
              //Somebody else is trying to enter into your room.
              else
              {
                Serial.println("\nGet Out of Here !");
                lcd.clear();
                lcd.print("Card isNOT FOUND!");
                lcd.setCursor(0,1);
                lcd.print("Get Out of Here!");

                for(int i = 0; i < 7; i++)
                {
                  digitalWrite(Buzzer, HIGH);
                  digitalWrite(Red_LED,HIGH);
                  delay(500);
                  digitalWrite(Buzzer, LOW);
                  digitalWrite(Red_LED,LOW);
                  delay(500);
                }
                delay(1000);
              }
          }
       }
      //Put RFID Reader into Halt, untill it not detects any RFID Tag.
      rfid.halt();
    }

body:
I had seen many errors in your code. Some of them are as follows

 1. `MFRC522.initial();` replace it with `rfid.initial();`
 2. Libraries such as liquidcrystal, servo are default libraries in arduino so if you had download them from external source and copied them in your library folder please remove them.
 3. This logic won't help as if the first id didn't match it will break the loop and and comparison won't go further with other and your will always find false as a result in this case.

              for(int i = 0; i < 5; i++)
          {
              //if any one Unique ID Digit is not matching,
              //then make My_Card = false and come out from loop
              //No need to check all the digit!
              if( My_RFID_Tag[i] != rfid.serNum[i] ) // suggested change if( My_RFID_Tag[i] == rfid.serNum[i] )
              {
                My_Card = false;//My_Card = true
                break;
              }
          }

 4. Library functions used in code are different from those available in library, open library file and search for those function used for same purpose.

 5. Remove them

        #define SDA_D1O 9
        #define RESET_D1O 8
        MFRC522(SDA_D1O, RESET_D1O);
you are already defining them and using them here in your code

        #define SS_PIN 10
        #define RST_PIN 9
        MFRC522 rfid(SS_PIN, RST_PIN );


sender: user

message:
Digispark Micro (ATTINY85) not working on Macbook Pro 2016

I just bought 2 Digispark Micro to start learning some Arduino things.

But when I try to upload the code to my Digispark, it just send me an "Device search timed out" error.

My Digispark is plugged with an USB-C to USB connector and the Red dot on the Digispark is working. The connector is working well with any other device.

**Arduino app (1.8.9) settings:**

- Tools
 - Board → Digispark (Default - 16.5 mhz)
 - Programmer → Micronucleus

I tried using the [micronucleus CLI][1], but, even if I try plug/unplug several times (~10s between each unplug/plug) I got this :

    > Please plug in the device ...
    > Press CTRL+C to terminate the program.

  [1]: https://github.com/micronucleus/micronucleus/tree/master/commandline

sender: assistant

body:
Digisparks are known to have problems with USB3 ports (which your USB-C adaptor probably provides). Try using a cheap USB2 hub between the DigiSpark and the adaptor.

It's always a good idea to use a cheap USB hub between whatever experimental device you want to connect and your machine, so that if you wire something up incorrectly you don't end up frying an expensive laptop. This is particularly true for a device such as the digispark which does not have a real USB interface but really bit-bangs the protocol out of ordinary I/O pins.

There is no guarantee that the hub will protect you from all wiring mistakes, but it's an added level of protection.


message:
Interrupt triggering using DHT-11

I am new at arduino.
I want to write a sketch that would print the message if the temperature grows greater than 30 C.
Here is my sketch can you please tell me what's wrong with it

    #include "DHT.h"
    #define DHTTYPE DHT11
    #define dht_dpin D3

    DHT dht(dht_dpin, DHTTYPE);

    void setup()
    {
     Serial.begin(9600);
     }
    void loop()
    {
     float t = dht.readTemperature();
     Serial.print("temp=");
     Serial.println(t);
     attachInterrupt(dht_dpin, IntCallback, CHANGE);
    }
    void IntCallback()
    {
      float t = dht.readTemperature();
      if(t>30)
      {
        Serial.print("Alert");
      }
    }

body:
You can't use an interrupt the way you are attempting to. Attaching an interrupt to a pin like that will cause the interrupt to trigger any time the digital pin's value changes. The DHT11 uses serial communication to send temp values to the Arduino. Serial communication uses lots and lots of on/off pulses on the signal line to send characters of data. Your interrupt will fire every time the DHT11 toggles the signal line.

You need to read the temp from the DHT11 in your loop, and then add an if statement that does what you want when the temp exceeds your threshold. (It looks like you just need to get rid of the attachInterrupt() call, and instead call IntCallback() every couple of seconds.


body:
You don't even need an interrupt.Modification:

    #include "DHT.h"
    #define DHTTYPE DHT11
    #define dht_dpin D3

    DHT dht(dht_dpin, DHTTYPE);

    void setup()
    {
     Serial.begin(9600);
     }
    void loop()
    {
     float t = dht.readTemperature();
     Serial.print("temp=");
     if(t>30)
      {
        Serial.print("Alert");
      }
    }


message:
May mulitple sensor connect to one arduino uno board since they shared same pin?

i am a Arduino beginner here. I start knowing about Arduino since my supervisor give me this project. In my project , i need to invent a car safety system to avoid animal hurting that hide under vehicle and solve drowsy driving problem. In sensor requirement, i choose to use PIR motion sensor (HC-SR501) to sense the movement of living things under the car, for the drowsy driving i choose to use pulse sensor and eye blink sensor to detect whether the driver is sleeping or not, it the driver is sleeping then it will activate alarm and led light on. But during research, i found that these 3 sensor have sharing the same pin with is the pin 2 (picture attach). So may is ask is possible to connect these all 3 sensor in one board ?? May i ask how can i do it if i connect the pins to the breadboard ??
Last question is do i need have MEMS MPU -6050 sensor in my project since i found this is with the eye blink sensor in other person research. Thank for accepting my question.

[![pulse sensor][1]][1]

[![pir motion sensor][2]][2]

[![mems mpu -6050 sensor][3]][3]

  [1]: https://i.stack.imgur.com/u4nLz.png
  [2]: https://i.stack.imgur.com/DcWly.png
  [3]: https://i.stack.imgur.com/FDRUF.png

body:
You did not provide a picture, or any other information.

Given how little info you provided, the answer is "it depends".

PIR sensors tend to use digital lines that change state when they detect motion. You would not want to share an input line with such a PIR. (I couldn't find a spec-sheet on your PIR with a quick search.)

For devices that use serial communication, the I2C interface standard **is** designed for connecting multiple devices on the same serial bus. If you have multiple I2C devices, you should connect them all to the same pins, and it works great as long as they have different device addresses on the I2C bus.

Other types of serial interfaces are only designed for 2 devices to communicate with each other, and cannot be shared.


body:
Your drawing seems to show plenty of pins available, with only pin 2 in common. If the pin is being used for an Interrupt, then one device can use a different pin instead and the code adapted to use PCINT for the interrupt.

I would suggest the PIR does not even need an interrupt, it is slow changing and polling it for activity would be just as effective.

Add some current limit resistors to your LEDs so you don't damage the IO pins.


message:
Sporadically corrupted data returned from ESP8266

I have an Arduino Uno connected to an ESp8266 via an ESP-01 adapter.  The Adapter is powered from the Arduino 5v and Gnd pins and the Tx/Rx to the Adapter use Arduino pins 2/3. I have basic code which sets the ESP8266 as an access point and I am able to connect to the AP from my phone, send a message and receive a reply from the ESP8266.  This works fine for 75% of the time.  other times, the message received by ESP8266 ( and printed on the serial monitor for debug ) is truncated, and/or corrupted.
I have tried a different ESp8266 and a different adapter; I don't get corruption errors with other programs run on the Uno; I have dropped the communications speed between the Uno and ESp8266 to 9600 baud.
What could be the cause of the corruption I am seeing in the data ? Thanks

I have updated my app an no longer get corrupted data, but there are characters data missing from the returned data stream.

Here is my sketch :
````
#include <SoftwareSerial.h>

//
// ESP8266 interface
////////////////////

SoftwareSerial wifiSerial(2, 3);            // RX, TX for ESP8266

#define TICK  100

bool DEBUG = true;
int responseTime = 1000;

#define ESP8266CMD_SET_UART_9600            "AT+UART_CUR=9600,8,1,0,3"
#define ESP8266CMD_SET_UART_38400           "AT+UART_CUR=38400,8,1,0,0"

#define ESP8266CMD_ECHO_OFF                 "ATE0"
#define ESP8266CMD_ECHO_ON                  "ATE1"
#define ESP8266CMD_SET_WIFI_STATION_MODE    "AT+CWMODE=1"
#define ESP8266CMD_SET_WIFI_SOFTAP_MODE     "AT+CWMODE=2"
#define ESP8266CMD_GET_IP_ADDRESS           "AT+CIFSR"
#define ESP8266CMD_CONFIG_AP_LIST_ALL       "AT+CWLAPOPT=1,2047" // Sort and display all netwroks
#define ESP8266CMD_CONFIG_AP_LIST           "AT+CWLAPOPT=1,3"    // Sort and display ECN / ESSID only
#define ESP8266CMD_LIST_AVAILABLE_APS       "AT+CWLAP"

#define ESP8266CMD_SEND_DATA                "AT+CIPSEND=0,"     // required data length to be appended
#define ESP8266CMD_CLOSE_ALL_CONNECTIONS    "AT+CIPCLOSE=5"

//
// LCD interface
////////////////

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR                            0x27
#define BACKLIGHT_PIN                       3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

//
// S E T U P
////////////

void setup()
{
  Serial.begin(115200);
  Serial.println("Initialising...");

  lcd.begin( 16, 2 );                                 //  LCD is 16x2

  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);        // Switch on the backlight
  lcd.setBacklight(HIGH);

  lcd.home();
  lcd.print("Initialising...");

  wifiSerial.begin(9600);

  sendToWifi( ESP8266CMD_ECHO_OFF, responseTime, DEBUG );
  sendToWifi( ESP8266CMD_SET_WIFI_STATION_MODE, responseTime, DEBUG );

  sendToWifi( ESP8266CMD_CONFIG_AP_LIST, responseTime, DEBUG );

  Serial.println("Wifi connection is running!");

  lcd.clear();
  lcd.print("Ready");

  pinMode(13,OUTPUT);  //set build in led as output
}

//
// L O O P
//////////

void loop()
{
String APList = sendToWifi(ESP8266CMD_LIST_AVAILABLE_APS, responseTime, DEBUG);

  Serial.println(APList);

  delay(100 * TICK);
}

/*
* Name:         sendToWifi
* Description:  Send data to ESP8266.
* Params:       command - the data/command to send
*               timeout - the time to wait for a response
*               debug - print to Serial window?(true = yes, false = no)
* Returns:      Response from the esp8266 (if there is a reponse)
*/
String sendToWifi(String command, const int timeout, boolean debug){
 String response = "";

 if(debug)
    Serial.println( "Command[" + command + "]" );

 wifiSerial.println(command);       // send string esp8266

 long int time = millis();
 while( (time+timeout) > millis())
 {
   while(wifiSerial.available())
   {
   char c = wifiSerial.read();      // read resonse

    response += c;
    time = millis();                // data received - reset timeout
   }
 }
 if(debug)
    Serial.println( "Response[" + response + "]" );

 return response;
}
````
..and here is output debug data from a sample run.
````
Initialising...
Command[ATE0]
Response[
OK
]
Command[AT+CWMODE=1]
Response[
OK
]
Command[AT+CWLAPOPT=1,3]
Response[
OK
]
Wifi connection is running!
Command[AT+CWLAP]
Response[]

Command[AT+CWLAP]
Response[+CWLAP:(4,"VM2293456_EXT")
+CWLAP:(3,"NVR9ca3a92708f2")
+CWLA]
+CWLAP:(4,"VM2293456_EXT")
+CWLAP:(3,"NVR9ca3a92708f2")
+CWLA
Command[AT+CWLAP]
Response[+CWLAP:(4,"VM2293456_EXT")
+CWLAP:(4,"VM2293456")
+CWLAP:(5,"]
+CWLAP:(4,"VM2293456_EXT")
+CWLAP:(4,"VM2293456")
+CWLAP:(5,"
````
As well as the two networks VM2293456 and VM2993456_EXT there are a number of other netwroks available, and on some runs I see those networks shown. In any case, there are missing characters from the response text.

body:
AT firmware writes the data to Serial without any control. If the data are not read fast the Serial buffer overflows. If you count the bytes read by your sketch (including 2 not visible line ending characters per line) you count 64 bytes. That is the size of the RX buffer of SoftwareSerial. SoftwareSerial can tell you if the buffer overflowed. Call `wifiSerial.overflow()`.

The CWLAP takes time to execute on esp8266 side and then the AT firmware puts out the complete listing to Serial. Reading it byte by byte and storing millis() in-between is then too slow. You need to read it faster with a buffer.

I use `readBytesUntil` to read a line into buffer. This function waits for the next byte if there is a gap between bytes and stops reading if terminator is received or it times out. Default timeout is 1000 millis. It can by set with `setTimeout(t)`.

In your sketch you use String. I do not recommend it for a project, but in a test you could use:

    result += wifiSerial.readStringUntil('\n');

to read and append a whole line.


body:
Taking the information that people have kindly offered to me, I have re-written my code to use the AltSoftSerial library and I now have my small app working fine.  Thanks.  AltSoftSerial uses pins 8/9 in an interrupt driven manner, leaving the 'standard' pin 1/2 serial comms for a debug channel.  I have it running at 19200 baud.
I have remove String variable from the code and my final improvement will be to use malloc() to allocation data buffer in place of the current statically declared buffer.
The purpose of my test app is to connect to my home wifi network a to print out the IP address allocated.  All output goes to an LCD display, but the serial monitor could be used instead.

Here's my code :

````
#include <AltSoftSerial.h>
#include "ESP8266_cmd.h"

//
// Connect to home WiFi network using AltSoftSerial via pins 8/9 to ESP8266
///////////////////////////////////////////////////////////////////////////

//
// ESP8266 interface
////////////////////

AltSoftSerial wifiSerial;                   // RX, TX for ESP8266

#define TICK  100

#define DEBUG                               false
#define ResponseTime                        1000

#define NW_CREDENTIALS                      "\"VM2293456\",\"----------\""

//
// LCD defines
//////////////

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR          0x27
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

int n = 1;

LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

//
// Buffer for ESP8266 data
//////////////////////////

#define BUFFER_LEN    512
char Buffer[BUFFER_LEN];

//
// State Machine
////////////////

enum {
 STATE_INIT_WIFI = 0,
 STATE_WIFI_CONNECT,
 STATE_WAIT_FOR_CONNECTED,
 STATE_GET_IP_ADDRESS,
 STATE_WAIT,

 STATE_ERROR,
} State;

int MachineState = STATE_ERROR;
int ErrorCode = 0;

void setup()
{
String response;

  Serial.begin(115200);
  Serial.println("Initialising...");

  lcd.begin( 16, 2 );                                 //  LCD is 16x2.  Cmd is Column, Row

  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);        // Switch on the backlight
  lcd.setBacklight(HIGH);

  lcd.clear();
  lcd.home();
  lcd.print( "Network Connect " );

  wifiSerial.begin(19200);

  MachineState = STATE_INIT_WIFI;
}

void loop()
{
String response;
char cmd[64];

  switch( MachineState )
  {
  case STATE_INIT_WIFI:
    lcd.setCursor( 0, 1);
    lcd.print("Initialising    ");

    sendToWifi( ESP8266CMD_ECHO_OFF, ResponseTime, DEBUG );
    if( strcmp( Buffer, "OK" ) != 0 )
    {
      ErrorCode = 1;
      MachineState = STATE_ERROR;
      break;
    }

    sendToWifi( ESP8266CMD_SET_WIFI_STATION_MODE, ResponseTime, DEBUG );
    if( strcmp( Buffer, "OK" ) != 0 )
    {
      ErrorCode = 2;
      MachineState = STATE_ERROR;
      break;
    }
    MachineState = STATE_WIFI_CONNECT;
    break;

  case STATE_WIFI_CONNECT:
    lcd.setCursor( 0, 1);
    lcd.print("Connecting           ");

    strcpy( cmd, ESP8266CMD_CONNECT_TO_AP );
    strcat( cmd, NW_CREDENTIALS );
    sendToWifi( cmd, ResponseTime, DEBUG );
    MachineState = STATE_WAIT_FOR_CONNECTED;
    break;

  case STATE_WAIT_FOR_CONNECTED:
    lcd.setCursor( 0, 1);
    lcd.print("Wait for connect");
    readFromWiFi( ResponseTime );
    if( strstr(Buffer, "WIFI GOT IP") != NULL )
       MachineState = STATE_GET_IP_ADDRESS;
    else
       delay( 1000 );
    break;

  case STATE_GET_IP_ADDRESS:
    lcd.setCursor( 0, 1);
    lcd.print("Getting IP Addr ");

    sendToWifi(ESP8266CMD_GET_IP_ADDRESS,ResponseTime,DEBUG);

    MachineState = STATE_ERROR;   // prime for error case
    ErrorCode = 3;

    if( strstr( Buffer, "OK" ) != NULL )
    {
      if( strncmp( Buffer, "+CIFSR:STAIP", 12 ) == 0 )
      {
        lcd.setCursor( 0, 1 );
        lcd.print( "                " );
        lcd.setCursor( 0, 1 );
        for( int i = 15; i < strlen(Buffer ); i++ )
        {
          if( Buffer[i] == '"' )
            Buffer[i] = '\0';
        }
        lcd.print( &Buffer[14] );   // Display extracted IP address
        MachineState = STATE_WAIT;
      }
    }
    break;

  case STATE_WAIT:
    delay(10000);
    MachineState = STATE_GET_IP_ADDRESS;
    break;

  case STATE_ERROR:
  default:
    lcd.setCursor( 0, 1 );
    lcd.print( "                " );
    lcd.setCursor( 0, 1 );
    strcpy( cmd, "Err " );
    itoa( ErrorCode, &cmd[strlen(cmd)], 10 );
    lcd.print( cmd );
    delay(10000);
    break;
  }
}

/*
* Name:         readFromWiFi
* Description:  Read data from ESP8266.
* Params:       timeout - the time to wait for a response
*               debug - print to Serial window?(true = yes, false = no)
* Returns:      Response from the esp8266 (if there is a reponse) in Global Buffer
*/
void readFromWiFi(int timeout)
{
int l = 0;
long int t = millis();

    while( ( t + timeout ) > millis() ){
      while( wifiSerial.available() > 0 ) {
        Buffer[l++] = wifiSerial.read();
        t = millis();
       }
    }

    Buffer[l] = '\0';

    trimRight( Buffer );
    trimLeft( Buffer );
}

/*
* Name: sendToWifi
* Description: Function used to send data to ESP8266.
* Params: command - the data/command to send; timeout - the time to wait for a response; debug - print to Serial window?(true = yes, false = no)
* Returns: The response from the esp8266 (if there is a reponse)
*/
void sendToWifi( const char *command, const int timeout, boolean debug){

 if(debug)
 {
    Serial.print( "Command[" );
    Serial.print( command );
    Serial.println( "]" );
 }

 wifiSerial.println( command );       // send string esp8266

 readFromWiFi( timeout);

 if(debug)
  {
    Serial.print( "Response[" );
    Serial.print( Buffer );
    Serial.println( "]" );
  }
}

void trimRight( char *src )
{
  int i = strlen(src)-1;

  for( ; i >= 0; i-- )
  {
    if( (src[i] != ' ' ) && ( src[i] != '\t' ) && ( src[i] != '\n' ) )
      break;
  }
  src[i] = '\0';
}

void trimLeft( char *src )
{
  int i, l = strlen(src);

  for( i = 0; i < l; i++ )
  {
    if( (src[i] != ' ' ) && ( src[i] != '\t' ) && ( src[i] != '\n' ) && ( src[i] != '\r' ) )
      break;
  }
  memmove( src, &src[i], l);
}
````

and here is the ESP822_cmd.h header file that I created :

````
// ESP82266_cmd.h
//
// #defines for ESP8266 interface
//

#define ESP8266CMD_SET_UART_9600            "AT+UART_DEF=9600,8,1,0,0"
#define ESP8266CMD_SET_UART_19200           "AT+UART_DEF=19200,8,1,0,0"
#define ESP8266CMD_SET_UART_38400           "AT+UART_CUR=38400,8,1,0,0"

#define ESP8266CMD_ECHO_OFF                 "ATE0"
#define ESP8266CMD_ECHO_ON                  "ATE1"
#define ESP8266CMD_SET_WIFI_STATION_MODE    "AT+CWMODE=1"
#define ESP8266CMD_SET_WIFI_SOFTAP_MODE     "AT+CWMODE=2"
#define ESP8266CMD_GET_IP_ADDRESS           "AT+CIFSR"
#define ESP8266CMD_CONFIG_AP_LIST_ALL       "AT+CWLAPOPT=1,2047" // Sort and display all netwroks
#define ESP8266CMD_CONFIG_AP_LIST           "AT+CWLAPOPT=1,3"    // Sort and display ECN / ESSID only
#define ESP8266CMD_LIST_AVAILABLE_APS       "AT+CWLAP"

#define ESP8266CMD_SEND_DATA                "AT+CIPSEND=0,"      // required data length to be appended
#define ESP8266CMD_CLOSE_ALL_CONNECTIONS    "AT+CIPCLOSE=5"

#define ESP8266CMD_CONNECT_TO_AP            "AT+CWJAP_CUR="      // required essid and password to be appended
```


message:
Read nested array item from PROGMEM

I have a 2D array of uint16_t arrays (IR Remote Codes). Due to the size of this data in RAM I'm having all kinds of trouble when my array is larger than one code. Thus, I have been trying to move this whole structure into PROGMEM. Following various tutorials and [this solution][1], I have come up with the code below for reading a single element out of the array and into a variable that I can feed to the IRLIB2 IRSendRaw function.

The variable that holds the code that is read out of PROGMEM is still huge and causing some problems. Is there a more direct way like a python list comprehension to access an arbitrary element and send it directly to the IRSender?

[This PROGMEM_readAnything library][2] looks promising, but I don't have enough C++ fu to make the mental leap to implement it in my code.

```
#include <IRLibSendBase.h>    //We need the base code
#include <IRLib_HashRaw.h>    //Only use raw sender

#define RAW_DATA_LEN 68
const uint16_t sources[3][RAW_DATA_LEN] PROGMEM =
  {{8550, 4306, 530, 1606, 530, 566, 502, 1610, //power on/off
  530, 566, 502, 574, 506, 1630, 506, 566,
  506, 1630, 506, 566, 502, 1610, 530, 566,
  502, 1634, 506, 1606, 530, 570, 498, 1634,
  506, 570, 510, 562, 506, 566, 502, 1634,
  506, 1606, 530, 1610, 530, 562, 538, 538,
  530, 542, 538, 1598, 538, 1570, 558, 542,
  538, 538, 530, 542, 538, 1598, 530, 1578,
  558, 1578, 562, 1000},

  {8546, 4310, 558, 1578, 562, 538, 498, 1638,  //source CD
  530, 542, 506, 570, 502, 1634, 502, 570,
  498, 1638, 534, 538, 498, 1638, 530, 542,
  506, 1606, 554, 1582, 558, 538, 510, 1602,
  554, 546, 506, 566, 502, 570, 510, 1602,
  554, 1582, 558, 538, 510, 566, 502, 1606,
  554, 546, 502, 1610, 558, 1574, 554, 546,
  502, 570, 510, 1602, 526, 1610, 526, 574,
  506, 1602, 526, 1000},

  {8550, 4306, 530, 1606, 534, 566, 502, 1606,  //source CDR
  534, 566, 502, 570, 510, 1602, 526, 570,
  510, 1602, 534, 566, 502, 1606, 534, 566,
  506, 1602, 530, 1606, 534, 566, 502, 1610,
  530, 570, 498, 574, 506, 566, 502, 570,
  510, 1602, 526, 570, 510, 566, 502, 570,
  510, 1602, 526, 1610, 526, 1606, 534, 1602,
  534, 566, 502, 1610, 530, 1602, 534, 1602,
  526, 574, 506, 1000}};

//Create a sender
IRsendRaw mySender;

//Read out one code into a variable and send to the IR transmitter
uint16_t myCode[RAW_DATA_LEN];
for (int i = 0; i < RAW_DATA_LEN; i++) {
   myCode[i] = pgm_read_word_near(sources[0] + i);
}
mySender.send(myCode,RAW_DATA_LEN,36);
```

  [1]: https://arduino.stackexchange.com/questions/61889/accessing-2-dimensional-array-in-progmem-inside-loop
  [2]: https://arduino.stackexchange.com/questions/13545/using-progmem-to-store-array-of-structs

body:
The library, as it stands, doesn't support direct sending from PROGMEM.  However it's not too hard to get around that - if your C++ is up to it.

The IRsendRaw class is a child class that extends the IRsendBase with a single function.  You just need to do the same thing to create a new class that implements the functions in a way that can read from PROGMEM.

This is the original:

    class IRsendRaw: public virtual IRsendBase {
      public:
        void send(uint16_t *buf, uint8_t len, uint8_t khz) {
          enableIROut(khz);
          for (uint8_t i = 0; i < len; i++) {
            if (i & 1) {
              space(buf[i]);
            }
            else {
              mark(buf[i]);
            }
          }
          space(0); // Just to be sure
        }
    };

You just need to make your own one of those in your sketch, called something different, and which uses the progmem functions instead of accessing `buf[i]`:

    class IRsendRawPGM: public virtual IRsendBase {
      public:
        void send(const uint16_t *buf, uint8_t len, uint8_t khz) {
          enableIROut(khz);
          for (uint8_t i = 0; i < len; i++) {
            if (i & 1) {
              space(pgm_read_word_near(buf + i));
            }
            else {
              mark(pgm_read_word_near(buf + i));
            }
          }
          space(0); // Just to be sure
        }
    };

Now you can define your sender object as:

    IRsendRawPGM mySender;

And send the data directly:

    mySender.send(sources[0], RAW_DATA_LEN, 36);

(Note: this code is untested).


message:
Limitations of connecting to many Arduinos via Ethernet?

I'm planning a project where I need to control a lot of Arduino Unos from a single PC. I'll need to send commands to the Arduinos and receive responses, as well as have the ability to update each Arduino from the PC, preferably without Arduino IDE at some point. Connecting via USB is out of the question, as I have already tried this and got miserable results, in part because of the number of Arduinos I need to control. So now I'm considering connecting the PC to an ethernet switch and then from there connect each Arduino with an ethernet shield.

Which brings me to my questions. Are there any limitations I should be aware of, if I want to pursue this setup? Will controllings tens, or even a hundred, Arduinos at the same time be a problem? How about stuff like updating a specific Arduino on the network?

My current working prototype uses a Windows PC that connects to one of multiple Raspberry Pis, which then in turn communicates with a number of Arduinos via I2C, and updates them via USB. But if I'm able to do all this directly from the main PC to the Arduinos via Ethernet, that would be fantastic.

Thanks for reading, looking forward to any answers.

body:
With a lot of devices on the ethernet, you may want to consider a private wire that is dedicated to those devices.  That is, a second ethernet port or a VLAN off a capable switch.

As the number of devices increases, and the number of simultaneous talkers increases, you will start getting contention.  Chances are a modern switch can handle this to some extent, but you were not clear on how much traffic you are planning on sending, or how often each device talks, or if it is centrally coordinated (aka "polled") or just speaking whenever.


message:
ESP8266: Multiple analog inputs using software

Is there a way to get at least three analog inputs to the esp8266 (without a multiplexer)?

Each digital or analog pin on an Arduino can be configured as digital or "analog" (e.g., [PWM software][1]).

Here is a way to squeeze one additional analog input pin: [hackaday.io/project/8435-2-analog-inputs-for-esp8266-without-multiplexer][2]

Any ideas or software[?][3]

  [1]: https://github.com/Palatis/arduino-softpwm
  [2]: https://hackaday.io/project/8435-2-analog-inputs-for-esp8266-without-multiplexer
  [3]: https://www.esp8266.com/viewtopic.php?f=6&t=19521

body:
1) nope it's not possible "in a straightforward way". you should use analog muxes.

2) the statement "Each digital or analog pin on an Arduino can be configured as digital or "analog" (e.g., PWM software)." means for PWM or the so called "analog output". not intended the ADC unit.

3) the link provided uses software tricks to measure 2 signals in a muxed fashion. it's up to purpose.

workarounds :

1) use CD4066 CMOS bilateral switch. it works with analog signals.

2) use GPIOs to supply voltage to measurement units. like the link you provided. it works for passives like photoresistors and for devices like LM35 temp sensor. but can't be used for devices like 3 channels analog-out accelerometers.


message:
esp8266 advertising AP even when flashed with custom firmware

I bought several ESP8266 boards from an Amazon seller, and I have flashed them with custom firmware.  This firmware basically sends telemetry to an MQTT server, and has some OTA functionality to self-update from a web server I run.

I flashed them from the Arduino IDE initially, although have also since updated them OTA.

These devices properly connect to the AP I have defined, get an address, and send their mqtt messages.  However, they ALSO advertise an SSID that is `FaryLink_XXXXXX` where the XXXXXX relates to the MAC.

How is this possible, and how should I wipe their little brains fully?

body:
The Espressif ESP8266 SDK is part of every Arduino sketch for the ESP8266. The SDK handles the WiFi and other basic functions of the chip.

If enabled, the SDK remembers WiFi STA and SoftAP settings and start to connect right after boot. At default it is enabled. In Arduino sketch this is controlled by [`WiFi.persistent(bool)`][1] and of course this setting is stored too.

To clear SoftAP settings, call `WiFi.softAPdisconnect()`. To only turn off SoftAP, use `WiFi.setMode(WIFI_STA)`.

  [1]: https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/generic-class.html#persistent


message:
Brushed ESC won't move slowly

I'm trying to control the brushed motor in a Traxxas Slash RC car with the built-in XL5 ESC using the Servo library on Arduino. I previously had success controlling this car with a Pololu Micro Maestro, but it died on me, and so, while waiting for a replacement to arrive, I thought I'd give a more manual approach a try.

The problem is, the motor moves *way* too fast. My understanding is that, for this ESC (which allows for reverse driving), 90 degrees / 1500 ms should be the neutral point, with anything above this leading to progressively faster forward speed; and, below, reverse.
But, while it seems there is some speed modulation, the motor just abruptly begins with a very high speed at an angle (`Serial.write(95)`) of 95 or so, and then gets even faster from there.

A minimal version of my code is pasted below; my circuit has the signal pins of the steering and ESC servo connectors (white wires) attached to pins 2 and 9, respectively on a Pro Micro, their two 5V pins connected to each other (since the ESC supplies its own 5V), and their grounds connected to the Arduino's ground pins.

While it's possible that I need a special arming sequence to get this ESC to work properly (I do operate in the three-blink "training" mode, which is supposed to be slower), I would expect that problem to manifest as no motion at all, not too *much* motion.

I've tried powering the ESC with the original 9.1V battery (nominal 8.4V), and with a 8.4V regulated supply attached to a ~15V battery.

What could I be doing wrong here?

    #include <Servo.h>

    Servo throttle;

    void setup(){

        Serial.begin(115200);

        throttle.attach(9);
        // throttle.write(91);
        // delay(300);

        int first = 90;
        for(int angle=first; angle < first+20; angle++) {
            Serial.println(angle);
            throttle.write(angle);
            delay(10);
        }

        // This doesn't work any better.
        // int first = 1500;
        // for(int us=first; us < first+10; us++) {
        //     Serial.println(us);
        //     throttle.writeMicroseconds(us);
        //     delay(50);
        // }

        throttle.write(90);
    }

    void loop() {
    }

body:
Per @jsotola 's suggestion, I looked more closely at the [manual][1] (see the section "XK-5 Setup Programming"):

> XL-5 Setup Programming (Calibrating your ESC and transmitter)
>
> Read
> through all of the programming steps before you begin. If you get lost
> during programming or receive unexpected results, simply unplug the
> battery, wait a few seconds, plug the battery pack in, and start over.
>
> 1. Disconnect one of the motor wires between the XL-5 and the motor. This is a precaution to prevent runaway when the speed control is
> turned on before it is programmed.
>
> 2. Connect a fully charged battery pack to the XL-5.
>
> 3. Turn on the transmitter (with the throttle at neutral).
> 4. Press and hold the EZ-Set button (A). The LED will first turn green and then red. Release the button.
>
> 5. When the LED blinks RED ONCE, pull the throttle trigger to the full throttle position and hold it there (B).
>
> 6. When the LED blinks RED TWICE, push the throttle trigger to the full reverse and hold it there (C).
>
> 7. When the LED blinks GREEN ONCE, programming is complete. The LED will then shine green or red (depending on LowVoltage Detection
> setting), indicating the XL-5 is on and at neutral (D).

I wrote a short program to send specified servo angles in [0, 180] interactively. The manual says to apply "full throttle" and "full reverse", but I wasn't exactly sure what these translated to in terms of servo angle/pulse width milliseconds. I gather that these are often given as 45° and 135° (1.25 ms and 1.75 ms), respectively, but that setting the limits to [0, 180] during this training period also worked. It's valuable to get the full range, so I can get finer gradations in speed. Since I don't expect to ever reach full speed in my application, and will only use the near-90 part of the range, this will be particularly helpful.

I'm still perplexed about what caused the original problem--the Pololu servo controller never needed this tuning process. Perhaps the limits were set to [45, 135], and I mistakenly sent 180, which put the ESC into some state not described in the manual. And I don't know whether I'll need to repeat this in the future, or
whether my new [0, 180] limits will prevent the above mistake from being a problem. For that matter, I don't know how non-volatile the non-volatile memory is on the ESC in which these limits are stored. Does it require periodic battery power to refresh?

Finally, while it might be even more particular to the XL-5 ESC and my power supply setup, another useful note is that the low-voltage detection mode might prevent movement independent of the setup process.

  [1]: https://traxxas.com/sites/default/files/58024-OM-EN-R01.pdf


message:
Invoke a method in the main sketch from within a library

I need to use a specific library that issues error messages in the form of String texts. The library uses the `Serial.println()` function to send the messages to the Arduino IDE's serial monitor.

The problem is that I have the Serial lines from the Arduino linked to another device, therefore I can't use the Serial Monitor to see the messages. I have a method in the Main Arduino sketch that sends any String text msg generated to another device using Udp commands (wireless). This device is connected to a serial monitor unit.

My question is: How can I invoke the Udp method inside the main sketch of the Arduino program from within the aforementioned library? This would help me to convert the `Serial.print()` text messages from the library directly into Udp messages to be able to visualize them.

The Udp method I'm using is declared as `void UdpSend(String msg)` in the Arduino sketch. I'd like to use something similar inside the library to wrap the text msg and send it over to the method on the main program.

Any example or link to get this information will help.

EDIT1:

@Majenko,

 1. On the target library, added:  `void libUdpSend(const char *libMsg);`
 2. On the sketch, I added this method (Udp comm handler):

         void libUdpSend(const char *libMsg)
         {
           Udp.begin(localPort);
           Udp.beginPacket(Udp.remoteIP(), localPort);
           Udp.write(libMsg);
           Udp.endPacket();
           delay(40);
         }

 3. Added this line on the library (right after the declaration on 1.) to test through the remote serial interface:

        libUdpSend("String wrapper has been implemented SUCCESSFULLY!");

When trying to compile linking the library, the following exception occurrs:

> error: expected constructor, destructor, or type conversion before '(' token
> `libUdpSend("String wrapper has been implemented SUCCESSFULLY!");`

I then switched to String as this is the type I want to wrap, Same steps:

 1. On the target library, added:  `void libUdpSend(String *libMsg);`
 2. On the sketch:

        void libUdpSend(String *libMsg)
        {
          Udp.begin(localPort);
          Udp.beginPacket(Udp.remoteIP(), localPort);
          Udp.write(libMsg.c_str());
          Udp.endPacket();
          delay(40);
        }

Now the error message says:
>request for member 'c_str' in 'libMsg', which is of pointer type 'String*' (maybe you meant to use '->' ?)

I am not an expert on pointers so I'd need some help on how to assign the pointer as argument on the `UdpWrite` function using the '->' command proposed by the compliler?

Let me know your thoughts on this.

body:
The connection between a sketch and a library is not one-way as many suppose.  Things can go quite happily in both directions.

What you are proposing is something I do quite often when developing a library and I need to get some debugging information out of the library. Yes, it's possible to directly use `Serial` in the library, but that's something I don't like, and often isn't appropriate anyway, as in your situation.

However, doing it the way you propose (and I use) is actually very simple.

You just make your function in your sketch and tell the library to use it.

For example, in your sketch:

    void debug(const char *msg) {
        Serial3.println(msg);
    }

And in the library add the line:

    void debug(const char *msg);

Then at any point in the same file (or translation unit) you can use

    debug("I am here");

That is assuming that the file that you are using it in is a C++ file (`.cpp`).  If it's a C file (`.c`) then you have to treat things very slightly differently.  You see, C++ makes a mess of the function names (even vanilla functions like that) which means they can't be seen by C files.  So you have to tell the compiler "I'd like this to be usable in a C file, please".

Which you do with a special "extern" wrapper around your function:

    extern "C" {
        void debug(const char *msg) {
            Serial3.println(msg);
        }
    }

And then `debug()` is usable in a C file in the same way as above.

However now it won't work in a C++ file...  (round and round we go...)

Simple to fix: add the `extern "C"` to the prototype in the C++ file:

    extern "C" {
        void debug(const char *msg);
    }

If you want to include your "extern" in a header file that could be included into either C or C++ files it's very common to use a construct such as:

    #if defined(__cplusplus)
    extern "C" {
    #endif

    void debug(const char *msg);

    #if defined(__cplusplus)
    }
    #endif

That will add the `extern "C"` wrapper for C++ files (identified by the presence of the macro `__cplusplus`) but omit it for C files.

I have used "const char *" as the parameter for this example, but you can choose whatever parameters are appropriate for your usage.


message:
Linear Actuator Arduino Control

**Update:**

Here is my first try based on the code I found and it did not work.
The first time I uploaded it, it move to the "current positional value". But did not do the void loop part. Just holds the positions.

Thanks.

        //Includes
        #include <Servo.h>

        //Defines
        #define LINEAR_1_100PIN 11        //Linear Actuator Digital Pin
        #define LINEAR_2_100PIN 6      //Linear Actuator Digital Pin

        String msg;

        //max/min pulse values in microseconds for the linear actuators
        #define LINEAR_1_100_MIN      1050  //
        #define LINEAR_1_100_MAX      2000 //
        #define LINEAR_2_100_MIN  1050     //
        #define LINEAR_2_100_MAX  2000    //

        Servo LINEAR_1_100, LINEAR_2_100;  // create servo objects to control the linear actuators
        //int knobValue, sliderValue;  //variables to hold the last reading from the analog pins

        int linear100Value_1 = 1051;   //current positional value being sent to the linear actuator.
        int linear100Value_2 = 1051;  //current positional value being sent to the linear actuator.

        int speed = 10;

        void setup()
        {
          //initialize servos
          LINEAR_1_100.attach(LINEAR_1_100PIN, LINEAR_1_100_MIN, LINEAR_1_100_MAX);      // attaches/activates the linear actuator as a servo object
          LINEAR_2_100.attach(LINEAR_2_100PIN, LINEAR_2_100_MIN, LINEAR_2_100_MAX);  // attaches/activates the linear actuator as a servo object

          //Analog pins do not need to be initialized

          //use the writeMicroseconds to set the linear actuators to their default positions
          LINEAR_1_100.writeMicroseconds(linear100Value_1);
          LINEAR_2_100.writeMicroseconds(linear100Value_2);
        }

        void loop()
        {
       LINEAR_1_100.write(90);
       delay(1000);
       LINEAR_1_100.write(0);
       delay(1000);
       LINEAR_2_100.write(90);
       delay(1000);
       LINEAR_2_100.write(0);
       delay(1000);
        }

**Old Question:**

I am trying to make the code described in this tutorial:

http://learn.robotgeek.com/demo-code/118-arduino-linear-actuator-tutorial-analog-direct-control-of-small-linear-actuator.html

https://github.com/robotgeek/firgelliDirectControl/blob/master/firgelliDirectControl/firgelliDirectControl.ino

work with PWM from an Arduino, without the additional board.

So far the Arduino Examples>Servo>Sweep works as I would like to achieve it (delay changed to 30 ms) but very slowly and it does not seem to just go 180 steps out wait 30 ms and 180 steps in again. It sometimes moves twice in one direction. If I change the steps from 1 to 5 the servo does not move anymore (I expected it to go faster).

With the code above I understand I can control the servo with a Knob or Slider, but I would like to understand how I can control this Linear Actuator Servo with PWM from an Arduino PMW Pin (e.g. 11) and change the speed. Finally I would like to make the Servo consistently go x amount of steps out, wait for x ms and the same amount back in again.

Most importantly I would like to make sure it always ends at position 0, and that it does not accumulate errors.

Thank you for any help.

body:
About being sure about returning to position 0 this is not a problem. You are not actually controlling anything with your PWM. You are only sending a signal to the IC inside the servo to tell it where to move the actuator. That IC knows in what position the actuator is located in any moment, usually using some kind of encoder (it's called a closed loop system) and it will make sure that it will move back exactly to `0` whenever you tell it to move to `0`.

If you want to make things clearer you can use `write` method to send value to the servo.

    void Servo::write(int value)
    {
      if(value < MIN_PULSE_WIDTH)
      {  // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
        if(value < 0) value = 0;
        if(value > 180) value = 180;
        value = map(value, 0, 180, SERVO_MIN(),  SERVO_MAX());
      }
      this->writeMicroseconds(value);
    }

Any value from `0` to `180` will set a position to which servo will move from MIN to MAX possible position. No need for manual calculation of microseconds.

You have to remember that PWM works constantly. If you write for example `LINEAR_1_100.writeMicroseconds(1051)` this code will set some timers, counters and prescalers inside the ATmega chip on the Arduino board and the value of PWM will be sent constantly until you change it.

So the `delay(2000)` doesn't stop the PWM signal, and servo remains in constant position.

The issue is here:

    LINEAR_1_100.writeMicroseconds(1800);
    LINEAR_1_100.writeMicroseconds(1051);

You set the value of `1800` and then immediatelly set value of `1051`, but the ATmega didn't even have the time to send the first value to the servo.
Add a `delay(1000)` after every call of `write` or `writeMicroseconds` to allow the PWM to actually be sent to the servo.


message:
How to sample incoming 600khz pin and divide it by 4 and generate low frequency signal at output pin of arduino

I am trying to divide a incoming high frequency signal 600kHz by 4 and output wave at arduino MEGA2560 digital pin.

 - The input to arduino comes from incremental Encoder which is connected to motor that runs at 9000 rpm and the generates 1024 pulses per rotation.
 - I am trying to downsample the frequency I am getting from arduino to 250kHz or less.
 - I tried following approaches :

   a. I counted the rising edge of the incoming wave and a interrupt is triggered as number of rising edge reaches certain value and ISR toggle an output pin.
   b. I tried to get hardware counter work at T0 pin but I was not able to hit ISR when the count has reached specific value.

The problem with approach 1 is: As my frequency of incoming wave increases the output wave starts missing some pulses and generates one half cycle for 6/8/10 pulses of incoming wave. It should actually generate one half cycle for 4 pulses.

**Here is approach 2 code:**

    #define outPin1 10
    volatile short encoder = 4;

    void setup ()
    {
       pinMode (outPin1, OUTPUT);
       Serial.begin(9600);
       cli();
       // reset Timer 0
       TCCR0A = 0;
       TCCR0B = 0;

     }  // end of setup

     ISR(TIMER0_COMPA_vect)
     {
         digitalWrite(outPin1, !digitalRead(outPin1));

     }

     void loop ()
     {
        TCNT0 = 0;      //counter to zero

        // set compare match register to desired timer count:
       OCR0A = encoder;
        // turn on CTC mode:

       bitSet(TCCR0A, WGM01);
       // Timer 0 - counts events on pin D4

      bitSet(TIMSK0, OCIE0A);    // interrupt on Timer 0 CTC
       // start Timer 0
      // External clock source on T0 pin (D4). Clock on rising edge.

       bitSet(TCCR0B, CS02);
       bitSet(TCCR0B, CS01);
       bitSet(TCCR0B, CS00);
    }

**Please someone help me out with this issue**

body:
This is probably too fast to have have software involved in the loop.
You should try to use a hardware-only solution. Note the Arduino timers
should be usable as hardware frequency dividers:

* configure a timer to be clocked off the input signal, so that it
  behaves like a counter.
* configure it for delivering a PWM output with a period of 4 timer
  clock cycles and a duty cycle of 50%.

You may try this, but beware I have not tested it:

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

    void setup()
    {
        // Configure Timer 5 as a frequency divider:
        //   input: digital pin 47 = PL2 = T5
        //   ouput: digital pin 46 = PL3 = OC5A
        DDRL  |= _BV(PL3);    // set pin PL3 as output
        TCCR5A = 0;           // undo the Arduino core's configuration
        TCCR5B = 0;
        ICR5   = 4 - 1;       // period = 4 timer clock cycles
        OCR5A  = 2 - 1;       // output HIGH for 2 timer clock cycles
        TCCR5A = _BV(COM5A1)  // non-inverting PWM on pin OC5A
               | _BV(WGM51);  // mode 14: fast PWM, TOP = ICR5
        TCCR5B = _BV(WGM52)
               | _BV(WGM53)
               | _BV(CS50)    // clock on rising edges of T5
               | _BV(CS51)
               | _BV(CS52);
    }

    void loop(){}


body:
I am writing another answer because what I propose here is radically
different from the previous answer. In that answer I wrote that this is
too fast for being done in software, and here I am going to contradict
myself. :-/

At 600 kHz, the input stays low for roughly 13 CPU cycles,
then high for another 13 cycles. You cannot do much in 13 cycles.
Notably, the prologue of an ISR can quite often take more than this.
Also, whenever the Timer 0 overflow ISR from the Arduino core fires, it
can delay your own ISR for way more than 13 cycles. That's why it
is usually illusory to expect any job to be reliably done in this time
frame. Especially if interrupts are involved.

That being said, if the CPU has _absolutely nothing else_ to do. And
specifically if it is never interrupted, Then it can keep up with that
pace. Here is a program that should do what you expect. I initially
thought about writing it in assembly, but it can also be written in C,
as the compiler translates it in a quite straightforward way. If in
doubt, however, check the generated assembly:

<!-- language: c -->

    /*
     * From one square wave generate two waves in quadrature at 1/4 of the
     * original frequency.
     *
     * https://arduino.stackexchange.com/questions/63202
     *                               _   _   _   _   _   _
     *  input:  digital 13 = PB7    / \_/ \_/ \_/ \_/ \_/ \_/
     *                               _______         _______
     *  output: digital 10 = PB4    /       \_______/       \
     *                                   _______         ____
     *  output: digital 11 = PB5    ____/       \_______/
     */

    int main(void)
    {
        DDRB = _BV(PB4) | _BV(PB5);  // PB4 and PB5 as outputs
        for (;;) {
            loop_until_bit_is_clear(PINB, PB7);  // wait for rising input
            loop_until_bit_is_set(PINB, PB7);
            PORTB |= _BV(PB4);                   // rise PB4
            loop_until_bit_is_clear(PINB, PB7);  // wait for rising input
            loop_until_bit_is_set(PINB, PB7);
            PORTB |= _BV(PB5);                   // rise PB5
            loop_until_bit_is_clear(PINB, PB7);  // wait for rising input
            loop_until_bit_is_set(PINB, PB7);
            PORTB &= ~_BV(PB4);                  // fall PB4
            loop_until_bit_is_clear(PINB, PB7);  // wait for rising input
            loop_until_bit_is_set(PINB, PB7);
            PORTB &= ~_BV(PB5);                  // fall PB5
        }
    }

Note that, since this is not using the Arduino core, I wrote `main()`
rather than `setup()` and `loop()`. This overrides the `main()` provided
by the core, thus you don't have the initializations that come with it
and, in particular, you don't have the Timer 0 interrupt.


message:
Sending GPS data through a WiFi module

I'm trying to send GPS data using a neo-6m GPS module through WiFi using esp8266 module, I have both of the modules working alone, but when I try using both the WiFi works but won't send the data from the GPS.

I call the GPS and save the latitude, longitude, date and time to separate variables, then try sending those variables using the WiFi to the server on the Arduino Uno, but they just show up as 0's.

    #include <TinyGPS++.h>
    #include "WiFiEsp.h"

    // Emulate Serial1 on pins 6/7 if not present
    #ifndef HAVE_HWSERIAL1
    #include "SoftwareSerial.h"
    SoftwareSerial Serial1(6, 7); // RX, TX
    #endif

    char ssid[] = "UPC9080883";            // your network SSID (name)
    char pass[] = "OYKXVYND";        // your network password
    int status = WL_IDLE_STATUS;

    int ledStatus = LOW;

    WiFiEspServer server(80);

    // use a ring buffer to increase speed and reduce memory allocation
    RingBuffer buf(8);

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

    // The TinyGPS++ object
    TinyGPSPlus gps;

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

    double  latitude, longitude;
    int days, months, years, hr, mins, secs;
    void setup()
    {
      pinMode(LED_BUILTIN, OUTPUT);  // initialize digital pin LED_BUILTIN as an output.
      Serial.begin(115200);   // initialize serial for debugging
      Serial1.begin(9600);    // initialize serial for ESP module
      WiFi.init(&Serial1);    // initialize ESP module

      // check for the presence of the shield
      if (WiFi.status() == WL_NO_SHIELD) {
        Serial.println("WiFi shield not present");
        // don't continue
        while (true);
      }

      // attempt to connect to WiFi network
      while (status != WL_CONNECTED) {
        Serial.print("Attempting to connect to WPA SSID: ");
        Serial.println(ssid);
        // Connect to WPA/WPA2 network
        status = WiFi.begin(ssid, pass);
      }

      Serial.println("You're connected to the network");
      printWifiStatus();

      // start the web server on port 80
      server.begin();
    }

    void loop()
    {
      Serial1.end();
      Serial2.begin(GPSBaud);
      GPS();
      Serial2.end();
      Serial1.begin(9600);
      WiFiEspClient client = server.available();  // listen for incoming clients
      if (client) {                               // if you get a client,
        Serial.println("New client");             // print a message out the serial port
        buf.init();                               // initialize the circular buffer
        while (client.connected()) {              // loop while the client's connected
          if (client.available()) {               // if there's bytes to read from the client,
            char c = client.read();               // read a byte, then
            buf.push(c);                          // push it to the ring buffer

            // printing the stream to the serial monitor will slow down
            // the receiving of data from the ESP filling the serial buffer
            //Serial.write(c);

            // you got two newline characters in a row
            // that's the end of the HTTP request, so send a response
            if (buf.endsWith("\r\n\r\n"))
            {
              sendHttpResponse(client);
              break;
            }
          }
        }

        // close the connection
        client.stop();
        Serial.println("Client disconnected");
      }
    }
    void GPS() {
      while (Serial2.available() > 0) {
        gps.encode(Serial2.read());
        if (gps.location.isUpdated()) {
          // Latitude in degrees (double)
          latitude = (gps.location.lat(), 6);
          // Longitude in degrees (double)
          longitude = (gps.location.lng(), 6);

          // Day (1-31) (u8)
          days = (gps.date.day());
          // Month (1-12) (u8)
          months = (gps.date.month());
          // Year (2000+) (u16)
          years = (gps.date.year());

          // Hour (0-23) (u8)
          hr = (gps.time.hour());
          // Minute (0-59) (u8)
          mins = (gps.time.minute());
          // Second (0-59) (u8)
          secs = (gps.time.second());
          Serial.println(longitude);
          Serial.println(latitude);
          Serial.println(days);
          Serial.println(months);
          Serial.println(years);
          Serial.println(hr);
          Serial.println(mins);
          Serial.println(secs);

        }
      }
    }

    void sendHttpResponse(WiFiEspClient client)
    {
      // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
      // and a content-type so the client knows what's coming, then a blank line:
      client.println("HTTP/1.1 200 OK");
      client.println("Content-type:text/html");
      client.println();

      // the content of the HTTP response follows the header:
      client.println("
");
      client.println("
");
      client.print("Latitude= ");
      client.print(latitude);
      client.print(" Longitude = ");
      client.println(longitude);
      client.println("
");
      client.print("Date: ");
      client.print(days);
      client.print("/");
      client.print(months);
      client.print("/");
      client.print(years);
      client.println("
");
      client.print("Time: ");
      client.print(hr);
      client.print(":");
      client.print(mins);
      client.print(":");
      client.print(secs);
      // The HTTP response ends with another blank line:
      client.println();
    }

    void printWifiStatus()
    {
      // print the SSID of the network you're attached to
      Serial.print("SSID: ");
      Serial.println(WiFi.SSID());

      // print your WiFi shield's IP address
      IPAddress ip = WiFi.localIP();
      Serial.print("IP Address: ");
      Serial.println(ip);

      // print where to go in the browser
      Serial.println();
      Serial.print("To see this page in action, open a browser to http://");
      Serial.println(ip);
      Serial.println();
    }

body:
SoftwareSerial can't listen on two instances. There is a `.listen()` function to switch between SoftwareSerial instances.

The esp8266 AT firmware doesn't wait until you listen on the SoftwareSerial instance. If there is a connection to the server it sends +IPD and data. If the SoftwareSerial instance doesn't listen the information about client connection is lost.

You must listen to esp8266 all the time, so you can't use two SoftwareSerial instances.

You could use the RX pin of Uno to receive data from GPS module over hardware Serial.


message:
I am building an robotic arm by using flex sensor, servo and 2 xbees

Rx Code:

    #include <Servo.h>
    Servo myServo;

    void setup() {
    Serial.begin(9600);
    myServo.attach(9);
    delay(5000);
    myServo.write(0);
    }

    void loop() {
      while(Serial.available()==0);

        int d = Serial.read() - '0';
        if(d>0)
        {
          int pos = map(d,0,9,0,180);
          pos = constrain(pos,0,180);
          myServo.write(pos);
          Serial.println(d);

          delay(50);
          }
          else
          {};

    }

Tx code:

    int sensorValue = 0;         // the sensor value
    int sensorMin = 1023;        // minimum sensor value
    int sensorMax = 0;           // maximum sensor value
    int SensorMid = 0;
    const int POWER_OF_TWO_TO_AVERAGE = 6;

    void setup() {
    pinMode(13,OUTPUT);
      Serial.begin(9600);

      while (millis() < 10000) {
        digitalWrite(13,HIGH);
        sensorValue = analogRead(A1);
        if (sensorValue > sensorMax) {
          sensorMax = sensorValue;
        }
        if (sensorValue < sensorMin) {
          sensorMin = sensorValue;
        }
      }
      SensorMid = (sensorMin + sensorMax )/2;
      digitalWrite(13,LOW);
      }

    void loop() {
    int val = map(analogRead(A1),SensorMid,sensorMax,0,9);
    Serial.println(val);
    delay(100);
    }

I am building a robotic arm and I am facing some problems regrading to the servos stability with the flex, I am using the flex as the transmitter and the servo as the receiver, and when I press my finger my servo doesn't move properly.

Any suggestions?

body:
Without knowing more about the actual problem of "doesn't move properly", what I initially see is that you are transmitting values 0-9 by using `Serial.println()`, which sends the byte data, and also a newline (ASCII value `10`), so your RX code is probably getting alternating input of the intended value, and the value `10`, which is getting subtracted from `48` (the ASCII value of `'0'`), `map`ped and `constrain`ed to `0`.

Try changing your TX script to call `Serial.print()` instead. Your receiver doesn't care about each value showing up on a new line -- it doesn't know about lines.


message:
What Version of the Sketch did I leave on there?

Is there a way to "ask" the Arduino what sketch was compiled on it?

There are several versions of the sketch and I need to see which version the Arduino has been running.

body:
First, you have to store the desired information in your sketch.

    #define VERSION F("0.01 4-Apr-2019")

    void setup() {
       Serial.begin(9600);
       Serial.print(F("Test Sketch V"));
       Serial.println(VERSION);
    }

    void loop() {
    }

Of course any other way might work as well:

- Only print it, if at reset a test button is pressed

- Check for a Serial command and respond the version info.

- Don't print it, but use avrdude and a programmer to read the FLASH memory and search it for the version string. (Similar to jot's comment above)


body:
If you have not set the flash protection bits you can read back the contents of the program memory. See https://www.evilmadscientist.com/2011/avr-basics-reading-and-writing-flash-contents/

By reading back the first pages you can then compare with the different versions of the sketch (hex file) and determine which version is on the device. The first pages are the different ISR vectors and should be unique for the sketches.

Cheers!


message:
Push and hold on/off switch for arduino

Many electronic devices turn on/off, or more correctly on/sleep, by pressing a button and holding it for two or three seconds. I would like to put this ability into a project using an Adafruit Feather board.  The sleep side is easy, I can detect a level and if it stays there for some time, run the code to put the processor to sleep.  My question involves the wake up side. The chip wakes up via an interrupt.

The question then becomes, how do I generate the interrupt source only after the button has been held for the designated time? I've considered two options:

1) Use a level interrupt and an RC circuit to do the delay.
2) Have the processor wake up immediately and then implement logic to determine if it has been held "long enough" and go back to sleep if not.

Am I missing an easy option? Is there a general consensus on the best way to do this? It seems like such a normal thing that I'm surprised my searches haven't turned up any tutorials.

body:
I would go for option 2.

You can wake up the controller immediately, but only the processor.

Then just start waiting for the "long enough" time that you defined, regulary checking the button state. If the button is still pushed, then initiate full wake up. If it is released, go back to sleep.

This is the easy option, requiring no extra hardware, and only a dozen of so of lines of code.

Another option, that exist and have a somewhat similar behaviour, is to have your processor wake up regulary on timer, and checking the state of the input. This is what is done for "radio controled" devices, for example (Where the "button" is a radio circuit that need to be switch on and off).
Given a sufficiently long sleep between check, on average you will get the "long enough" delay.

This option is useful when you don't have available interrupt pins, or you need something more complex that a button as the input.


message:
Remove gravity from accelerometer of MPU-6050

I am currently working with MPU-6050. Now I want to minus gravity from my accelerometer's value as we minus the offset.

Here is the code:

    #include <Wire.h>
    #include <MPU6050.h>
    //read as rool:pitch:yaw:accX:accY:accZ
    MPU6050 mpu;
    unsigned long timer = 0;
    float timeStep = 0.01;
    float pitch = 0;
    float roll = 0;
    float yaw = 0;
    float accX = 0;
    float accY = 0;
    float accZ = 0;
    float rollRad = 0;
    float pitchRad = 0;
    float yawRad = 0;

    int count = 0;

    Vector minusGravity(Vector vec)
    {
        /*
         float x = vec.XAxis, y = vec.YAxis, z = vec.ZAxis;
         vec.XAxis -= x * cos(yawRad) - y * sin(yawRad) + x * cos(pitchRad) + z
               * sin(pitchRad) + 0;
         vec.YAxis -= x * sin(yawRad) - y * cos(yawRad) + 0 + y * cos(rollRad) -
               z * sin(rollRad);
         vec.ZAxis -= 0 - x * sin(pitchRad) + z * cos(pitchRad) + y *
               sin(rollRad) + z * cos(rollRad);
        */

        return vec;
    }

    float accP(float value)
    {
        int x = (int)(value * 10);
        return ((float)(x)) / 10;
    }

    void setup()
    {
        Serial.begin(115200);
        while (!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
        {

        }
        //mpu.calibrateGyro();
        mpu.setThreshold(1);
     }

     void loop()
     {
        timer = millis();
        Vector norm = mpu.readNormalizeGyro();
        pitch = pitch + norm.YAxis * timeStep;
        roll = roll + norm.XAxis * timeStep;
        yaw = yaw + norm.ZAxis * timeStep;
        Vector normAccel = minusGravity(mpu.readNormalizeAccel());
        rollRad = roll * 0.0174533;
        pitchRad = pitch * 0.0174533;
        yawRad = yaw * 0.0174533;

        Serial.print(roll);
        Serial.print(":");
        Serial.print(pitch);
        Serial.print(":");
        Serial.print(yaw);
        Serial.print(":");
        accX = accP(normAccel.XAxis);
        accY = accP(normAccel.YAxis);
        accZ = accP(normAccel.ZAxis);
        Serial.print(accX);
        Serial.print(":");
        Serial.print(accY);
        Serial.print(":");
        Serial.println(accZ);
        delay((timeStep * 2500) - (millis() - timer));
    }

I understand the problem is here :

    vec.XAxis -= x * cos(yawRad) - y * sin(yawRad) + x * cos(pitchRad) + z
               * sin(pitchRad) + 0;
         vec.YAxis -= x * sin(yawRad) - y * cos(yawRad) + 0 + y * cos(rollRad) -
               z * sin(rollRad);
         vec.ZAxis -= 0 - x * sin(pitchRad) + z * cos(pitchRad) + y *
               sin(rollRad) + z * cos(rollRad);

New code :

          #include <Wire.h>
      #include <MPU6050.h>
      //read as rool:pitch:yaw:accX:accY:accZ
      MPU6050 mpu;
      unsigned long timer = 0;
      float timeStep = 0.01;
      float pitch = 0;
      float roll = 0;
      float yaw = 0;
      float accX = 0;
      float accY = 0;
      float accZ = 0;
      float rollRad = 0;
      float pitchRad = 0;
      float yawRad = 0;
      float gX = 0;
      float gY = 0;
      float gZ = -9.8;

      int count = 0;

      Vector minusGravity(Vector vec)
      {

        float x = gX, y = gY, z = gZ;
        vec.XAxis -= x * cos(yawRad) - y * sin(yawRad) ;
        vec.YAxis -= x * sin(yawRad) - y * cos(yawRad) ;

        x = vec.XAxis; z = vec.ZAxis;
        vec.XAxis -=  x * cos(pitchRad) + z * sin(pitchRad) ;
        vec.ZAxis -= - x * sin(pitchRad) + z * cos(pitchRad) ;

        y = vec.YAxis, z = vec.ZAxis;
        vec.YAxis -=  y * cos(rollRad) - z * sin(rollRad);
        vec.ZAxis -=  y * sin(rollRad) + z * cos(rollRad);

        return vec;
      }

      float accP(float value)
      {
        int x = (int)(value * 10);
        return ((float)(x)) / 10;
      }

      void setup()
      {
        Serial.begin(115200);
        while (!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
        {

        }
        //mpu.calibrateGyro();
        mpu.setThreshold(1);
        Vector normAccel = mpu.readNormalizeAccel();
        gX = normAccel.XAxis;
        gY = normAccel.YAxis;
        gZ = normAccel.ZAxis;
      }
      void loop()
      {
        timer = millis();
        Vector norm = mpu.readNormalizeGyro();
        pitch +=  norm.YAxis * timeStep;
        roll += norm.XAxis * timeStep;
        yaw += norm.ZAxis * timeStep;
        Vector normAccel = minusGravity(mpu.readNormalizeAccel());
        rollRad = roll * 0.0174533;
        pitchRad = pitch * 0.0174533;
        yawRad = yaw * 0.0174533;
        Serial.print(roll );
        Serial.print(":");
        Serial.print(pitch );
        Serial.print(":");
          Serial.print(yaw );
        Serial.print(":");
        accX = accP(normAccel.XAxis);
        accY = accP(normAccel.YAxis);
        accZ = accP(normAccel.ZAxis);
        Serial.print(accX);
        Serial.print(":");
        Serial.print(accY);
        Serial.print(":");
        Serial.println(accZ);
        delay((timeStep * 2500) - (millis() - timer));
      }
It is little buggy.

Can anyone help me figure out what is my mistake ?

body:
I may have come to a solution :

    Vector minusGravity(Vector vec)
    {

     float x = vec.XAxis, y = vec.YAxis, z = 0;
     vec.XAxis -= x * cos(yawRad) - y * sin(yawRad) ;
     vec.YAxis -= x * sin(yawRad) - y * cos(yawRad) ;

     x = vec.XAxis; z = vec.ZAxis;
     vec.XAxis -=  x * cos(pitchRad) + z * sin(pitchRad) ;
     vec.ZAxis -= - x * sin(pitchRad) + z * cos(pitchRad) ;

     y = vec.YAxis, z = vec.ZAxis;
     vec.YAxis -=  y * cos(rollRad) - z * sin(rollRad);
     vec.ZAxis -=  y * sin(rollRad) + z * cos(rollRad);

     return vec;
    }

Now this is far better, as after calculating effect of `roll,pitch,yaw` in every step the  `x,y,z` changes. I missed that part. I was calculating directly, so it was giving me wrong value.

`vec.XAxis -= x * cos(yawRad) - y * sin(yawRad) `

then, `vec.XAxis -=  x * cos(pitchRad) + z * sin(pitchRad) `
 doesn't give the same result as the wrong one `vec.XAxis -= x * cos(yawRad) - y * sin(yawRad) + x * cos(pitchRad) + z
           * sin(pitchRad) + 0;`


message:
Arduino freezes while running code

I am frustrated with my arduino project can you help me?
I am using Arduino Uno, electric lock (high/low), 4 distance sonic modules. Basically I have 4 drawers, I am measuring the distance - how much are they opened and if they are opened in given limits, I set the electric lock open (high).

It is working, but after some while, it stops and it stops running.
I have tried to comment all serial communication - didn't help. I have tried to use proper variable data types - same. I have tried to buy much powerful power source - 12V 3,5A and I bought Electrolyte condenzator 4,7mF to balance the power peaks while the lock closes - didn't help.

The lock is turned on using relay, connecting it directly to power source 12V.
Relay is powered from 5V arduino supply and controlled by arduino Digital pin.
4 Sonic distance modules are powered from arduino power supply.

Its even more funny that it starts running after ~10 minutes from nothing. Im confused.

Code:

        // defines pins numbers
    const int trigPin1 = 2;
    const int echoPin1 = 3;
    const int trigPin2 = 6;
    const int echoPin2 = 5;
    const int trigPin3 = 9;
    const int echoPin3 = 8;
    const int trigPin4 = 12;
    const int echoPin4 = 11;
    const int relayPin = 7;
    //distance limits
    const int minSuplik4=27;//suplik4
    const int maxSuplik4=29;
    const int minSuplik3=22;//suplik3
    const int maxSuplik3=24;
    const int minSuplik2=32;//suplik2
    const int maxSuplik2=34;
    const int minSuplik1=9;//suplik1
    const int maxSuplik1=11;
    /*
    double PreDistance1[4]={0,0,0,0};//supliky
    double PreDistance2[4]={0,0,0,0};//supliky
    double PreDistance3[4]={0,0,0,0};//supliky
    */
    long distance[4]={0,0,0,0};//array with distances
    int i;
    int x;

    int trigPinX[4]={trigPin1,trigPin2,trigPin3,trigPin4};//supliky
    int echoPinX[4]={echoPin1,echoPin2,echoPin3,echoPin4};//supliky
    int maxD[4]={maxSuplik1,maxSuplik2,maxSuplik3,maxSuplik4};//supliky
    int minD[4]={minSuplik1,minSuplik2,minSuplik3,minSuplik4};//supliky
    void setup() {
    pinMode(relayPin, OUTPUT);
    pinMode(trigPin1, OUTPUT); // Sets the trigPin as an Output
    pinMode(echoPin1, INPUT); // Sets the echoPin as an Input
    pinMode(trigPin2, OUTPUT); // Sets the trigPin as an Output
    pinMode(echoPin2, INPUT); // Sets the echoPin as an Input
    pinMode(trigPin3, OUTPUT); // Sets the trigPin as an Output
    pinMode(echoPin3, INPUT); // Sets the echoPin as an Input
    pinMode(trigPin4, OUTPUT); // Sets the trigPin as an Output
    pinMode(echoPin4, INPUT); // Sets the echoPin as an Input
    digitalWrite(relayPin, LOW);
    Serial.begin(9600); // Starts the serial communication
    }
    void loop() {

    for (int i=0; i<4; i++)
    {
      delay(5);
      distance[i]=DistanceFunction(trigPinX[i],echoPinX[i]);
      delay(20);
      /*********** DEBUG ************
      Serial.print("Distance");// Prints the distance on the Serial Monitor
      Serial.print(i+1);
      Serial.print(":");
      Serial.print(distance[i]);
      Serial.print("<");
      Serial.print(minD[i]);
      Serial.print(":");
      Serial.print(maxD[i]);
      Serial.print(">");
      Serial.print(";");
      *********************************/
    }

    if(distance[0]>=minD[0] && distance[0]<=maxD[0] && distance[1]>=minD[1] && distance[1]<=maxD[1] && distance[2]>=minD[2] && distance[2]<=maxD[2] && distance[3]>=minD[3] && distance[3]<=maxD[3])
          {
            OpenFcn();
          }
    else
          {
            CloseFcn();
          }
    delay(100);
    }

    int DistanceFunction(int trigPin, int echoPin)
    {
      digitalWrite(trigPin, LOW);// Clears the trigPin
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);// Sets the trigPin on HIGH state for 10 micro seconds
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      long duration = pulseIn(echoPin, HIGH);// Reads the echoPin, returns the sound wave travel time in microseconds
      long distanceFcn= duration*0.034/2;// Calculating the distance
      return distanceFcn;
    }

    int OpenFcn()
    {
      digitalWrite(relayPin, HIGH);
      //Serial.println("OPENED");
      for (int x=5; x>0; x--)
        {
          //Serial.println("Otevreno:");
          //Serial.println(x);
          delay(1000);
        }
    }

    int CloseFcn()
    {
      digitalWrite(relayPin, LOW);
      //Serial.println("CLOSED");
    }

[![This is the moment when it start working crazy][1]][1]

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

body:
It looks like that there was a problem in the relay module or power supply cord. I have changed these two HW elements and looks like it is working. The reason why it did malfuctioning the arduino was, that when i moved the drawer, it slightly moved the power cord which had bad connection, so it made voltage drop on arduino supply and started to do crazy things.
Thanks all for your time


message:
NRF24L01 Networking

We checked Xbee, ZigBee and other alternatives already and we're trying to figure out a way for good and cheap network system. NRF24l01 looks good but 32 bytes not enough actually. Even so looks like we'll use it but some questions;

Questions' scenario contains 1 master and 300 slave devices with NRF24l01. We're thinking about making a addressing system like computer networks and every message will contain device id or device group tag. Master will be at the center of the room. Room do not have any inner wall or obstacle. Maximum range is less than 100m².

1) May messages get corrupt or latency ?
2) Is there any prepared library for Arduino for this kind of communication ?
3) Do you think is there any better solution for this kind of master & slaves networking logic (*must be cheap and stable*) ?

body:
> 1) May messages get corrupt or latency ?

For uni-directional Master to One Slave, no, there should be no corruption (at least not caused by there being lots of slaves present). For bi-directional Master to Multiple Slaves at the same time, yes, you're going to run into problems when the slaves try and reply. Keeping your protocol really simple will be beneficial.

> 2) Is there any prepared library for Arduino for this kind of communication ?

There's nothing special about what you propose. The RF24.h library will probably do the job (though I have never used it, so don't ask me how to use it).

> 3) Do you think is there any better solution for this kind of master & slaves networking logic (must be cheap and stable) ?

They're all a bit of a muchness really. RF communication is RF communication. It's how you use it that matters.

The nRF24L01+ has a number of benefits that mean you can do some things in hardware:

* Multiple receive pipes, each with their own address - so you can have one for the device address, one for a group address, and one for a global "broadcast" address
* Auto-acknowledge and re-sending of failed packets for more reliable communication (only for one-to-one communication)
* Automatic packetisation so you don't have to worry about crafting a low-level protocol of your own
* Direct communication giving low-latency
* Power Amplifier option for greater range.

You could use WiFi, however that would struggle with so many devices (most home access points and routers can't handle more than a few dozen devices), plus it adds extra latency that it sounds like you don't want.

The nRF24L01+ is probably a good choice for this kind of communication - however, be cautious with cheap clone devices: some of them have a silicon error that causes them to not be compatible with other nRF24L01+ devices.


message:
Can't store RFID data in the next 5 bytes of array

I'm working on RFID project to handle multiple cards.

I did most of the things OK. But now I have one problem. Which is the following:

1. The RFID code is 5 bytes, so I need an array of 5 bytes. If more cards then the array size = number of card * 5.
2. For my example I'm working with 2 cards. So array size is 10 bytes.
3. I can store the first card in the first 5 bytes.

The problem:
I can't store the 2nd card in the next 5 bytes in the array. I don't know why.

This is my only test code:

    /****************************** LIBRARIES ******************************/
    #include <SPI.h>
    #include <RFID.h>

    /****************************** DEFINITIONS ******************************/
    // pins definitions
    #define SS_PIN          10
    #define RST_PIN         9

    // setup definitions
    #define CARDS           2
    #define MXCD            CARDS*5

    /****************************** VARIABLES ******************************/
    // rfid variables:
    byte crd_buf[MXCD],card_no;
    byte register_lock,check_lock,print_lock;

    /****************************** FUNCTIONES ******************************/
    // rfid functions
    void register_accepted_card(void);
    void record_new_cards(void);
    void check_card(void);
    void print_registered_cards(void);

    // objects
    RFID rfid(SS_PIN, RST_PIN);

    //////////////////////////////////////////////////////////////////////
    void setup(){
      Serial.begin(9600);
      SPI.begin();
      rfid.init();
    }

    void loop(){
        register_accepted_card(); // apply only once
    }

    void register_accepted_card(void){
      if (!register_lock) {
        if (rfid.isCard()) {
          if(rfid.readCardSerial()){
            if(card_no>0){
              for(byte i = 0; i<card_no; i++){
                if(!memcmp((crd_buf+(i*5)),rfid.serNum,5)){

                  Serial.println("already card is");
                  for(byte p = i*5; p<(i*5)+5; p++){
                    Serial.print(crd_buf[p],HEX);Serial.print(", ");}
                    Serial.println();

                  lcd_state = ALREADY_MSG;
                  register_lock = 1;
                }
              }
            }

            //////////////////////////
            // problem is in this part
            //////////////////////////

            if(!register_lock){

              for(byte i=card_no*5;i<(card_no*5)+5;i++){
                crd_buf[i] = rfid.serNum[i];}

              Serial.print("loop#"); Serial.println(card_no);
              Serial.print("start index ");Serial.println(card_no*5);
              Serial.print("end index ");Serial.println((card_no*5)+5);
              Serial.println();

              Serial.print("card#"); Serial.println(card_no+1);
              for(byte i=card_no*5;i<(card_no*5)+5;i++){
                Serial.print(crd_buf[i],HEX);Serial.print(", ");}
              Serial.println();Serial.println("//////////////////////////");

              card_no++;
              if(card_no >= CARDS){lcd_state = FINISH_MSG;}
              else{lcd_state = REGISTER_MSG;}
              register_lock = 1;
            }
          }
        }
        rfid.halt();
      }
    }

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

My second question, for the part of checking the cards after finishing registering the cards to be accepted.

I did a for loop for the number of cards to get the card that is registered in the array and send a message that the card is stored and accepted, otherwise, it returns a denied message that the card isn't stored in the array with alarm buzzer.

The problem that is the for loop checks the card for all the indexes in the array which is what I want but the result is mixed with accepted and denied.

The question is how to get out of the for loop?

    void check_card(void){
      if (check_lock){
        if (rfid.isCard()){
          if (rfid.readCardSerial()){
            for(byte i=0;i<card_no;i++){

              // start of for loop
              Serial.print("check# ");Serial.println(i);
              if(!memcmp(crd_buf+(i*5),rfid.serNum,5)){
                Serial.println("card accepted");
                digitalWrite(ACCEPT_LED,HIGH);
                digitalWrite(DENIED_LED,LOW);
                digitalWrite(BUZZER,LOW);
                check_lock = 0;
                sys_state = 1;
                lcd_state = ACCEPTED_MSG;
              }
              else{
                Serial.println("card denied");
                digitalWrite(ACCEPT_LED,LOW);
                digitalWrite(DENIED_LED,HIGH);
                digitalWrite(BUZZER,HIGH);
                check_lock = 0;
                sys_state = 1;
                lcd_state = DENIED_MSG;
              }
            }
                // end of for loop

          }
          rfid.halt();
        }
      }
    }

body:
Your problem is this bit:

          for(byte i=card_no*5;i<(card_no*5)+5;i++){
            crd_buf[i] = rfid.serNum[i];}

For the first card you're copying bytes 0-4 of the serNum to bytes 0-4 of crd_buf.

However for the second card you're copying bytes 5-9 of serNum to bytes 5-9 of crd_buf.  That's correct for crd_buf but wrong for serNum.

The right way would be to add card_no*5 to i when creating the index:

          for(byte i=0; i<5; i++){
            crd_buf[(card_no*5) + i] = rfid.serNum[i];}

Or better to define your card buffer as a 2D array so you don't need to do that calculation:

    byte crd_buf[CARDS][5];

    for (i = 0; i < 5; i++) {
        crd_buf[card_no][i] = rfid.serNum[i];
    }

Or simpler:

    memcpy(crd_buf[card_no], rfid.serNum, 5);

----

For your second question, don't print your message at all in the loop.

Instead start out assuming that access is denied. Then if a card matches, grant access.  The simplest way is with a flag.

    if (rfid.readCardSerial()){

        bool accessGranted = false;  // A flag to store the state - start off denied.

        for(byte i=0;i<card_no;i++){
            if(!memcmp(crd_buf+(i*5),rfid.serNum,5)){
                accessGranted = true;
            }
        }

        // replace these with your own message routines.
        if (accessGranted) {
            Serial.println("Access Granted");
        } else {
            Serial.println("Access Denied");
        }
    }


message:
Why is no PWM signal generated using Timer 2?

I managed to work with timer 0 and 1 but am unable to generate a PWM with timer 2 in my atmega328p.

This is the code:

    #include <avr/io.h>

    int main(void)
    {
        /* PD6 output */
        DDRD |= (1 << DDD6);

        /* 50% duty cycle */
        OCR2A = 128;

        /* fast PWM  */
        TCCR2A |= (1 << WGM21) | (1 << WGM20);

        /* prescaler = 8 */
        TCCR2B |= (1 << CS21);

        while (1);

    }

Could someone explain what the issue is and why I am not seeing a pwm signal on pin 6 of my arduino uno board?

Thanks

body:
The output compare unit of timer 2 is connected to pins PB3 (OC2A) and PD3 (OC2B). So you have to configure those as outputs.
Keep in mind that you can't choose any pin when using hardware pwm, this hardware feature is linked to specific pins.

You also have to set `COM2A1` in `TCCR2A`. Otherwise `OC2A` is disconnected from the output compare unit (ref: Table 17-3 in [datasheet][1]).
The effect of `COM2A0/1` depends on the configuration in `WGM20`-`WGM22`.
The same applies to `OC2B` respectively.

  [1]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf


message:
Multiple void loops with ESP8266

I want to run multiple sketches on one sketch. I use the method of multiple void loops. It works but esp8266 take a lot of time to execute commands.

    void Setup()
     {
      setup1();
      setup2();
     }
    void loop()
     {
      loop1();
      loop2();
     }

Is there any method to avoid that ?

body:
If the `setup()` or `loop()` functions call `delay()` then of course that will delay getting to the next function and will slow down the whole process.

The only way to deal with that is to rewrite the code, combining what you're calling and fixing it so that it takes into account the other work it needs to do.

Same thing if you call any blocking functions, like reading from `Serial` until you get a newline.

If that's not the case... well, the ESP8266 is a small, not particularly fast processor. If there are no delays or blocking functions then your code is running as fast as your code might run and you'll just have to live with it.


body:
As long as you're not using `delay()` or other blocking code, as John mentions in his answer, that approach will work fine. I have a fairly large project where I defined a class `ArduinoObject`. The `ArduinoObject` class has a setup method and a loop method, and the main sketch creates and manages an array of `ArduinoObject`s (and another stack of a subclass of `ArduinoObject` called a `MenuObject` that manages menus on the LCD screen the project uses.)

At times there are a dozen or more `ArduinoObjects` being called on each pass through the sketch's `loop()` function and it works just fine. The key thing is to write your sub-loops to be FAST. They should do a tiny amount of work on each pass, and then a little more on the next pass (if needed.) You never want one of your sub-loops to take enough time to make the other sub-loops "stutter".