body:
First C program. Spent a lot of time looking for a solution. KeyPad produces 'char' instead on 'int'.  Plus I want to display 'End', thus I wrote the 'main' to to support 'char' and thus had to adapt a 'char' to 'int' conversion work around, line 89  Certainly there are other errors.

    extern "C"
    // Microwave ccp

      #include <Arduino.h>
      #include <stdlib.h>
      #include <string.h>
      #include <inttypes.h>
      #include <Keypad.h>
      #include "TM1637.h"
      #include <TimerOne.h>
    class TimingISR
    {
    public:
        TimingISR();
        bool Enable_interrupts, Disable_interrupts;

      char lead_char, unit_sec, tens_sec, num_min;
      int int_unit_sec, int_tens_sec, int_num_min;
      int Count_Seconds, Remainder, brightness = 4, PowerLevel;   //BRIGHT_TYPICAL = 4, BRIGHT_DARKEST = 0, BRIGHTEST = 7
      bool Colon, PointFlag, Points_enable;
      char data_char;
    };

    // these are all Clobal Variables
      int pin_Clk = 2; //  or 3 for IC2
      int pin_DIO = 3; //  or 2 for IC2
      int PIN_RELAY = 4;  // controls power on/off to 'cook'
      int PIN_Beeper = 5; // PWM beeps when finished

      int  pos, Remainder, num;
        // Timer variables
      char tempchar;

      // Read Key Pad, continuously
    const byte ROWS = 4; // Four rows
    const byte COLS = 3; // Three columns
    char lastkey;
    char keys[ROWS][COLS] = {
      {'1','2','3'},
      {'4','5','6'},
      {'7','8','9'},
      {'#','0','*'} };// Define the Keymap
    byte rowPins[ROWS] = { 9, 8, 7, 6 };  // Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
    byte colPins[COLS] = { 12, 11, 10 };  // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
    Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );  // Create the Keypad
    #define ledpin 13
    void setup()
    //        Colon = OFF;   PointFlag, Points_enable   ***************************not coded yet
    {
      pinMode(ledpin,OUTPUT);
      digitalWrite(ledpin, HIGH);
      Serial.begin(9600);
    }
    void loop()
    {    // run repeatedly

       char key = kpd.getKey();
       // if ((key = NO_KEY) || (lastkey = key)); delay(100); exit(0);    }

     {  if (key)  // Check for a valid key.
          switch (key) {

          case ('0'): case ('1' - '0'): case ('2' - '0'): case ('3'-'0'): case ('4' - '0'):  case ('5' - '0'): case ('6' - '0'): case ('7' - '0'): case ('8' - '0'): case ('9' - '0'): //all key integers
     { if ( Count_Seconds > 0 ) // Cooking in progress, thus SHUT DOWN, any numeric key shuts down the power
      {  lead_char = 'C';
         num_min=    'n';
         tens_sec=   'C';
         unit_sec=   'l';
    goto CancelPower;
      } //  Short Delay, then Display “A000”
        else
      {     num_min = tens_sec;  // integers: update the 'time' 'stack' as integers
            tens_sec = unit_sec;
            unit_sec =  (key-'0');  // '0' = 30 base 10 etc
            lastkey = key;
            Colon = ON;
    goto DisplayAll;   // accumulate time value  // any old num_min_segment fall off
      } }     //
      break;  //---------------------------------------

          case ('#'-'0'):  // Start Heating
          if (lead_char != 'A')
    goto OOPS ;
           else  // convert time parts to Count_Seconds
            (  Count_Seconds = int(unit_sec) + int(tens_sec) * 10 + int(num_min) * 60  );
      {       if  (  Count_Seconds > 0 )
    TimingISR(  ) ;
              lead_char = 'c'; //  ’c’ooking
              Colon = ON;
              pinMode(PIN_RELAY, OUTPUT);
              digitalWrite(PIN_RELAY, HIGH);  // turn on the heat
              PowerLevel = 10;
      }
       break;  //---------------------------------------

          case  ('*'-'0'):  // Set Power level or default DEFROST Power level
         //unit_sec_segment = a number as a 'segment' value    // a power level manually inserted
    {   if ( lead_char ==  'A'  &&   num_min == '0' &&  tens_sec == '0' )
    {    if ( unit_sec =  !('0') )         // &&  unit_sec > '0' && unit_sec <= '9' )
     {      int PowerLevel = aoti(unit_sec);
            lead_char = 'P';    //Display "P=n0", n = percent power via duty cycle
            num_min =   '=';
            tens_sec = unit_sec;  //display 'char' as 10's 'percent' value, move number left one place
            unit_sec =  '0';  // insert a zero
     }   else  // power not manually set
     {      PowerLevel = 2;     // 'defrost' = 20 %
            lead_char = 'd';
            num_min =   'E';
            tens_sec =  'F';
            unit_sec =  '_';
     }
    goto DisplayAll;
    }
       else
    //    if ( lead_char != 'A'  ||  num_min != '0' ||  tens_sec != '0' || unit_sec !=  '0' )
    goto OOPS ;
    }     //end if, of Case “*"
          break;  //---------------------------------------

       lastkey = key;
    delay(100);  //100 millisec
    }   // End Of Switch Key
    }  //  End of If (Key)
    //return

    // Beginning of GOTO's--------------------------------------
    {
    OOPS:
         lead_char = 'o';   //Display "ooPS"
         num_min =   'o';
         tens_sec=   'P';
         unit_sec =  'S';   // then Short Delay, then Display “A000”
    CancelPower:
          pinMode(PIN_RELAY,OUTPUT);
          digitalWrite(PIN_RELAY, LOW);  // turn off the heat
    goto DisplayAll;  //ready to accumulate 'heating' time input
        delay (3000);     //let it display for 3 Count_Seconds, then clear the display
        lead_char = 'A';        //ready to accumulate 'heating' time input
        num_min =   '0';
        tens_sec =  '0';
        unit_sec =  '0';
        Disable_interrupts;
        int Count_Seconds = 0 ;
    DisplayAll:

    // DisplayAll:  //Would like to put this into the 7 segment display
     // Address each 7 segent unit, one after the other; left to right
    {    for ( pos = 0 ; 3 < 4; pos++);
          if ( pos = 0 )
            char_data = lead_char
          if ( pos = 1 )
            char_data = num_min
          if ( pos = 2 )
            char_data = tens_sec
          if ( pos = 3 )
            char_data = unit_sec

    if ( char_data='0') ; num = 1; // the 7 segment display 'h' only allows for integers 0 through 15, i.e. HEX characters
    if ( char_data='1') ; num = 2;
    if ( char_data='2') ; num = 3;
    if ( char_data='3') ; num = 4;
    if ( char_data='4') ; num = 5;
    if ( char_data='5') ; num = 6;
    if ( char_data='6') ; num = 7;
    if ( char_data='7') ; num = 8;
    if ( char_data='8') ; num = 9;
    if ( char_data='9') ; num = 10;
    if ( char_data='A') ; num = 11;
    if ( char_data='B') ; num = 12;
    if ( char_data='C') ; num = 13;
    if ( char_data='d') ; num = 14;
    if ( char_data='E') ; num = 15;
    if ( char_data='F') ; num = 16;
    if ( char_data='c') ; num = 17;
    if ( char_data='H') ; num = 18;
    if ( char_data='h') ; num = 19;
    if ( char_data='I') ; num = 20; //left vertical 2 segments
    if ( char_data='i') ; num = 21;
    if ( char_data='L') ; num = 22;
    if ( char_data='l') ; num = 23; /right /vertical 2 segments
    if ( char_data='n') ; num = 24;
    if ( char_data='O') ; num = 25;
    if ( char_data='o') ; num = 26;
    if ( char_data='P') ; num = 27;
    if ( char_data='r') ; num = 28;
    if ( char_data='S') ; num = 29; //same as a five
    if ( char_data='U') ; num = 30;
    if ( char_data='u') ; num = 31;
    if ( char_data=' ') ; num = 32;
    if ( char_data='=') ; num = 33;
    if ( char_data='-') ; num = 34; //dash / minus
    if ( char_data='_') ; num = 35; //under score
    if ( char_data='[') ; num = 36; /left /bracket
    if ( char_data=']') ; num = 37; //right bracket
    // there are other usefull, such as "top score", "middle score... "top minus", "bottom Minus",
    // which yoou could assign some other othervise unprintable character as a proxy, e.g  the ampersant to display a "top position minus sign"

    }
    Disable_Interrupts;
      TM1637DisplayAll(uint8_t num, uint8_t pos);
    Enable_Interrupts;
    }
    return(0)
    }
    }  //  End of void LOOP()

    //--------------------------------------

    // ----------------------------------------------------

title: Cannot find solution to "variable out of scope"

Answers: 1

body:
 1. The first line says `extern "C"` but you haven't scoped it, I'm really not sure what you are trying to achieve or if it will work.  Personally I would remove that line.
 2. "Microwave ccp" come compilers complain if the filename is not right.  As far as I know it should be either .cc or .cpp, but its proably just a typo in the comment, because I doubt you would get this far if it was wrong.
 3. Pins 2 and 3 for I2C, its normally A4 and A5.
 4. Line 58 The reason your commented out code didn't work is `(lastkey = delay)` you should have used equivalence (==) rather than assignment (=).
 5. Use function calls rather than goto statements, it isn't the 1970s anymore! :)
 6. `int(variable)` is not casting it is creating an integer from variable and then its disposed of when it goes out of scope.  `(int)variable` is casting.
 7. `for (pos = 0; 3 < 4; pos++);` This will cause you problems, because its an empty loop, does nothing, which means `pos` doesn't have the value you think it does.

Please don't take any of this the wrong way, I'm not a teacher but I need to explain what has gone wrong with you code and how you can fix it.  It is not personal criticism, I bet my first program was ten times worse.

You seem to have a misunderstanding of "variable scopes".  Put simply a variable can only be 'seen' after the point you declare it and within the immediate curly braces {} and all child braces. e.g.:

    int GlobalVariable = 1; // Visible through-out the code
    void loop ()
    {
        int LoopVariable = 2;
        for (int ForVariable = 0 ForVariable < LoopVariable; ++ForVariable)
        {
           ++GlobalVariable;
        }
        Serial.println (ForVariable);  // ERROR
    }
    void AFunction()
    {
        Serial.println(LoopVariable);//ERROR
    }

You immediate error is you have defined the variable `unit_sec` inside class TimingISR and you are accessing it like a local variable.

Now The way you have defined `class TimingISR` is like designing a car, its fine on paper but you can't drive it until you build one.  As far as I can see you haven't instantiated an instance of TimingISR.  It sounds complex but you have been doing it for int and char (They aren't classes, but its very similar)

    int pin_clk = 2;
    TimingISR aTimingISR;

If a value should change define it as const.

    const int pin_clk = 2;

If it does change you will get a compilation error rather than suddenly sending the I2C clock signal to the on board LED.

goto is evil.

    case ('0'): case ('1' - '0'): case ('2' - '0'): case ('3' - '0'): case ('4' - '0'):  case ('5' - '0'): case ('6' - '0'): case ('7' - '0'): case ('8' - '0'): case ('9' - '0'): //all key integers
      { if (Count_Seconds > 0) // Cooking in progress, thus SHUT DOWN, any numeric key shuts down the power
      {
       lead_char = 'C';
       num_min = 'n';
       tens_sec = 'C';
       unit_sec = 'l';
       goto CancelPower;

    CancelPower:
      pinMode(PIN_RELAY, OUTPUT);
      digitalWrite(PIN_RELAY, LOW);  // turn off the heat
      goto DisplayAll;  //ready to accumulate 'heating' time input
      delay(3000);         /// NEVER EXECUTED
      lead_char = 'A';     /// NEVER EXECUTED
      num_min = '0';       /// NEVER EXECUTED
      tens_sec = '0';      /// NEVER EXECUTED
      unit_sec = '0';      /// NEVER EXECUTED
      Disable_interrupts;  /// NEVER EXECUTED
      int Count_Seconds = 0;/// NEVER EXECUTED
     DisplayAll:

      // DisplayAll:  //Would like to put this into the 7 segment display
      // Address each 7 segent unit, one after the other; left to right
    // Code cut (but it should be == not =)
      Disable_Interrupts;
      TM1637DisplayAll(uint8_t num, uint8_t pos);
      Enable_Interrupts;

Code isn't being executed because gotos never return to the call, they just carry on from the label.  Try this instead:

    // TimingISR& theISR means you can change the values in theISR
    // TimingISR  theISR means you copy theISR and all changes are lost when the function exits.
    // TimingISR const& theISR means you can't change the values in theISR
    void CancelPower (TimingISR& theISR)
    {
      pinMode(PIN_RELAY, OUTPUT);
      digitalWrite(PIN_RELAY, LOW);  // turn off the heat
      DisplayAll(theISR);  //ready to accumulate 'heating' time input
      delay(3000);     //let it display for 3 Count_Seconds,
      ClearDisplay();
      theISR.lead_char = 'A';        //ready to accumulate 'heating' time input
      theISR.num_min = '0';
      theISR.tens_sec = '0';
      theISR.unit_sec = '0';
      theISR.Disable_interrupts(); // This should be a function that does something, not a bool
      theISR.Count_Seconds = 0;
    }

I'm afraid that's just some of the things you need to change, ***BUT*** that's one hell of a program for a first attempts and that's the only reason I raised so many issues.  Try again and post it again, I'd love to  see the differences.


body:
I want to make a small and compact gas sensor using the Arduino Uno and MQ2 sensor. However all sites list a breadboard as a requirement.

Now, the MQ2 has A0, D0, GND, VCC, pins and the Uno also has A0, GND, 3.3V and 5V connectors.

So can I use Male to Female Jumper Wires to directly connect these? I am not using anything else like LEDs or speakers.

My code keeps the inbuilt LED ON when smoke level is LOW and blinks when the Level is HIGH. Also will I need any resistor for it?

title: Use MQ2 Sensor with Arduino Uno without breadboard?

Answers: 5

body:
Usually I don't think at the UNO as "small and compact"; I usually prefer to use a barebone atmega or an arduino pro mini / nano as alternatives (nano has inbuilt usb, pro mini doesn't). But anyway...

The [SeeedStudio MQ2][1] has four pins, but no D0 pin; it has Vcc, GND and A0 and a NC pin (which means do not connect this pin).

So... Yes, The sensor is 5V powered and has an analog out interface, so you should connect the A0 pin to any analog input on the arduino (A0..A7); you are not forced to use A0.

Be careful that the sensor uses 800mW of power (160mA at 5V) in the pre-heating, so you are not advised to use it form a battery source

  [1]: http://wiki.seeed.cc/Grove-Gas_Sensor-MQ2/

body: Yes, you can use male to female jumper wires to directly connect them. Breadboard is not a requirement. Also, you don't need any resistors.

body:
This is point-to-point wiring, a technique loved by high-end audio amplifier fans:

[![point-to-point][1]][1]

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

body:
You can connect it exactly like this.
I'm using female-female jumper wires and have soldered pins onto the UNO clone to enable me to do this.

[![MQ2 Connected to Uno R3 Clone close-up showing pins soldered onto board][2]][2]

Pins on sensor from left to right A0 - D0 - GND - VCC

You can also find the wiring diagram on-line for a barebones sensor
if you've not got the sensor module.

here [MQ2- Sensor Information][4]

  [2]: https://i.stack.imgur.com/HGb3T.jpg

  [4]: https://playground.arduino.cc/Main/MQGasSensors

You can either use the D0 output pin to turn on an LED in the presence of gas / smoke or you can use the A0 to report a gas / smoke level.

The code in my other reply is for the analogue reporting of the sensor value.
The Digital output is either on or off and the potentiometer on the back of the sensor will adjust the point at which the D0 pin report a High output level, if it's not set right then the D0 pin won't actually output a voltage.

body:
MQ2 flammable gas and smoke sensor detects the concentrations of combustible gas in the air and ouputs its reading as an analog voltage.
The sensor can measure concentrations of flammable gas of 300 to 10,000 ppm.

The sensor can operate at temperatures from -20 to 50°C and consumes less than 150 mA at 5 V.

Connecting five volts across the heating (H) pins keeps the sensor hot enough to function correctly. Connecting five volts at either the A or B pins causes the sensor to emit an analog voltage on the other pins.

A resistive load between the output pins and ground sets the sensitivity of the detector. Please note that the picture in the datasheet for the top configuration is wrong. Both configurations have the same pinout consistent with the bottom configuration.

The resistive load should be calibrated for your particular application using the equations in the datasheet, but a good starting value for the resistor is 20 kΩ.

[DataSheet PDF Here][1]

        * Smoke/Gas Sensor Module project
         * tutorial url: http://osoyoo.com/?p=671
         */
        void setup()
        {
            Serial.begin(9600);
        }

        void loop()
        {
            int val;
            val=analogRead(0);
            Serial.println(val,DEC);
            delay(100);

    }

[![MQ2 - Wiring Diagram][2]][2]

  [1]: https://www.pololu.com/file/0J309/MQ2.pdf
  [2]: https://i.stack.imgur.com/H9otg.jpg


body:
I need to implement callback in my C++ library. The "proper" C++ way of doing it would be to create an interface (or pure abstract class) and pass it to interested party. I'm wondering though, would that be optimal?

My analysis:

* Function pointer - occupies 2 bytes in memory (+code of function)
* Class derived from abstract one - occupies 2 bytes in memory PLUS 2 bytes for VMT (since we have derived method) PLUS size of VMT table (if any) (+code of method).

Is optimizer smart enough to compile abstract class with single method as method pointer? Which solution is more optimal in regard of memory and speed? Is my analysis correct?

title: Function pointer or abstract class?

Answers: 2

body:
The best way is to find out yourself, there are memory 'debug'  functions to show the amount of free memory, so if you do some tests you know for sure what the compiler optimizes.

See e.g. [AvailableMemory][1] library.

It might be quite hard to exactly calculate and predict the optimizer. However, is it really needed to optimize? Mostly it is best to not optimize before knowing it is really necessary.

  [1]: https://playground.arduino.cc/Code/AvailableMemory

body:
Sometimes you want your callback to be fed some data that you provide
when you register that callback. Here is a very common callback pattern
in plain C that does that:

    // The API:

    typedef void (*callback_t)(void *data);
    void register_callback(callback_t callback, void* data);

    // Usage:

    typedef struct {
        // stuff only the user of the API knows about.
    } my_data_t;

    void my_callback(void *in_data)
    {
        my_data_t *data = (my_data_t *) in_data;
        // do something with data->foo, data->bar...
    }

    // ...somewhere else:
    my_data_t my_data = { stuff... };
    register_callback(my_callback, (void *)&my_data);

The problem is: it's clumsy. C++ classes allow you to pack together the
code (the callback function) and the data it needs. Thus, if in your use
case you need to pass data to the callback, by all means use a C++
class. It will make your life easier and you are unlikely to even notice
the memory overhead.

However, if you only need to pass a function, with no attached data,
then a plain function pointer would be both easier for the API user and
optimal memory-wise.


body:
I have been trying to find a solution for `UART receive interrupt` for my `UNO` board and I came across a possible solution in : [PCInt][1]

I did a small editing in the following portion of the code to make it work for `UART`.(code works like a loop-back test)

    void RXint(void) {
    char k;
    if(Serial.available()>0)
    {
    k=Serial.read();
    Serial.print(k);
    }}
    void setup()
    {
    Serial.begin(9600);
    PCattachInterrupt(0, RXint, FALLING);
    }
    void loop()
    {}

The code works pretty well with one big drawback.
The character displayed is having one char delay, what i mean is that for the following input
> qwerty

output is
> qwert

That means if I enter the 5th char,the output will be 4th one.
When the first input is given, it doesn't show output till the second input is entered.

Can someone help me out with this

(This is only a test code, the interrupt part is to be used in a larger code where the `loop()` carries out different tasks and interrupt is to be raised when data is received via `UART`)  .

  [1]: https://playground.arduino.cc/Main/PcInt

title: Delay in displaying data received from UART when used with PCINT on PIN0

Answers: 2

body:
Your interrupt is happening at the same time the START bit of the *next* frame is arriving in the hardware. As a result you don't have that data yet, because it's still to arrive. All you have is what has gone before. You won't get the new character until the frame has finished arriving and the UART RX interrupt fires and the byte gets copied out of the RX FIFO and placed into the Arduino receive buffer.

The way you are doing it is completely wrong. The data is already being captured using an interrupt and placed in a buffer for you to deal with as you see fit at a time that suits you (as long as it is before the buffer overflows).

If you can't read it fast enough using your main loop (or variations thereon) then you need to rethink how you are doing your main loop.

body:
As other have emphasized, make sure your `loop` runs freely, without delays or blocking while loops.  It would be very unusual to have a `loop` that *really* takes > 64ms (the input buffer overflow time @ 9600).

However, there is one case where a frequently-used library is blocked for 150ms or more:  SDfat.  If you are logging data, the library may have to wait for the SD card to accept more data.  It is an indeterminate length of time, and it is specific to the individual card.  In this case, you have two choices:

* process the RX characters as they arrive, during the RX character interrupt; or

* add a `yield` call to the offending SDFat method.

For the former solution, I have posted modified versions of the most commonly-used Arduino serial port libraries.  They all have a new `attachInterrupt` method that allows your function to be called for each RX character.  See [NeoHWSerial](https://github.com/SlashDevin/NeoHWSerial) (a modified `HardwareSerial`), [NeoICSerial](https://github.com/SlashDevin/NeoICSerial) (a modified `AltSoftSerial`) and [NeoSWSerial](https://github.com/SlashDevin/NeoSWSerial) (a more-efficient alternative to `SoftwareSeriall`).


body: I am currently building my first Arduino project : a car that you can control from your computer. I have my Arduino Mega that outputs 3.3 or 5V and my stepper that receives 12-25V, how can I make my Arduino digitally write something to that stepper?

title: Output 12-25V from Arduino Mega

Answers: 1

body:
Use an H-bridge motor driver. They can use arduino signals to control higher voltages without damaging the arduino. Check out the  [L298N][1] from gearbest. It's cheap but will probably do the trick if you're not using too much current.

It can supply about 1A through each gate at 5-30V.

[this video][2] should help explain it. (I haven't watched the video but it seems like it got good feedback).

  [1]: http://m.gearbest.com/other-accessories/pp_226466.html
  [2]: https://m.youtube.com/watch?v=QixPEZgRVzM


body: I'm trying to make a time lapse video of a crystal patch in a small space.  I need some way of taking a picture every hour or so within an area no greater than 35mm, the smaller the better.  Something like the Arduino-Leonardo-Beetle would be the ideal dimensions.  What sort of camera and Arduino board do people recommend?  Thanks!

title: Taking pictures with a small Arduino

Answers: 1

body:
Check out [Arducam][1]. I have used it and the library is maintained.

  [1]: http://www.arducam.com/tag/arducam-rev-c/


body:
Is there any method with which I can split a string given by `Serial.read()` into an array of 3 items: [command, address, message], to write it to EEPROM?

Thanks.

title: Splitting a string read from Serial into parts

Answers: 2

body:
The first thing you should do is to collect your serial input into a string.

If your incoming data use a separator, then you can take advantage of the useful function "readStringUntil".

For example, if your separator is comma (,):

    while (Serial.available() > 0) {
      var1 = Serial.readStringUntil(','); // writes in the string all the inputs till a comma
      Serial.read();
      var2 = Serial.readStringUntil(',');
      Serial.read();
      var3 = Serial.readStringUntil('\n'); // writes in the string all the inputs till the end of line character
    }

At this point you have your data in 3 different variables and you can use the standard eeprom library to store. Don't forget you will need to declare the variables and to initialize the Serial.

A faster way is to save the whole input in string and process it when ready.

Much better it will be if you use interrupts attached on the Serial input, so you can keep free your loop from waiting data. This can't be done with the standard Serial library but you can use this library:

https://github.com/SlashDevin/NeoHWSerial

It works really well, we use it to collect data from GPS receivers at very high speed and it's fast.

N.B. eeprom is limited in the numbers of reads and writes it can support before risk a failure. Even 100,000 reads/writes sounds a big numnber, if you write the data once every second your eeprom will die in just 27 hours, a day of life. Try to write data only when it's strictly necessary and read data as well only when you start the procedure that uses those data, once.

body:
That's the code I used to fix this issue.

<!-- language: lang-cpp -->

    #include <EEPROM.h>

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

    void loop() {
        while (Serial.available() > 0) {
          String command = Serial.readStringUntil(' '); // writes in the string all the inputs till a comma
          Serial.read();
          String addressStr = Serial.readStringUntil(' ');
          Serial.read();
          String messageStr = Serial.readStringUntil('\n'); // writes in the string all the inputs till the end of line character
          int address = addressStr.toInt();
          int message = messageStr.toInt();
          if (command == "Read"){
            Serial.print("Reading from EEPROM->Address: ");
            Serial.print(address);
            Serial.print("\n");
            Serial.print("Content of ");
            Serial.print(address);
            Serial.print("is: ");
            Serial.println(EEPROM.read(address));
          }else if(command == "Write"){
            Serial.print("Writing to EEPROM in Address: ");
            Serial.print(address);
            Serial.println();
            EEPROM.write(address, message);
          }
      }
    }


body:
So i'be been toying with the idea in my head of creating a solar powered weather station with an arduino, two 6V 2W [solar panels][1] in parallel, two 5V USB battery packs, and an [adafruit module][2] which converts voltages from 3-12V to 5V (to charge my batteries). I'm also working on using some small relays or MOSFETs for the arduino switch between batteries.

The problem: If my solar panel voltage drops below 3V, the adafruit board will supply the batteries with a n unstable voltage below 4.8V. I need some sort of circuit or sensor that is capable of detecting when the voltage  from the solar panels drops below 3.3V and which will open the circuit to protect the batteries from unstable voltages.

  [1]: http://m.gearbest.com/garden-supplies/pp_246917.html
  [2]: https://www.adafruit.com/product/2190

title: Undervoltage from solar panels

Answers: 1

body:
You have selected a number of things that don't go well together. It is possible to use relays or mosfets to switch between batteries, and the Arduino could be used to measure a voltage. Or you can make a circuit with a few electronic components (e.g. a comparator). However, no one does it like that. It would be unreliable.

Every solar power charging module can handle darkness as well. Some modules will also create 5V.

This Adafruit module has no 5V output, it only contains the charging part: [Adafruit:USB / DC / Solar Lithium Ion/Polymer charger - v2][1]
It is out of stock at the moment, and you need solar cells, battery, a cable, and a DC-DC converter to make 5V.
When it is dark and the battery is empty, I assume the output drops and the Arduino stops working. Adafruit made [a tutorial][2] for it that shows the DC-DC converter and also Collin shows a DC-DC converter: [Youtube, Collin's Lab: Solar][3]

There are other modules like that. For example the [Sparkfun Sunny Buddy][4].

Take care that the batteries don't get too hot.
It is possible to run some Arduino boards directly from a battery (3.1 to 4.2V). Then you would not need the DC-DC converter.
Buy solar cells that are the best in low light conditions. With enough sunlight, the power is no problem. It is the dark winter days that could be a problem.

  [1]: https://www.adafruit.com/product/390
  [2]: https://learn.adafruit.com/usb-dc-and-solar-lipoly-charger
  [3]: https://youtu.be/RRW4pBCzXBA?t=4m21s
  [4]: https://www.sparkfun.com/products/12885


body:
How to convert the char array to Byte array? I tried every method but it doesn't work.

    char CardNumber[8] = "B763AB23"; // Length is 8, basically it's in Hex
                                     // B7 63 AB 23

I need to convert it into Byte array to `byte CardNumberByte[4];`
So basically, it should be like :

    CardNumberByte[0] = B7;
    CardNumberByte[1] = 63;
    CardNumberByte[2] = AB;
    CardNumberByte[3] = 23;

I am unable to find any solution for that.

title: How to convert an hex string to an array of bytes?

Answers: 3

body:
There are indeed many methods (and they all work if done right).

Is it always a lenght of 8 ? That means it is 32-bit unsigned long number.
The strtoul can convert it to a long. Use '16' for the base. If you need the seperate numbers, you can shift the unsigned long and convert to bytes or use a union.

It is also possible to do with a for statement can convert each character of the input to a value: [forum.arduino.cc: convert HEX (ASCII) to a DEC int][1]

[**ADDED**]
Thank you @goddland_16 for providing a full sketch. I could not stay behind and wrote a sketch with strtoul.

    char *CardNumber = "B763AB23";
    byte CardNumberByte[4];

    void setup()
    {
      Serial.begin(9600);
      Serial.println("With strtoul");

      // Use 'nullptr' or 'NULL' for the second parameter.
      unsigned long number = strtoul( CardNumber, nullptr, 16);

      for(int i=3; i>=0; i--)    // start with lowest byte of number
      {
        CardNumberByte[i] = number & 0xFF;  // or: = byte( number);
        number >>= 8;            // get next byte into position
      }

      for(int i=0; i<4; i++)
      {
        Serial.print("0x");
        Serial.println(CardNumberByte[i], HEX);
      }
    }

    void loop()
    {
    }

  [1]: http://forum.arduino.cc/index.php?topic=45182.0

body:
Here is a simple solution to your question. I took each character, checked against its hexadecimal character and returned as a combination.

    char CardNumber[] = "B763AB23";
    byte CardNumberByte[4];

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

    void loop() {
      for(char i = 0; i < 4; i++)
    {
      byte extract;
      char a = CardNumber[2*i];
      char b = CardNumber[2*i + 1];
      extract = convertCharToHex(a)<<4 | convertCharToHex(b);
      CardNumberByte[i] = extract;
      Serial.println(CardNumberByte[i], HEX);
    }

      while(1);
    }

    char convertCharToHex(char ch)
    {
      char returnType;
      switch(ch)
      {
        case '0':
        returnType = 0;
        break;
        case  '1' :
        returnType = 1;
        break;
        case  '2':
        returnType = 2;
        break;
        case  '3':
        returnType = 3;
        break;
        case  '4' :
        returnType = 4;
        break;
        case  '5':
        returnType = 5;
        break;
        case  '6':
        returnType = 6;
        break;
        case  '7':
        returnType = 7;
        break;
        case  '8':
        returnType = 8;
        break;
        case  '9':
        returnType = 9;
        break;
        case  'A':
        returnType = 10;
        break;
        case  'B':
        returnType = 11;
        break;
        case  'C':
        returnType = 12;
        break;
        case  'D':
        returnType = 13;
        break;
        case  'E':
        returnType = 14;
        break;
        case  'F' :
        returnType = 15;
        break;
        default:
        returnType = 0;
        break;
      }
      return returnType;
    }

body:
A char array is a byte arrray. No difference whatsoever

What you are attempting to do is a conversion of hex string to byte. For that you have to determine if you are scanning left to right or right to left.

After that convert a char in the string to a half byte.

From there you shift the half byte left and or it with the next half byte until the whole string has been exhausted.


body:
I'm working on a small game on arduino but I'm facing some really odd behavior. When I run this code all of my leds flash on and off in less than a second even though `delay(10000);` should stop them for 10 seconds. However if I remove the while(game_running) block they go back to flashing every 10 seconds even though that block of code never actually runs.

    int yellow = 12;
    int green = 10;
    int red = 9;
    int blue = 11;

    int debug = 13;

    int sequence[1000];
    int level = 0;

    int game_running = false;

    void setup() {
      pinMode(yellow, OUTPUT);
      pinMode(blue, OUTPUT);
      pinMode(green, OUTPUT);
      pinMode(red, OUTPUT);

      pinMode(debug, OUTPUT);
    }

    void loop() {

      // Pre Game light flash
      digitalWrite(yellow, HIGH);
      digitalWrite(green, HIGH);
      digitalWrite(red, HIGH);
      digitalWrite(blue, HIGH);
      digitalWrite(debug,HIGH);
      delay(10000);
      digitalWrite(debug,LOW);
      digitalWrite(yellow, LOW);
      digitalWrite(green, LOW);
      digitalWrite(red, LOW);
      digitalWrite(blue, LOW);
      delay(10000);

      game_running = false;
      level = 0;

      while(game_running) {

        sequence[level] = random(4); // Select next color

        // Blink LEDs
        for (int i=0; i < level; i++) {

           if(sequence[i] == 0) {
             digitalWrite(yellow, HIGH);
             delay(1000);
             digitalWrite(yellow, LOW);
             delay(1000);
           } else if(sequence[i] == 1) {
             digitalWrite(green, HIGH);
             delay(1000);
             digitalWrite(green, LOW);
             delay(1000);
           } else if(sequence[i] == 2) {
             digitalWrite(red, HIGH);
             delay(1000);
             digitalWrite(red, LOW);
             delay(1000);
           } else {
             digitalWrite(blue, HIGH);
             delay(1000);
             digitalWrite(blue, LOW);
             delay(1000);
           }
        }
        level += 1;
      }
    }

title: delay() runs super fast unless I remove a while loop that never runs

Answers: 2

body:
offtopic (but cannot put it in a comment):

I do not see any problem with your code (maybe it's in the circuit?)

You can rewrite the 10 s pregame flash as:

    // Pre Game light flash
    setAllLights(HIGH);
    setAllLights(LOW);

    void setAllLight(int state)
    {
      digitalWrite(yellow, state);
      digitalWrite(green, state);
      digitalWrite(red, state);
      digitalWrite(blue, state);
      digitalWrite(debug, state);
      delay(10000);
    }

You can even optimize this further by creating an array:

    int[] lights = { yellow, green, red, blue, debug}

    void SetAllLights(int state)
    {
       for (int color = 0; color < sizeof(lights) / sizeof(int); color++)
       {
           digitalWrite(lights[color], state);
       }
    }

You can rewrite the inside of the loop like:

    switch (sequence[i]):
       case 0:
          flash(yellow);
          break;

       case 1:
          flash(green);
          break;

       case 2:
          flash(red);
          break;

       default:
          flash(blue);
          break;
    }

    void flash(int colorPin)
    {
       digitalWrite(colorPin, HIGH);
       delay(1000);
       digitalWrite(colorPin, LOW);
       delay(1000);
    }

body:
I will add an official answer just so that others can see it if they run into similar problems.

The issue is with the `int sequence[1000]` array, which eats up 2,000 bytes of data memory. The Uno only has 2,048 bytes of data memory so the instability is due to this memory hog of an array. Use a smaller number of array entries or switch to `char` (if you can) to use half the bytes of an `int`.


body: Pretty simple question. Is there a microcontroller that can output hdmi? If not, what microcontrollers can output any type of video?

Answers: 2

body: It depends on what you are looking for. There are lots o chips made to control and process hdmi frames. However, as Jot said, the arduino is not suitable for this. The arduino can output basic VGA, but it does not have enough "horsepower" to play with HDMI. The best and cheapest solution is to use a Raspberry Pi.

body: RP2040 can output DVI which HDMI monitors can render.


body:
I would like to be able to read the serial numbers of SD cards using the SD.h library. Only reading the values is enough, I am not looking to modify the CID.
This should be possible but I do not have the programming skills to get it running.

I am using an esp8266 and already have the SD card running and working correctly. Only the chipselect needed to be modified for the SD library to work.

So far I have found this in Sd2Card.h

          /**
       * Read a cards CID register. The CID contains card identification
       * information such as Manufacturer ID, Product name, Product serial
       * number and Manufacturing date. */
      uint8_t readCID(cid_t* cid) {
        return readRegister(CMD10, cid);
      }
      /**

And in Sd2Card.cpp there is this:

    /** read CID or CSR register */
    uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) {
      uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
      if (cardCommand(cmd, 0)) {
        error(SD_CARD_ERROR_READ_REG);
        goto fail;
      }
      if (!waitStartBlock()) goto fail;
      // transfer data
      for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec();
      spiRec();  // get first crc byte
      spiRec();  // get second crc byte
      chipSelectHigh();
      return true;

     fail:
      chipSelectHigh();
      return false;
    }

So it seems that the underlying code has been prepared in the library already, my question is how would I include it into a sketch like CardInfo.ino?

title: read CID of SD card with SD.h library

Answers: 1

body:
The method is visible from within your sketch. You just need to first create a `cid_t` struct like this in your sketch:

    cid_t cid;  // at the top with the other globals

Then call `readCID()` anywhere in `setup()` after the card has been initialized.

    card.readCID(&cid);
    Serial.print("Serial number: "); Serial.println(cid.psn); // psn is the serial number field of the struct

Check out `SdInfo.h` for the other struct members.


body:
The sample code is this:

 [Sample code for Edgar Bonet][1]

I have questions. I need to integrate the analog sine wave of 60 Hz, this signal described in the next picture, adding an offset near 2.5 V, because I can damage the Arduino board with the negative signal cycle. Internally on the Arduino board, I remove this offset, multiplying by 2, and subtracting 1.

    V1=analogRead(A0)*2/1023.0-1.0;

The sampling period must be at least fs=300 Hz, T=1/fs and V1 is the signal I need integrate.

What modifications can I make to Edgar Bonet's code?

[![Schematic and waveform][2]][2]

  [1]: https://arduino.stackexchange.com/a/9460/34871
  [2]: https://i.stack.imgur.com/hY0Jx.png

title: Integrating an analog signal using Arduino Mega 2560

Answers: 3

body:
> `V1=analogRead(A0)*2/1023.0-1.0;`

This will give you the voltage across R1 in units of 2.5 V. I do
not know whether you care or not about the units but, if you want the
voltage in volts, then:

* the voltage at the Arduino input is `analogRead(A0) * (5.0/1024)`
* to get the voltage across R1, you have to subtract 2.5 V
* to get the voltage at the output of the transformer, you have to
  multiply by 11.

This could be written as

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

    float V = (analogRead(A0) * (5.0/1024) - 2.5) * 11;

but, in order to minimize the number of floating point operations, you
can simplify it to

    float V = analogRead(A0) * (55.0/1024) - 27.5;

You could then integrate the voltage by running it through a function
like this:

    static float integral(float x)
    {
        static float y;                         // last filter output
        static uint32_t last_sample;            // last time sampled
        uint32_t now = micros();
        float dt = (now - last_sample) * 1e-6;  // step time in seconds
        last_sample = now;
        y += x * dt;
        return y;
    }

Now, there is an issue with this approach: the average voltage at the
input of the Arduino is not going to be exactly 2.5 V, because
your resistors R3 and R4 will not have identical resistance. Then the
output of the integral will slowly drift and eventually become
unreasonably large.

One way to mitigate this drift problem is to measure this average using
the same Arduino running the same program: disconnect the mains, see how
the output of the program drifts, and measure the drift rate. Then you
subtract the drift rate from the `27.5` in the code, and fine tune until
there is no drift at all. There is, however, the risk that some time
later it will drift again, due to components changing behavior as the
temperature changes.

A better option would probably be to _not_ integrate, but instead use a
first-order low-pass filter. Such a filter behaves like an integrator
for any signal faster than its cutoff frequency but, unlike a simple
integrator, it has a finite gain at zero frequency. You can turn the
integrator into a low-pass filter simply by changing the line
`y += x * dt;` into

    y += (x - y/tau) * dt;

where `tau` is the time constant of the filter.

body:
The signal will saturate.

You should increase the attenuation if you want to be able to add the full cycle.  Or add half cycle and make assumptions about the other half.

As to the code you simply needs to convert the ADC readings to a DC reading and subtract the center offset from it  . Much better to do that in the ADC reading domain. Like this

  Y = analogread(AIN) - 2.5 * 1023 / Vref;

body:
**Brief Electrical Comment First**

The circuit as depicted seems sound, but it may be wise to measure the max and min peaks with an oscilloscope or multi-meter to ensure you are within the voltage range of the Atmel chip on the Mega 2560, which is zero Volts to Vcc [1] per Atmel processor's spec sheet [1].

Since Vcc is 5V per the Mega's schematic [2], the safe range you depicted is correct, however you cannot trust the voltage on the mains to stay within IEEE specifications, the p-p secondary Voltage of the adapter to be dead on in proportional relation to the primary, or the resistors to be in the center of their 5% or 10% range of precision.  You may wish to add some potentiometers to your circuit to make adjustments.

**Now the Math and Software Implementation**

Continue to take the i,t (integer, time) sample vector as in the example you referenced.  I changed the variable names to be more descriptive from a systems engineering point of view.

    int s_in = analogRead(input_pin);
    unsigned long microsecs = micros();

The algebraic (not code) relation of the sample to the instantaneous voltage is as follows.

> v_in = 5V X s_in / 1024
>
> v_no_offset = v_in - v_offsreallyreallyet
>
> v_offset = 2.5
>
> v_secondary = v_no_offset X (110 KOhms / 10KOhms)

Keep in mind here that the sample is not a p-p measurement.  It is an integer representing a Voltage measurement over a very small time range relative to the period of an approximate [3] 60 Hertz sine wave.  There is no reason to multiply samples or corresponding Voltages by two for this circuit.

The period of a 60 Hertz sine wave is 16,667 usec, so the difference between your max value and min value for any given 16,667 usec period's worth of samples is your p-p Voltage for that period.  You can average those over time to get a less instantaneous p-p Voltage.  Before considering p-p or RMS calculations, you must first computing the secondary Voltage corresponding to the integer sample acquired in the analogRead.

Substitution and calculation in mV instead of Volts yields this.

    mv_secondary = (5000 X s_in / 1024 - 2500) X (110000 / 10000)

Translating into C, which will be interpreted correctly within an Ino sketch, and using a simplified expression and long integers to achieve reasonable computational speed and accuracy [4] you get this.

    int s_in = analogRead(input_pin);
    unsigned long microsecs = micros();
    unsigned long mv_secondary = 53711L * s_in / 1000 - 27500;

The v,t (secondary Voltage, time) vector is now in the variables mv_secondary and microsecs respectively.  Then calculate the delta time and find the product to sum.

    unsigned long nano_volt_second = mv_secondary * u_sec_delta;

**System Design Considerations**

In designing the system, it is often better to delegate the conversion to physical units and the Gaussian approximation of an integral to another part of the system (as in the case of when the embedded program is doing data acquisition but not control) or not do it at all (as in the case when control is in the same board as the data acquisition and the PID parameters superseded the need to translate the integers from readAnalog to physical units altogether).

To achieve the higher loop speed when using USB transfer of the values, one can USB transfer the return values of the analogRead more directly as two byte pairs and perform calculations on the USB peer computer (workstation or other computing hardware).  Conversion of integers of any type to strings slows a data acquisition loop down considerably, and should be avoided.

Hardware triggering of the ADC subsystem of the Atmel chip can also increase speed, especially if the analogRead function is bypassed by a lower level implementation of the register reading.  At sampling speeds above 200KHz, completely within the capability of the Arduino Due, every usec counts.

**Ambiguous Intent Reference to Integration**

The summing of products isn't actually integration, which is a symbolic operation, not a calculation.  The example reference given does a Gaussian discrete approximation of an integral.  The reason for seeking that approximation is not given.

The result of such a calculation would be the product of the time over which the approximation is made and the offset, which would naturally be zero except for any calibration error and low frequency noise in the secondary winding's circuit.

If the intention is to calculate Voltage RMS, there is another real time methodology for that.  If you want the average p-p Voltage, there's another (partly described above) for that.  If you want to track spikes on the line, then you probably want a circuit with over-Voltage protection and a different algorithm.

**Usefulness of Optimized Math**

The use of unsigned long for optimization may not be necessary for low frequency applications [5], but any system that needs to meet the Nyquist criterion for audio will require a sample rate where the fixed point simulation may cause a statistically significant number of delays over the time of sampling.

Even if the speed is not needed, exceeding the Niquest criteria permits gaining extra bits of accuracy if windowing is used during data reduction.

**References**

[1] Atmel 2560 cpu spec sheet @ http://www.atmel.com/Images/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf

[2] Mega 2560 schematic @ https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf

[3] A Voltage waveform from a power grid is rarely if ever a perfect sine wave.

[4] Arduino use of long integer constants as in C/C++ discussion @ https://www.arduino.cc/en/Reference/IntegerConstants

[5] The maximum Δt before the unsigned long product overflows is given by `floor ((2^32 - 1) / (53,711 x 1023 / 1000 - 27,500)) = 156,485 usec, corresponding to a 6.39 Hz sample rate.


body:
I'm trying to read the analog value of the light sensor and print its percentage but for unknown reasons I'm getting negative values when I'm printing the value.

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

    void loop() {

      // Let's say 1002 is the analogValue
      int analogValue = (int) analogRead(0);

      // get the percentage
      int value = 100 * analogValue / 1023;

      Serial.println("~~~~~~~~~~~~~~~~~~~~~~~~~");
      Serial.println(analogValue); // print the analog value 0...1023
      Serial.println(100 * analogValue); // just for test
      Serial.println(value); // The percentage
      Serial.println("~~~~~~~~~~~~~~~~~~~~~~~~~");

      delay(500);
    }

I don't know what's going in background, but I'm getting negative values when I try to print the percentage:

    ~~~~~~~~~~~~~~~~~~~~~~~~~
    1002
    -30772
    -30
    ~~~~~~~~~~~~~~~~~~~~~~~~~

title: Read from analog then cast not showing the correct value

Answers: 1

body: Max value for `int` is 32,767. But 100 * 1002 = 100,200. You are overflowing the `int`. Use `unsigned long`. Or `float` and cast to `int` when printing.


body:
The Arduino/Genuino Micro has RX/TX pins and can do serial via USB.

But, Arduinos `Serial` ties them both together, so when using `Serial.begin(9600)` to send messages between my PC and the Arduino, I cannot use the RX/TX pins as GPIOs.

From what I can tell reading the Atmega32u4s [Datasheet][1], the USART module on the chip is completely separate from the USB controller, so it should be possible to somehow disable the USART Transceiver and Receiver after executing `Serial.begin(9600)`.

Is there something fundamental preventing me from doing this or can it be done? If it can, how would I do it?

  [1]: http://file:///G:/Users/Felix/Source/Repos/Cases/PwrButton/Datasheets/ATmega16U4-32U4.pdf

title: Stopping Serial on RX/TX pins while running Serial on USB

Answers: 2

body:
There is no real reason why it should be tied somehow. And running simple test program seconds that:

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

    void setup() {
      pinMode(0, OUTPUT);
      pinMode(1, OUTPUT);
      Serial.begin(9600);
    }

    void loop() {
      digitalWrite(0, LOW);
      delay(400);
      digitalWrite(0, HIGH);
      digitalWrite(1, LOW);
      delay(1000);
      digitalWrite(1, HIGH);
      Serial.println("something");
    }

LEDs on TX and RX pins blinks and USB Serial is sending the message (Genuine Arduino Micro, Arduino IDE 1.8.1)

body:
The Serial and Serial1 are two seperated ports. They are not connected. The Serial is the USB serial and does not use pin 0 and 1 at all. The Serial1 is the hardware serial port at pin 0 and 1, but if Serial1 is not used then pin 0 and 1 are normal digital pins that you can use.

Don't be confused by the text labels printed on the board. Pin TX (also called TX1) is D1 and pin RX (also called RX1) is D0.
This is the pinmapping for the Micro: [PighiXXX - Micro][1].

The Arduino Zero uses 'SerialUSB' to indicate the serial port via USB. You can do the same for the Leonardo and the Micro and use the alias 'SerialUSB' in your sketch instead of 'Serial'.
I found it more convenient to use 'SerialUSB' in my sketch, but not many people use it.
The Serial port at pin 0 and 1 is still called 'Serial1'.

  [1]: http://www.pighixxx.com/test/portfolio-items/micro/


body:
I've seen some projects using PWM for playing audio files, and it seems like it needs an amplifier, otherwise the sound is very low.

I already made a project using a DFPlayer and [PAM8403][1], but now I need more control over the files in the SD Card which is not supported by the DFPlayer library, so it seems like I need to use PWM and a SD Card module, instead of a separate audio module.

My questions are, can I simply connect the PWM output to the amplifier (PAM8403) and I will be able to control volume (using the programming language) and have a good quality sound?

  [1]: http://www.allelectronics.com/mas_assets/theme/allelectronics/spec/AMP-8403.pdf

title: Is it possible to use Arduino PWM for audio within a PAM8493 amplifier?

Answers: 1

body:
Are you using a basic Arduino board (not I2S) and a sampling frequency of 8 kHz or 16 kHz? That could interfere with the default switching frequency of 260 kHz.

My suggestion is to use a low pass RC filter.
You might have to lower the signal level from the Arduino.
The PAM8403 requires a series capacitor and resistor at the input (those are probably already on the amplifier module).
In the end you probably need a voltage divider with a capacitor to ground for each channel.

I don't know if your PWM library has volume control. The TMRh20 has a function to set the volume.

The overall quality will be reasonable, but not very good. There are MP3 shields that can play mp3 files from a SD memory card. Those have better quality.

[**ADDED**]
I think I have misunderstood your question. Sorry. I'm still not sure that I understand your question now.

Wiki of DFPlayer Mini: [DFRobot:DFPlayer Mini][1]
Code on Github for DFPlayer Mini: [Github:DFPlayer Mini][2]
The PAM8403 has no volume control, you need to adjust the audio signal that is going to the PAM8403 module.
The DFPlayer Mini code has functions for volume, volumeUp, volumeDown and readVolume. However, it does not seem to have a function to select a specific file.

The Adafruit Music Maker shield is in two versions, one has an amplifier onboard: [Adafruit:Music Maker MP3 Shield for Arduino w/3W Stereo Amp - v1.0][3]. With that shield, you can play a file by its name. It can also set the volume. I suppose that is what you want ?

  [1]: https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299
  [2]: https://github.com/DFRobot/DFRobotDFPlayerMini
  [3]: https://www.adafruit.com/product/1788


body:
So, I downloaded tools for my ESP8266 using this link:
<http://arduino.esp8266.com/stable/package_esp8266com_index.json>

I installed the last version in my motherboard manager (2.3.0) and tried to execute my first example ("Blink"), but here is what I get :

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

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

What can I do to prevent this?

P.S My ESP8266 is connected to an Arduino Mega

title: error: espcomm_upload_mem failed ESP8266

Answers: 1

body:
The reason why this error comes up is because the programmer cannot communicate with the bootloader of the ESP.
The link you mentioned in the comments misses a very important step, which is to remove the ATmega chip already on the Uno board. Otherwise the programmer will see corrupt data due to 2 bootloaders on the same UART lines.
Remember that only one device can communicate on the UART lines.
The Mega board has the ATmega chip soldered to the board, so you don't have much hopes of isolating the UART lines.
Another thing to remember is to always reset the ESP into flash mode (reset the ESP with GPIO_0 pulled low).

If you still want to use the ESP with the Mega board, go through the Multi Serial examples given in the IDE. The concept requires making two GPIO lines communicate with the ESP, while the original Serial lines to the programmer (the computer).
All data sent via ESP is routed to Mega's serial lines and vice versa.


body:
I am trying to use D0/D1 as normal IO pins but DigitalWrite does not work as on an Arduino UNO.

I know the SAMD21G has SERCOM but I can't seem to find an example of not using D0/D1 as an UART port.

EDIT ** **Code I have tried:**

    #define MYMASK 0x00000C00
    void setup() {
      REG_PORT_DIRSET0 = MYMASK; // Direction set to OUTPUT
      REG_PORT_OUTSET0 = MYMASK; // set state of pin(s) to TRUE (HIGH)
      delay(1000);
      REG_PORT_OUTCLR0 = MYMASK; // set state of pin(s) to FALSE (LOW)
    }

    void loop() {
    }

title: Arduino Zero D0/D1 set output high

Answers: 1

body:
You can do this by simply calling the right registers:

Example 1, using a MASK

D0/D1 are mapped to to PA10 & PA11 on the M0

    /* The following ports where selected
     PORT_PA11
     PORT_PA10
     */
    #define MYMASK 0x00000C00

    int main (void)
    {
     system_init();

     REG_PORT_DIRSET0 = MYMASK; // Direction set to OUTPUT
     REG_PORT_OUTSET0 = MYMASK; // set state of pin(s) to TRUE (HIGH)
     //REG_PORT_OUTCLR0 = MYMASK; // set state of pin(s) to FALSE (LOW)

     while(1){

     }
    }

Here is another simple example:

    /* The following ports where selected
     PORT_PA11
     PORT_PA10
     */
    #define MYMASK 0x00000C00
    #define LED1 PORT_PA10
    #define LED2 PORT_PA11
    int main (void)
    {
     system_init();

     REG_PORT_DIRSET0 = LED1 | LED2; // Direction set to OUTPUT
     REG_PORT_OUTSET0 = LED1 | LED2; // set state of pin(s) to TRUE (HIGH)
     //REG_PORT_OUTCLR0 = LED1 | LED2; // set state of pin(s) to FALSE (LOW)
     while(1){

     }
    }

In the Arduino IDE you can do something like:

    #define MYMASK 0x00000C00
    void setup() {
      REG_PORT_DIRSET0 = MYMASK; // Direction set to OUTPUT
    }

    void loop() {
       REG_PORT_OUTSET0 = MYMASK; // set state of pin(s) to TRUE (HIGH)
       delay(1000);
       REG_PORT_OUTCLR0 = MYMASK; // set state of pin(s) to FALSE (LOW)
       delay(1000);
    }


body:
I have a Uno program and I can transfer data to Processing using println. In Processing bufferUntil('\n') interprets the ln  as \n, stops buffering, and reads the string until the next '\n'. I would like to use something other than ln to trigger Processing. That way I can use Serial Monitor in the Uno to see serial data when Processing is not running at the same time.

I have searched the net but have not found the technique to use something other than ln. Thanks.

title: Passing serial data to Processing using something other than ln to trigger Processing

Answers: 1

body:
If I understand your question (which is not certain):

 - Pick a different "trigger" byte that you won't be sending in your messages.  Maybe *TAB*?
 - In your "Processing" program, use: `port.bufferUntil(TRIGGER);`
 - In your Arduino sketch, rather than *println*, use *print* to send both your data and the trigger byte:  `Serial.print(your_message); Serial.print(TRIGGER);`

Note that sending binary data will cause this to fail when the data uses the trigger byte.

*From: [https://www.arduino.cc/en/Serial/Println][1] The **println()**
   method sends your output then a CR and NL.  And it seems **bufferUntil()** takes a character on which to trigger:
[https://processing.org/reference/libraries/serial/Serial_bufferUntil_.html][2]*

  [1]: https://www.arduino.cc/en/Serial/Println
  [2]: https://processing.org/reference/libraries/serial/Serial_bufferUntil_.html


body:
I am trying to read some resistive buttons presses on a PCB like this:

[![game gear buttons PCB][1]][1]

This is the full sketch I am using:

    #include <Keyboard.h>

    byte ZbuttonPin = 3;

    void setup() {
     // initialize the button-reading pins
      pinMode(ZbuttonPin, INPUT_PULLUP);
    }

    void loop() {
      if (digitalRead(ZbuttonPin) == 0) {
        // if the button goes low
        Keyboard.write('z'); // send a 'z' to the computer via Keyboard HID
        delay(100); // delay so there aren't a kajillion z's
      }
    }

If I short the Arduino pin 3 and GND directly it outputs the "z" letter correctly.

But when I connect M16 and GND on the PCB it outputs "z" continuously even if the button if not pressed with the rubber pad.

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

title: How to read resistive buttons with Arduino Pro Micro?

Answers: 0


body:
I am running a setup of two NRF24L01P's on homemade code where the TX sends an analog signal fed through a standard pot, and the RX simply prints out the signal. But the RX seems to be getting incorrect data, meaning that where the centre value on TX side is 670, the centre value on RX side is 180. Why is this happening? I have auto acknowledgement, and dynamic payload enabled. I also tried setting 250KBPS and 2000KBPS with the max power setting, and still the results dont change. Is this because of loss of power in the wireless communication? Will a voltage follower be needed?

Function definitions in code:

    /* CONNECTIONS
     * NRF    ARDUINO
     * GND    GND
     * VCC    VCC
     * CE     D7
     * CSN    D8
     * MOSI   D11
     * SCK    D13
     * MISO ``D12
     * IRQ    D2*/

     #include <SPI.h>
     #define CE_PIN 7
     #define CSN_PIN 8
     #define MOSI_PIN 11
     #define SCK_PIN 13
     #define MISO_PIN 12
     #define W_REGISTER B00100000
     #define R_RX_PAYLOAD B01100001
     #define W_TX_PAYLOAD B10100000
     #define FLUSH_TX B11100001
     #define FLUSH_RX B11100010
     #define RF_SETUP 0x06
     #define RF_DR_LOW 5
     #define RF_DR_HIGH 3
     #define RF_CH 0x05
     #define EN_RXADDR 0x02
     #define ERX_P0 0
     #define SETUP_AW 0x03
     #define RX_ADDR_P0 0x0A
     #define FEATURE 0x1D
     #define EN_DPL 2
     #define EN_AA 0x01
     #define CONFIG 0x00
     #define PWR_UP 1
     #define PRIM_RX 0
     #define MASK_RX_DR 6
     #define MASK_TX_DS 5
     #define MASK_MAX_RT 4
     #define EN_CRC 3
     #define CRCO 2
     #define STATUS 0x07
     #define RX_DR 6
     #define TX_DS 5
     #define MAX_RT 4
     #define NOP B11111111
     #define TX_ADDR 0x10
     #define DYNPD 0x1C

     byte data_buff;
     int address = 123;
     byte data_recieve;

    //******************************** write a byte to a regster *******************************
    void writeRegister(byte reg_address, byte data)
    {
      bitClear(PORTB, 0);
      SPI.transfer(W_REGISTER | reg_address);
      SPI.transfer(data);
      bitSet(PORTB, 0);
    }

    //******************************* set the air data rate *******************************
    void setAirDataRate(int air_data_rate)
    {
      switch(air_data_rate)
      {

        case 250:
         setRegisterBit(RF_SETUP, RF_DR_LOW, 1);
         setRegisterBit(RF_SETUP, RF_DR_HIGH, 0);
         break;

        case 1000:
         setRegisterBit(RF_SETUP, RF_DR_LOW, 0);
         setRegisterBit(RF_SETUP, RF_DR_HIGH, 0);
         break;

        case 2000:
          setRegisterBit(RF_SETUP, RF_DR_LOW, 0);
          setRegisterBit(RF_SETUP, RF_DR_HIGH, 1);
          break;

        default:
          Serial.println("WRONG AIR DATA RATE ENTERED!");
          break;
      }
    }

    void setRegisterBit(byte reg_address, byte bit_add, byte bit_val)
    {
      getRegisterStat(reg_address);

      if(bit_val == 1)
      {
        bitSet(data_buff, bit_add);
      }

      else
      {
        bitClear(data_buff, bit_add);
      }

      bitClear(PORTB, 0);
      SPI.transfer(W_REGISTER | reg_address);
      SPI.transfer(data_buff);
      bitSet(PORTB, 0);

      Serial.print(bit_add);
      Serial.print(" bit set to ");
      Serial.print(bit_val);
      Serial.print(" in register ");
      Serial.println(reg_address);
    }

    void getRegisterStat(byte reg_address)
    {
      bitClear(PORTB, 0);
      SPI.transfer(reg_address);
      data_buff = SPI.transfer(0);
      bitSet(PORTB, 0);
    }

    void enableDPL( int pipe_number)
    {
      setRegisterBit(FEATURE, EN_DPL, 1); //enable dpl by EN_DPL = 1
      setRegisterBit(DYNPD, pipe_number, 1); //DPL_Px = 1
    }

    void openReadingPipe()
    {
      setRegisterBit(EN_RXADDR, 0, 1); //ERX_P0 = 1
      writeRegister(RX_ADDR_P0, address);//set address for datapipe
      Serial.print("Data Pipe open with address:  ");
      Serial.println(address);
    }

    void openWritingPipe()
    {
      setRegisterBit(EN_RXADDR, 0, 1); //ERX_Px = 1
      writeRegister(TX_ADDR, address);//set address for datapipe
      writeRegister(RX_ADDR_P0, address);
    }

    //******************************* set the frequency *******************************
    void setChannelFreq(int frequency)
    {
      int  frequency_val = frequency - 2400;
      if(frequency_val <= 125 && frequency_val > 0)
      {
        writeRegister(RF_CH, frequency_val);
      }

      else
        Serial.println("WRONG FREQUENCY VALUE ENTERED!");
    }

    //******************************* print the status of the register *******************************
    void printRegStatus(byte reg_address)
    {
      getRegisterStat(reg_address);

      switch(reg_address)
      {
        case RF_SETUP:
        bitRead(data_buff, 3) ? Serial.println("AIR DATA RATE SET TO 2000KBPS") : bitRead(data_buff, 5) ? Serial.println("AIR DATA RATE SET TO 250KBPS") : Serial.println("AIR DATA RATE SET TO 1000KBPS");
        break;

        case EN_RXADDR:
        bitRead(data_buff, 0) ? Serial.print("Data Pipe 0 open with address:  ") : Serial.print("Data Pipe 0 not open with address:  ");
        Serial.println(address);
        break;

        case RF_CH:
        Serial.print("The set frequency is:");
        Serial.println(2400 + data_buff);
        break;

        case CONFIG:
        bitRead(data_buff, MASK_RX_DR) ? Serial.println("RX_DR interrupt not reflected on IRQ") : Serial.println("RX_DR interrupt is active low on IRQ");
        bitRead(data_buff, MASK_TX_DS) ? Serial.println("TX_DS interrupt not reflected on IRQ") : Serial.println("TX_DS interrupt is active low on IRQ");
        bitRead(data_buff, MASK_MAX_RT) ? Serial.println("MAX_RT interrupt not reflected on IRQ") : Serial.println("MAX_RT interrupt is active low on IRQ");
        bitRead(data_buff, EN_CRC) ? Serial.println("CRC is Enabled!") : Serial.println("CRC is diabled!");
        bitRead(data_buff, CRCO) ? Serial.println("CRC is 2 bytes.") : Serial.println("CRC is 1 byte.");
        break;

         case EN_AA:
        bitRead(data_buff, 0) ? Serial.println("ENABLE AUTO ACK ON PIPE 0") : Serial.println("AUTO ACK NOT ENABLED");
        break;

        case FEATURE:
        bitRead(data_buff, EN_DPL) ? Serial.println("DYNAMIC PAYLOAD LENGTH ENABLED") : Serial.println("DYNAMIC PAYLOAD LENGTH NOT ENABLED!");
        break;

        case DYNPD:
        bitRead(data_buff, 0) ? Serial.println("DYNAMIC PAYLOAD ON DATA PIPE 0 ENABLED!") : Serial.println("DYNAMIC PAYLOAD NOT ENABLED IN DATA PIPE!");
        break;

        case TX_ADDR:
        Serial.print("ADDRESS: ");Serial.println(data_buff);
        break;

        case RX_ADDR_P0:
        Serial.print("ADDRESS: ");Serial.println(data_buff);
        break;

        case SETUP_AW:
        if(bitRead(data_buff, 1) == 0 && bitRead(data_buff, 0 == 1))
        Serial.println("ADDRESS WIDTH 3 BYTES!");
        break;

      }
    }

    //******************************* set the address width *******************************
    void setAddressWidth(byte address_width)
    {
      switch(address_width)
      {
        //addres width is 3 bytes
        case 3:
        setRegisterBit(SETUP_AW, 0, 1);
        setRegisterBit(SETUP_AW, 1, 0);
        break;

        //address width is 4 bytes
        case 4:
        setRegisterBit(SETUP_AW, 0, 0);
        setRegisterBit(SETUP_AW, 1, 1);
        break;

        //address width is 5 bytes
        case 5:
        setRegisterBit(SETUP_AW, 0, 1);
        setRegisterBit(SETUP_AW, 1, 1);
        break;

        default:
        Serial.println("WRONG ADDRESS WIDTH ENTERED!");
        break;
      }
    }

    //******************************** enable auto acknowledgment *******************************
    void enableAutoACK()
    {
      setRegisterBit(EN_AA, 0, 1);
    }

    //******************************** enable auto acknowledgment *******************************
    void clearInterrupts()
    {
      setRegisterBit(STATUS, RX_DR, 1);
      setRegisterBit(STATUS, TX_DS, 1);
      setRegisterBit(STATUS, MAX_RT, 1);
    }

    void confirmTransmit()
    {
      Serial.print("PACKET SENT SUCCESSFULLY!!");
      setRegisterBit(STATUS, TX_DS, 1);

    }

    void setupRadio(int air_data_rate, int frequency, byte address_width)  //air data rate in kbps, frequency in MHz, address width in bytes
    {

      DDRB = B00101001;
      DDRD = B10000000;
      Serial.begin(115200);
      SPI.begin();
      //set air data rate
      setAirDataRate(air_data_rate);

      //set frequency
      setChannelFreq(frequency);

      //set address width
      setAddressWidth(address_width);

      //flush the rx and tx fifo
      bitClear(PORTB, 0);
      SPI.transfer(FLUSH_RX);
      bitSet(PORTB, 0);

      bitClear(PORTB, 0);
      SPI.transfer(FLUSH_TX);
      bitSet(PORTB, 0);

      //enable dpl
      enableDPL(0);

      //enable CRC
      setRegisterBit(CONFIG, EN_CRC, 1);
      setRegisterBit(CONFIG, CRCO, 0);

      bitClear(PORTD, 7); //set CE low
      bitSet(PORTB, 0);// keep CSN high
    }

    //******************************** setup the RX *******************************
    void setupRX()
    {
        //open up the pipe for transmission
        openReadingPipe();

        //mask tx and max rt IRQ
        setRegisterBit(CONFIG, MASK_MAX_RT, 1);
        setRegisterBit(CONFIG, MASK_TX_DS, 1);

        //power up module
        setRegisterBit(CONFIG, PWR_UP, 1);

        //Tpd2stby delay
        delay(5);

        attachInterrupt(digitalPinToInterrupt(2), recieveData, FALLING);

        //clear any interrupt flag
        clearInterrupts();

        //set PRIM_RX bit
        setRegisterBit(CONFIG, PRIM_RX, 1);
        bitSet(PORTD, 7); //set CE high
        delay(1);
    }

    //******************************** setup the TX *******************************
    void setupTX()
    {
      openWritingPipe();
      setRegisterBit(CONFIG, PRIM_RX, 0);

      //mask rx and max rt interrupt
      setRegisterBit(CONFIG, MASK_RX_DR, 1);
      setRegisterBit(CONFIG, MASK_MAX_RT, 1);

      //enable autoACK
      enableAutoACK();

      setRegisterBit(RF_SETUP, 2, 1);
      setRegisterBit(RF_SETUP, 1, 1);
      setRegisterBit(CONFIG, PWR_UP, 1);

      delay(5);

      attachInterrupt(digitalPinToInterrupt(3), confirmTransmit, FALLING);

      clearInterrupts();
      delay(1);
    }

    //******************************** read data from RX FIFO *******************************
    void recieveData()
    {
      Serial.println("RECIEVE ISR BEGUN");

      bitClear(PORTD, 7); //set CE_PIN low
      delayMicroseconds(100);

      bitClear(PORTB, 0);
      SPI.transfer(R_RX_PAYLOAD);
      data_recieve = SPI.transfer(NOP);
      bitSet(PORTB, 0);

      bitClear(PORTB, 0);
      SPI.transfer(RPD);
      data_buff = SPI.transfer(NOP);
      delay(1);
      bitSet(PORTB, 1);

      bitRead(data_buff, 0) ? Serial.println("THERE IS ENOUGH POWER!") :
      Serial.println("THERE IS NOT ENOUGH POWER!");

      delayMicroseconds(15000);
      setRegisterBit(STATUS, RX_DR, 1);

      bitSet(PORTD, 7);
      delayMicroseconds(100);

      Serial.print("THROTTLE :");
      Serial.println(data_recieve);
     }
    //******************************** write data to be transmitted *******************************
    void transmitData(byte data)
    {
      bitClear(PORTB, 0);
      SPI.transfer(FLUSH_TX);
      bitSet(PORTB, 0);

      bitClear(PORTB, 0);
      SPI.transfer(W_TX_PAYLOAD);
      SPI.transfer(data);
      bitSet(PORTB, 0);

      bitSet(PORTD, 7);
      delayMicroseconds(1000);
      bitClear(PORTD, 7);

      delayMicroseconds(130);

      /*bitClear(PORTB, 0);
      SPI.transfer(0x17);
      data_buff = SPI.transfer(NOP);
      bitSet(PORTB, 0);
      bitRead(data_buff, 4) ? Serial.println("TX FIFO EMPTY!") :
      Serial.println("DATA IN TX FIFO");*/
    }

The RX code (all function definitions are same obviously):

    void setup(){
      setupRadio(1000, 2515, 3);
      setupRX();
     /*printRegStatus(CONFIG);
     printRegStatus(TX_ADDR);
     printRegStatus(RX_ADDR_P0);
     printRegStatus(EN_AA);
     printRegStatus(RF_CH);
     printRegStatus(FEATURE);
     printRegStatus(RF_SETUP);
     printRegStatus(SETUP_AW);*/

    }

    void loop(){

     delay(1000);
    }

The TX code (all function definitions are same obviously):

    void setup(){
          setupRadio(1000, 2515, 3);
          setupTX();
         /*printRegStatus(CONFIG);
         printRegStatus(TX_ADDR);
         printRegStatus(RX_ADDR_P0);
         printRegStatus(EN_AA);
         printRegStatus(RF_CH);
         printRegStatus(FEATURE);
         printRegStatus(RF_SETUP);
         printRegStatus(SETUP_AW);
         printRegStatus(DYNPD);*/

        }

        void loop(){
         int throttle_raw = sqrt(pow(analogRead(A2), 2) + pow(analogRead(A3), 2));
          transmitData(throttle_raw);
          Serial.println(throttle_raw);
          delay(1000);
        }

title: Incorrect data being received on RX of NRF24L01P

Answers: 1

body:
Your new TX function:

    void transmitData(byte * data, byte len)
    {
      bitClear(PORTB, 0);
      SPI.transfer(FLUSH_TX);
      bitSet(PORTB, 0);

      bitClear(PORTB, 0);
      SPI.transfer(W_TX_PAYLOAD);

      len = min(len, 32); // since 32 is max size
      for (int i = 0; i < len; i++)
        SPI.transfer(*data++);
      bitSet(PORTB, 0);

      bitSet(PORTD, 7);
      delayMicroseconds(1000);
      bitClear(PORTD, 7);

      delayMicroseconds(130);

      /*bitClear(PORTB, 0);
      SPI.transfer(0x17);
      data_buff = SPI.transfer(NOP);
      bitSet(PORTB, 0);
      bitRead(data_buff, 4) ? Serial.println("TX FIFO EMPTY!") :
      Serial.println("DATA IN TX FIFO");*/
    }

To receive data with dynamic payloads enabled, you need to know the size of the incoming payload before you read. Study `getDynamicPayloadSize()` in the RF24 library and pass the value returned as the second argument to the RX function below. Your new RX function should look like this:

    void recieveData(byte * data, byte len)
    {
      Serial.println("RECIEVE ISR BEGUN");

      bitClear(PORTD, 7); //set CE_PIN low
      delayMicroseconds(100);

      bitClear(PORTB, 0);
      SPI.transfer(R_RX_PAYLOAD);
      for (int i = 0; i < len; i++){
        *data = SPI.transfer(0xff); data++;
      }
      bitSet(PORTB, 0);

      bitClear(PORTB, 0);
      SPI.transfer(RPD);
      data_buff = SPI.transfer(NOP);
      delay(1);
      bitSet(PORTB, 1);

      bitRead(data_buff, 0) ? Serial.println("THERE IS ENOUGH POWER!") :
      Serial.println("THERE IS NOT ENOUGH POWER!");

      delayMicroseconds(15000);
      setRegisterBit(STATUS, RX_DR, 1);

      bitSet(PORTD, 7);
      delayMicroseconds(100);
     }

In both functions, you pass in buffers to hold the data you want to send or receive. In your case, since you're sending `int`s, a call like this `transmitData(&throttle, 2)` should do. Since you already know the size of what you're sending, you can simply pass 2 as length to `receiveData()` and skip querying the payload size like this `receiveData(&throttle, 2)`. Casting will be done implicitly.

If, in fact, `receiveData` is an ISR like your comments say (maybe you're using some IRQ pin), you'll have to split it in two; one part to handle the interrupt quickly by setting an `available` flag or something (obviously taking no arguments) to be polled in `loop()` and another to actually `read` the data. Or you can just setup the buffer as a global thing and hard-code a 2-byte read in the ISR. Though I have to say your maybe-ISR is terrible, what with huge delays and prints everywhere and I don't know how it manages to work at all.

Basically, if you want to understand the chip, it doesn't hurt to look at existing code to understand the 'right' way to do stuff.


body:
I'm trying to use NeoPixel on the ESP8266.
I made simple test put all required code into `setup()` and `loop()` methods. Then, to keep everything in order I create a class `LedModule` which handle the led strip state, changes, etc.

Here some parts of my class

    LedModule::LedModule(unsigned int numOfPixels, uint8_t dataPin)
    {
     // When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
     // Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
     // example for more information on possible values.
     pixels = Adafruit_NeoPixel(numOfPixels, dataPin, NEO_GRB + NEO_KHZ800);

     mState = LED_MODULE_STATE_IDLE;
     mIsLedStripOn = false;
    }

    ...

    // The method to set all leds of the strip to the same color
    void LedModule::turnAllNeoPixelsTo(uint8_t red, uint8_t green, uint8_t blue)
    {
     for (uint16_t i = 0; i < getLedCount(); i++)
     {
      // Avoid to light up the middle leds
      if (i < 5 || i > 9)
      {
       pixels.setPixelColor(i, red, green, blue);
      }
      else{
       pixels.setPixelColor(i, 0,0,0); // off
      }
     }
     pixels.show(); // This sends the updated pixel color to the hardware.
     mIsLedStripOn = true;
    }

After this changes, when I call the method above, I got the exception:

    Exception 29: StoreProhibited: A store referenced a page mapped with an attribute that does not permit stores
    Decoding 15 results
    0x4020ddbd: ieee80211_send_mgmt at ?? line ?
    0x4020db5f: ieee80211_send_mgmt at ?? line ?
    0x40102864: trc_NeedRTS at ?? line ?
    0x4020fe6d: ieee80211_sta_new_state at ?? line ?
    0x402101ab: ieee80211_sta_new_state at ?? line ?
    0x4021060f: sta_input at ?? line ?
    0x402109cb: ieee80211_parse_wmeparams at ?? line ?
    0x402103ab: sta_input at ?? line ?
    0x40204ce3: pp_tx_idle_timeout at ?? line ?
    0x40204607: ppPeocessRxPktHdr at ?? line ?

It seems to crash during the `pixels.setPixelColor(i, red, green, blue);` method.

title: ESP8266 + NeoPixel - Cannot set pixel color, I got "Exception 29: StoreProhibited"

Answers: 1

body:
Your "constructor" isn't doing what you think.

In the example you point to you have, efectively:

    Class object = Class(parameters);

Whereas in your code you have:

    Class object;

    object = Class(parameters);

In the first form it results in a new `object` constructed at declaration time. In the second it first creates a new "empty" object and then at a later date tries to copy a newly constructed object into it - which may be failing if the class doesn't support copying.

Instead you should be working with `new` and pointers.

In your class definition you create a pointer to your Adafruit class:

    private:
        Adafruit_NeoPixel *pixels;

Then you create a `new` object pointing to it:

    pixels = new Adafruit_NeoPixel(numOfPixels, dataPin, NEO_GRB + NEO_KHZ800);

Accessing it is then done with `->` instead of `.`:

    pixels->setPixelColor(i, red, green, blue);


body:
I have made a very basic test circuit for the opto coupler H11L1 ('similar'datasheet: http://www.datasheet4u.com/datasheet/H/1/1/H11L1_MotorolaInc.pdf.html))

I use the test circuit:

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

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

<!-- End schematic -->

[![Circuit][1]][1]

The LED and 470 ohm resistor is only for testing.
U1 is the Arduino (software serial pin 9/11) and U2 is the H11L1.

The LED is flashing similar to the RX led on the Arduino.

Also I tested before in an even simpler circuit that the signals from the H11L1 pass through pin 4 (although inverted, which seems to be normal).

However, I don't receive any data in the Arduino (I tried different Arduinos, different speeds, different H11L1).

The data I receive from the (hardware) serial/debug terminal:

    0
    0
    0
    0

etc.

My sketch:

    #include <SoftwareSerial.h>

    SoftwareSerial mySerial(9, 11); // RX, TX

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

    void loop()
    {
        mySerial.write('A');
        while (mySerial.available())
        {
            Serial.println(mySerial.read());
        }

        delay(100);
    }

How can I get the correct signal? (meaning 'A' are printed instead of 0's?

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

Update
======

New sketch (not having the duplex problem):

    #include <SoftwareSerial.h>

    SoftwareSerial mySerial(12, 13); // RX, TX

    void setup()
    {

      Serial.begin(115200);
      mySerial.begin(115200);
    }

    void loop()
    {
      Serial.print("Write: A ");
      mySerial.write('A');

      while (mySerial.available())
      {
        Serial.print((int) mySerial.read());
      }

      Serial.println("");

      delay(100);
    }

Output:

    Write: A
    Write: A
    Write: A
    Write: A

etc.

Update
========
Problem solved: I put it in an answer for clearity.

title: H11L1 opto isolator does not pass signal to Arduino (correctly)

Answers: 3

body:
Rule of thumb: never use SoftwareSerial (unless you have to, and even then you should avoid it).

The SoftwareSerial works better with higher baudrates. The lower the baudrate, the more trouble you get. Unless you aim for a high baudrate of 115200, then SoftwareSerial can cause troubles again. Remember that using SoftwareSerial means that there is not much else you can do in your sketch.

When SoftwareSerial is used with a very low baudrate of 300, then it could even disturb the receiving of data of other hardware serial ports. Because SoftwareSerial disables interrupts during transmitting and receiving, the lower the baudrate, the longer the interrupts will be disabled.

**The SoftwareSerial can not transmit and receive at the same time, and that is what you are doing.**

A Arduino Leonardo, Micro, or Arduino Mega 2560 board have unused hardware serial port(s). Use one of those to do tests with a serial port.
As soon as you start using SoftwareSerial for a test, you are actually testing the SoftwareSerial itself.

There is an alternative, the [AltSoftSerial Library][1]. it can receive and transmit at the same time. Use a baudrate that is not too high, 9600 baud should be fine.

  [1]: https://www.pjrc.com/teensy/td_libs_AltSoftSerial.html

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

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

<!-- End schematic -->

I'm not sure I can help much with the MIDI problem but I can help with the schematic. I've reorganised it for clarity. Since the opto-isolator has an open-collector output any loads it is driving should be connected to supply + rather than common.

body:
Problem solved:

I created a setup with two Arduino Uno's, one which sends the information by a hardware UART, one that receives it. The reason to do this is not to use a software serial and having no problems with the duplex. I thought I need a Mega, but with two Uno's it is also possible.

However, this did NOT solve the problem.

What solved the problem was to use TWO opto-isolators. The H11L1 inverts the signal, and it seems I had to connect the output of the first H11L1 to the input of a second and now it works.


body:
I am on my 4th failed Adafruit Circuit playground, I can usualy program them a few times, like less than 10, then they become unresponsive. no amount of reseting, rebooting, bootloader re-installations, etc seem to help.
I am using Arduino 1.8.1, on a linux platform, running on a Lenovo T510.

I have numerous other MCUs that have never failed... Im just curious why there is such a high failure rate with the circuit playgrounds I am getting.

title: Unusualy high fail rate with Adafruit Circuit playgrounds

Answers: 0


body:
I have a ATTiny85 with a standard servo motor attached to it. I would expect the following sketch to make the servo to oscillate between position 60 and 100 but instead it just to to it's limit (180) and grinds there...

Any ideas ?

    #include <avr/power.h>
    #include <Adafruit_SoftServo.h>

    Adafruit_SoftServo servo;

    #define MOTOR_PIN 0

    bool flip = true;

    void setup() {
      if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
      // Set up the interrupt that will refresh the servo for us automagically
      OCR0A = 0xAF;            // any number is OK
      TIMSK |= _BV(OCIE0A);    // Turn on the compare interrupt (below!)

      servo.attach(MOTOR_PIN);
      servo.write(90);           // Tell servo to go to position per quirk
      delay(15);
    }

    void loop() {
      if(flip) {
        servo.write(60);
        delay(150);
        !flip;
      }
      else {
        servo.write(100);
        delay(150);
        !flip;
      }

      delay(500);

    }

    // We'll take advantage of the built in millis() timer that goes off
    // to keep track of time, and refresh the servo every 20 milliseconds
    volatile uint8_t counter = 0;
    SIGNAL(TIMER0_COMPA_vect) {
      // this gets called every 2 milliseconds
      counter += 2;
      // every 20 milliseconds, refresh the servos!
      if (counter >= 20) {
        counter = 0;
        servo.refresh();
      }
    }

Thanks.

title: Servo only going one direction till it reach limit

Answers: 1

body:
`!flip` doesn't really do anything and will probably be optimized out by the compiler. You need to save the result: `flip = !flip;`

You can simplify the code a bit:

<!-- language: lang-cpp -->

    void loop() {
        if(flip) {
            servo.write(60);
        }
        else {
            servo.write(100);
        }
        flip = !flip;
        delay(650);
    }

Or, get rid of the `delay` altogether:

<!-- language: lang-cpp -->

    uint32_t last_millis = 0;
    void loop() {
        if (millis() - last_millis >= 650) {
            servo.write(flip ? 60 : 100);
            flip = !flip;
            last_millis = millis();
        }
    }


body:
I was using Arduino-Makefile to upload code to a Leonardo via its standard `make upload`. However, it became "stuck" and unresponsive, as Leonardo's sometimes do. I tried power cycling it, and unplugging the USB cable, but nothing worked. So I tried re-burning the bootloader via an AVRISP MkII programmer and the Arduino 1.8.2 IDE, but that only made things worse.

It somehow uploaded a simple "blink" program, but now the it's completely unable to be programmed via USB. When I run `make upload`, or use the Arduino IDE's "upload" button, the Leonoardo's status LED begins blinking rapidly and its `/dev/ttyACM0` device disappears permanently. I have to power-cycle it to make the device reappear, but the upload still fails, with the error:

    /usr/share/arduino/bin/ard-reset-arduino --caterina  /dev/ttyACM0
    make[1]: Leaving directory '/usr/local/myproject/main'
    make do_upload
    make[1]: Entering directory '/usr/local/myproject/main'
    /usr/share/arduino/hardware/tools/avr/bin/avrdude -v -p atmega32u4 -C /usr/share/arduino/hardware/tools/avr/etc/avrdude.conf -D -c avr109 -b 57600 -P /dev/ttyACM0 \
      -U flash:w:build-leonardo/main.hex:i

    avrdude: Version 6.3, compiled on Jan 17 2017 at 11:00:16
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "/usr/share/arduino/hardware/tools/avr/etc/avrdude.conf"
             User configuration file is "/home/chris/.avrduderc"
             User configuration file does not exist or is not a regular file, skipping

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

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

             Programmer Type : butterfly
             Description     : Atmel AppNote AVR109 Boot Loader

    Connecting to programmer: .avrdude: butterfly_recv(): programmer is not responding

    avrdude: butterfly_recv(): programmer is not responding
    avrdude: butterfly_recv(): programmer is not responding
    avrdude: butterfly_recv(): programmer is not responding
    avrdude: butterfly_recv(): programmer is not responding
    avrdude: butterfly_recv(): programmer is not responding
    Found programmer: Id = ""; type =
        Software Version = .; Hardware Version = �.
    avrdude: butterfly_recv(): programmer is not responding
    avrdude: butterfly_recv(): programmer is not responding
    avrdude: error: buffered memory access not supported. Maybe it isn't
    a butterfly/AVR109 but a AVR910 device?
    avrdude: initialization failed, rc=-1
             Double check connections and try again, or use -F to override
             this check.

    avrdude: butterfly_recv(): programmer is not responding
    avrdude: error: programmer did not respond to command: leave prog mode
    avrdude: butterfly_recv(): programmer is not responding
    avrdude: error: programmer did not respond to command: exit bootloader

If I manually run:

    /usr/share/arduino/bin/ard-reset-arduino --caterina  /dev/ttyACM0

or upload via the Arduino IDE, it makes the Leonardo disappear from USB, and blink rapidly. Pressing the reset button does nothing. I have to manually unplug its USB cable to fix it.

I can program it still using the AVRISP MkII programmer...but obviously that's a huge inconvenience since it takes about 5 minutes just to upload the sample blink sketch, and even then it requires that I first power off the Leonardo, disconnect the programmer, and then power on. For development, where I might need to make dozens of revisions, this turnout is far too slow.

Why am I unable to program the Leonardo via avrdude and USB?

title: Unable to upload code to Leonardo

Answers: 1

body:
Using some examples and similar questions, [such as this one](https://arduino.stackexchange.com/questions/8564/unable-to-flash-bootloader-on-atmega32u4-with-avr-dragon) and [this one](https://stackoverflow.com/a/5414566/247542), I fixed udev rules for the AVRISP MkII programmer, then I manually reflashed the Leonardo's bootloader with with the MkII by running:

    avrdude -c avrispmkii -p m32u4 -P usb -B 8 -u -e -U lock:w:0x3F:m -v
    avrdude -c avrispmkii -p m32u4 -P usb -v
    avrdude -c avrispmkii -p m32u4 -P usb -u -U efuse:w:0xcb:m -v
    avrdude -c avrispmkii -p m32u4 -P usb -u -U hfuse:w:0xd8:m -v
    avrdude -c avrispmkii -p m32u4 -P usb -u -U lfuse:w:0xFF:m -v
    avrdude -c avrispmkii -p m32u4 -P usb -U flash:w:/usr/share/arduino/hardware/arduino/avr/bootloaders/caterina/Leonardo-prod-firmware-2012-12-10.hex -v
    avrdude -c avrispmkii -p m32u4 -P usb -U lock:w:0x0F:m -v

I'm not sure if the first and last command to write the lock bytes were necessary, since they returned the `verification error; content mismatch` error, but they didn't seem to break anything either.

Oddly, this ran in seconds, whereas the Arduino IDE took almost 5 minutes to burn the bootloader. So I suspect there's a bug in the Arduino IDE that burns an **incorrect or corrupted bootloader**.

After running this, `ard-reset-arduino` works correctly, and `make upload` can successfully upload a sketch again.

On a side note, I'm not 100% sure if `Leonardo-prod-firmware-2012-12-10.hex` was the correct bootloader to use. Again, I just made an educated guess based on naming. I'd read that the Leonardo uses the "caterina" bootloader, and the directory `/usr/share/arduino/hardware/arduino/avr/bootloaders/caterina` contained several .hex files, only three of which contained "Leonardo" in the name:

    Caterina-Leonardo.hex
    Leonardo-prod-firmware-2012-04-26.hex
    Leonardo-prod-firmware-2012-12-10.hex

It seemed logical to not use `Leonardo-prod-firmware-2012-04-26.hex`, since that was likely an old and obsolete bootloader based on the date. That left `Caterina-Leonardo.hex` or `Leonardo-prod-firmware-2012-12-10.hex`. Unfortunately, checking the [commit logs][1] shows they're exactly the same age. In my experience, `prod` tends to mean the final or production product, so I decided to try that one first and it worked. If anyone knows what `Caterina-Leonardo.hex` is for and how it differs from the others, please tell me. I don't want to risk breaking my Leonardo again experimenting with this.

The only issue I'm having now is that after I upload my sketch, with uses ROS and about 49% of the Arduino's memory, I again can no longer upload new sketches to it. I'm assuming the sketch's use of the Serial port is somehow stopping `ard-reset-arduino` from properly resetting it`. However, I the Arduino IDE is still able to upload sketches, so as a clumsy workaround, I can use that to upload the "blink" sketch, afterwhich then I can upload my own revised sketch.

  [1]: https://github.com/arduino/Arduino/tree/master/hardware/arduino/avr/bootloaders/caterina


body:
Because I have no pins available on my [Wemos D1 mini][1], I want to drive my [Neopixel ring][2] from a [MCP23008][3] I/O expander.

I'm trying to run the 'simple' example from the Adafruit_neopixel library. How do I declare the Neopixel pin number when using say pin 0 on the MCP23008 - or is this impossible?

  [1]: https://wiki.wemos.cc/products:d1:d1_mini
  [2]: https://www.adafruit.com/category/168
  [3]: http://www.microchip.com/wwwproducts/en/MCP23008

title: Neopixels with I/O expander

Answers: 2

body:
I think you will need to write your own library.  This isn't as bad as it seems.  If the library uses analog write then it won't work, because I don't think you can do PWM with that expander.

The library writes directly to pins.  You need to intercept this behaviour and tell the library to tell the MCP230008 to write to the pin.  I haven't seen the library I question, but this should be straight forward.

If you take the existing Adafruit library and find where it writes to a pin.  Rather than calling `digitalWrite` it needs to call `expanderWrite(pin, state)`.  Every instance of `pinMode()` needs replacing with `explanderPinMode(pin, mode)` Then write yourself those two functions that use I2C/SPI to set the IOX's registers to implement what  you need.

The IO Expander is not going to be a good idea if the library requires critical accurate timing, because of the lag of telling the IOX to do things.  An alternative is to use another D1 as the IO expander.

body:
I don't think that will be an option. The NeoPixel parts need very tight control of the timing in order to work, if the pin timing is wrong by 100 us the wrong data will get latched in.

Can you move some other functions / pins onto the IO expander and then drive the neopixels directly from the processor?


body:
I'm trying to control a [Tilt pan][1] with an Arduino Uno. And the [Sunrounder servo driver][2] is used to do this, which comes with it's own capacitor out of the box.

The pan has two Servo motors, that help it face any direction.

I have set this up and even calibrated, so that I can input numbers between -90 degrees to +90 degrees horizontally, and 0 to 90 vertically. And it is working...

But the problem is that, when it is idle for too long, or when I connect it in the beginning, The tilt pan shakes intensely for about 20 to 30 seconds and turns every other direction before stabilizing to the correct point. As if it had a seizure!

When I disconnect one of the Servos, this problem solves. Two servos are connected to the first and second channel of the servo driver. So it seems that these two channels have an effect on each other.

Besides, there is not much weight on the tilt pane. And removing the weight does not seem to help.

init code:

    pwm = Adafruit_PWMServoDriver();
    pwm.begin();
    pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
    yield();

turning horizontally:

    void Platform::setHorizontal(int d){
      if(d > 90)
        d = 90;
      if(d < -90)
        d = -90;
      point->setHorizontal(d);
      d = (d * 2.555) + 70.0; // calibrating.
      pwm.setPWM(0, 0, 325 + d); // 325 = (150 + 600) / 2
    }

How can I solve this?

  [1]: https://www.amazon.de/Mini-Pan-Tilt-Set-Micro-Servos/dp/B00PY3LQ2Y/ref=pd_sbs_147_2?_encoding=UTF8&psc=1&refRID=1FVW4X2PMYE8TM55X952
  [2]: https://www.amazon.de/gp/product/B014KTSMLA/ref=pd_bxgy_107_img_2?ie=UTF8&psc=1&refRID=F2QQAD84BXAF00N0YGCX

title: Uno - PCA9685 Servos are too shaky before stabilizing - when using two channels

Answers: 1

body: Start by verifying the power supply is adequate, then go from there. If nothing else try a much bigger capacitor.