message:
Executing machine code at runtime Uno

I want to create a small single threaded os for my arduino.The first thing I want to do is to allow my arduino to read a section from flash/eeprom and execute it. I have some question regarding the memory. The microcontroller is executing one command at a time from..where? Does it directly acces the flash containing the code and take every command at a time?(that would be slow) Or does it first load the entire program into sram?(also wouldn't make sense because sram is 2k while flash is 32k). Either way,if I can find in sram /flash my code( or the header to some void) then i could jump there.Am i wrong?Is it possible(to do such os)?

Something like this:

    uint16_t addr=0x1234;
    void (*function)(void)=addr;
    function();
(or maybe with some avr like assembly code?)

body:
> The microcontroller is executing one command at a time from..where?

Flash memory directly. The AVR core can *only* execute instructions from Flash memory. It uses a two-bus system known as Harvard Architecture, where the Instruction Bus is connected to Flash and is used to execute instructions, and the Data Bus is connected to SRAM, EEPROM, all the peripherals, GPIO pins, etc.

It is possible to jump to any location in memory in a similar way as you have depicted, but in order to know where you first need to know the functions you want to call.  You can get the address of any function and assign it to a pointer, and then call that pointer as a function, but what would that achieve? You may as well just call the function directly and save time. Unless you want to store the addresses of those functions in an array or something to maybe associate them with a command to trigger the execution of that function. In which case you don't need anything "fancy", just pointers to the functions you want to use.


sender: user

message:
Multiple MFRC522 RFID reader on Uno bugs

I have a problem!

 I need to connect 5 MFRC522 readers on an Arduino Uno but it is not working !

With one or two MFRC522 modules it works, when I use three or more nothing works anymore... The serial reading is not working, nothing is read with more than 2 modules. I'm so sad. So tonight I need your help, tell me what is not working in my code or on my setup!

I first thought that it was the Arduino that was not delivering enough current to the modules (on the 3.3v line) but this does not seem to be the case. We added some external ATX PSU power, and connected grounds. Nothing changed.

So we had a look at the code and we *believe* that it is a library problem. Nobody seems to have successfully connected more than 3 MFRC522 modules. Is there really a problem in the library? How could we achieve success?

    #include <SPI.h>
    #include <MFRC522.h>
    #include <EEPROM.h>

    #define SS_PIN_1 10 // PIN SDA pour le module RFID (1)
    #define RST_PIN_1 9 // PIN RESET pour le module RFID (1)
    #define SS_PIN_2 8 // PIN SDA pour le module RFID (2)
    #define RST_PIN_2 7 // PIN RESET pour le module RFID (2)
    #define SS_PIN_3 6 // PIN SDA pour le module RFID (3)
    #define RST_PIN_3 5 // PIN RESET pour le module RFID (3)
    #define SS_PIN_4 4 // PIN SDA pour le module RFID (4)
    #define RST_PIN_4 3 // PIN RESET pour le module RFID (4)
    #define SS_PIN_5 2 // PIN SDA pour le module RFID (5)
    #define RST_PIN_5 A0 // PIN RESET pour le module RFID (5)
    #define RELAY_PIN A1 // Pin du signal du Relais
    #define RELAY_ON 1024 // Valeur de seuil d'activation du relais
    #define RELAY_OFF 0 // Valeur de seuil de désactivation du relais
    #define MASTER_BUTTON_PIN A2 // Pin du bouton d'ouverture prioritaire
    #define CONFIGURE_BUTTON_PIN A3 // Pin du bouton de reprogrammation des badges
    MFRC522 rfid1(SS_PIN_1, RST_PIN_1);
    MFRC522 rfid2(SS_PIN_2, RST_PIN_2);
    MFRC522 rfid3(SS_PIN_3, RST_PIN_3);
    MFRC522 rfid4(SS_PIN_4, RST_PIN_4);
    MFRC522 rfid5(SS_PIN_5, RST_PIN_5);
    byte tag1[4] = {0xD6, 0x92, 0xBF, 0x93};
    byte tag2[4] = {0xC6, 0xA3, 0xC0, 0x93};
    byte tag3[4] = {0x96, 0x58, 0x68, 0x8E};
    byte tag4[4] = {0x06, 0xFB, 0xC1, 0x93};
    byte tag5[4] = {0x66, 0xF3, 0x63, 0x8E};

    void setup() {
      Serial.begin(9600);
      SPI.begin();
      rfid1.PCD_Init();
      rfid2.PCD_Init();
      rfid3.PCD_Init();
      rfid4.PCD_Init();
      rfid5.PCD_Init();
      Serial.println("Initialisation du système terminé, en attente de badges...");
    }

    void activate_relay(){
      analogWrite(RELAY_PIN, RELAY_ON);
      Serial.println("Le relay est activé");
    }

    void desactivate_relay(){
      analogWrite(RELAY_PIN, RELAY_OFF);
      Serial.println("Le relay est désactivé");
    }

    void loop() {
      if (! rfid1.PICC_IsNewCardPresent()) {
        return;
      }
      if (! rfid1.PICC_ReadCardSerial()) {
        return;
      }
      if (! rfid2.PICC_IsNewCardPresent()) {
        return;
      }
      if (! rfid2.PICC_ReadCardSerial()) {
        return;
      }
       if (! rfid3.PICC_IsNewCardPresent()) {
        return;
      }
      if ( ! rfid3.PICC_ReadCardSerial()) {
        return;
      }
       if (! rfid4.PICC_IsNewCardPresent()) {
        return;
      }
      if ( ! rfid4.PICC_ReadCardSerial()) {
        return;
      }
       if (! rfid5.PICC_IsNewCardPresent()) {
        return;
      }
      if ( ! rfid5.PICC_ReadCardSerial()) {
        return;
      }
      if (rfid1.uid.uidByte[0] == tag1[0]  & rfid1.uid.uidByte[1] == tag1[1] & rfid1.uid.uidByte[2] == tag1[2] & rfid1.uid.uidByte[3] == tag1[3]) {
        if (rfid2.uid.uidByte[0] == tag2[0]  & rfid2.uid.uidByte[1] == tag2[1] & rfid2.uid.uidByte[2] == tag2[2] & rfid2.uid.uidByte[3] == tag2[3]) {
          if (rfid3.uid.uidByte[0] == tag3[0]  & rfid3.uid.uidByte[1] == tag3[1] & rfid3.uid.uidByte[2] == tag3[2] & rfid3.uid.uidByte[3] == tag3[3]) {
            if (rfid4.uid.uidByte[0] == tag4[0]  & rfid4.uid.uidByte[1] == tag4[1] & rfid4.uid.uidByte[2] == tag4[2] & rfid4.uid.uidByte[3] == tag4[3]) {
              if (rfid5.uid.uidByte[0] == tag5[0]  & rfid5.uid.uidByte[1] == tag5[1] & rfid5.uid.uidByte[2] == tag5[2] & rfid5.uid.uidByte[3] == tag5[3]) {
              } else {desactivate_relay();}
            } else {desactivate_relay();}
          } else {desactivate_relay();}
        } else {desactivate_relay();}
      } else {desactivate_relay();}
    }

I've tried the code above but it didn't work. I also tried the `ReadUidMultiReader` example code but only one reader is working. Both Readers are working individually but only one when I connect them. I shared the SCK, MISO, MOSI, RST, and have different SS pins.

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

Thank you in advance.

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

sender: assistant

body:
For convenience, here is a comment:  You wrote, “I've tried the code above but it didn't work”.   That is inadequate to convey what happened and what you wanted to happen.    Please edit your question to include a clear statement of symptoms and desired results.

Now on to an answer.

From “I'm only using 2 readers to find the correct and make it work”, I deduce that you have two readers attached.  This by itself is enough to keep the code from producing output.  Assuming those two readers identify as `rfid1` and `rfid2`, when execution gets to `if ( ! rfid3.PICC_IsNewCardPresent())`, it executes `return;` which terminates `loop()` processing.  That is, execution will never get past `if ( ! rfid3.PICC_IsNewCardPresent())`.  To clear up that problem, remove all the code that references `rfid` variables other than `rfid1` and `rfid2` (more properly, other than whichever two you have attached).

That will entail removing 18 lines in the early part of `loop()`, and three lines in the big nested-if part of `loop()`.

Here is another comment:  When you are debugging code, it makes sense to report lots of intermediate results, and to report them as soon as they are available.  Don't go through a long stack of `if` statements and get no output and then say it doesn't work; instead, display and check results when you first read them in.


body:
after around million of trying and trying I discovered that the correct way to connect 4 RFID RC522 is to put them in the same line on test board except SS pins and the code as usual is ReadUidMultiReader from RFID library ... like this :[![enter image description here][1]][1]

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


message:
what pins are attached to ethernet shield SD card?

I have ARDUINO ETH SHIELD 06 - Rev 03. https://www.adafruit.com/product/201
what pins are attached to Ethernet shield SD card?

body: Arduino communicates with both the W5100 and SD card using the SPI bus (through the ICSP header). This is on digital pins 10, 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega. On both boards, pin 10 is used to select the W5100 and pin 4 for the SD card.


message:
Recording and storing Midi data with arduino and midi shield

i need help getting started on writing a sketch that would let me record and store midi data from a midi controller connected to a arduino mega through a midi shield. are there any functions in the midi library that will aid in this task?

body:
The Arduino MIDI Library allows you to read and write MIDI messages, but only in real time.

Storing MIDI data makes sense only with timestamps, so you have to call `millis()` or `micros()` when you receive a message.

How to actually store the data is something that you have to design yourself; which data structure to use depends on what you want to do with the data later.


message:
Do I really need Ramps 1.4 for laser engraver

I'm making 2-axis laser engraver like system. Arduino waits command from pc, on receive moves laser to next coordinate and send current coordinate to pc.

I have 3 step motors and I'm controlling them with Arduino Uno which is connected to A4988 drivers which is on breadboard. But almost all samples using Ramps. Do I miss something?

body:
Ramps 1.4 is one of the proof of concept standards for 3D printer systems. It is a motherboard mostly runs Marlin firmware on it. I advice to to take a look at the firmware if you didn't yet. It is also supporting many motherboards, hardware.

When you open the `configuration.h` file in the firmware and search for this definition `#define MOTHERBOARD` you will be seeing many options available.

After all, the firmware is the key factor. It contains many engineering solutions in it. So, you shouldn't re-invent the wheel.
All you have to do is to adapt it with some tweaks as per your design specifications.

But, I would worry more about your motherboard (Arduino Uno)
if your design is relatively simple, using less memory and IO pins, it may be just fine. I would consider Mega 2560 instead If I were you.

Good luck with your project.


message:
Too low voltage on digital input on attiny45

I'm using one of my attiny's pins as digital input. I use it with a pulldown resistor. As input I use simple square wave generated by a separate waveform generator. igh state for square wave is 5V, low is 0V.

However, when I look at the voltage on the digital input, voltage of high state is below 2V, while low state is 0V. My arduino doesnt detect high state as "1".

Here is the code:

    /*
     * Sketch for testing sleep mode with wake up on WDT.
     * Donal Morrissey - 2011.
     * ATTINY85
     */

    #include <TinyWireM.h>                  // I2C Master lib for ATTinys which use USI - comment this out to use with standard arduinos
    #include <LiquidCrystal_attiny.h>          // for LCD w/ GPIO MODIFIED for the ATtiny85

    #include <avr/sleep.h>
    #include <avr/power.h>
    #include <avr/wdt.h>

    //uwaga na numer pinu! nie używać tego z resetem
    #define STATUS_PIN  1
    #define IN_PIN     4
    #define LOOP_TIME 5000
    #define TIMEOUT 100

    #define GPIO_ADDR     0x27
    LiquidCrystal_I2C lcd(GPIO_ADDR, 16, 2); // set address & 16 chars / 2 lines

    /* f_wdt is a flag used to monitor watchdog status */
    volatile int f_wdt=1;

    /***************************************************
     *  Name:        ISR(WDT_vect)
     *
     *  Returns:     Nothing.
     *
     *  Parameters:  None.
     *
     *  Description: Watchdog Interrupt Service. This
     *               is executed when watchdog timed out.
     *
     ***************************************************/
    ISR( WDT_vect){
      if(f_wdt == 0){
        f_wdt=1;
      }
      else{
      }
    }

    /***************************************************
     *  Name:        enterSleep
     *
     *  Returns:     Nothing.
     *
     *  Parameters:  None.
     *
     *  Description: Enters the arduino into sleep mode.
     *
     ***************************************************/
    void enterSleep(void)
    {
      lcd.clear();
      lcd.print("Asleep...");

      /* Enable the WD interrupt (note no reset). */
      WDTCR |= (1<<WDIE);

      set_sleep_mode( SLEEP_MODE_PWR_DOWN );   /* EDIT: could also use SLEEP_MODE_PWR_DOWN for lowest power consumption. */
      sleep_enable();
      // Status pin goes low
      digitalWrite( STATUS_PIN, LOW );
      /* Now enter sleep mode. */
      sleep_mode();

      /* The program will continue from here after the WDT timeout*/
      sleep_disable(); /* First thing to do is disable sleep. */

      // Status pin goes low
      digitalWrite( STATUS_PIN, HIGH );

      /* Re-enable the peripherals. */
      power_all_enable();

      /* Disable the WD interrupt */
      WDTCR &= ~_BV(WDIE);
    }

    /***************************************************
     *  Name:        setup
     *
     *  Returns:     Nothing.
     *
     *  Parameters:  None.
     *
     *  Description: Setup for the serial comms and the
     *                Watch dog timeout.
     *
     ***************************************************/
    void setup()
    {
      /*  Setup the LCD */
      lcd.init();                           // initialize the lcd
      lcd.backlight();                      // Print a message to the LCD.
      lcd.clear();
      lcd.setCursor(0,0);

      /* Inform the user about initialization process */
      lcd.print("Initializing...");
      delay(1000);

      /* Config pins */
      pinMode( IN_PIN, OUTPUT );
      pinMode( STATUS_PIN, OUTPUT );

      /* Initialize pins */
      digitalWrite( STATUS_PIN, HIGH );

      /*** Setup the WDT ***/

      /* Clear the reset flag of watchdog interrupts, so that they are available again. */
      MCUSR &= ~(1<<WDRF);

      /* Enable configuration changes
       */
      WDTCR |= (1<<WDCE) | (1<<WDE);

    /*
    WDP3       WDP2    WDP1     WDP0         Number of WDT     Typical Time-out at
                                             Oscillator Cycles     VCC = 5.0V
      0         0      0        0             2K (2048) cycles       16 ms
      0         0      0        1             4K (4096) cycles       32 ms
      0         0      1        0             8K (8192) cycles       64 ms
      0         0      1        1            16K (16384) cycles    0.125 s
      0         1      0        0            32K (32768) cycles    0.25 s
      0         1      0        1            64K (65536) cycles    0.5 s
      0         1      1        0            128K (131072) cycles 1.0 s
      0         1      1        1            256K (262144) cycles 2.0 s
      1         0      0        0            512K (524288) cycles 4.0 s
      1         0      0        1            1024K (1048576) cycles 8.0 s
    */
      /* set new watchdog timeout prescaler value */
      WDTCR =  0<<WDP3 | 1<<WDP2 | 1<<WDP1 | 0<<WDP0 ;

      lcd.clear();
      lcd.print("Initialisation");
      lcd.setCursor(0,1);
      lcd.print("complete.");
      delay(500);
    }

    /***************************************************
     *  Name:        enterSleep
     *
     *  Returns:     Nothing.
     *
     *  Parameters:  None.
     *
     *  Description: Main application loop.
     *
     ***************************************************/
    void loop()
    {
      if(f_wdt == 1)
      {
        lcd.clear();
        lcd.print("Awake!");
        int start = millis();
        int end = 0;
        bool movement = false;
        int read = 0;
        lcd.clear();
        lcd.print( "Executing loop" );
        do{
          if( read = digitalRead(IN_PIN) ){
            lcd.setCursor(0,1);
            lcd.print( "Read value: " );
            lcd.print( read );

            //Wait for falling edge
            while( digitalRead(IN_PIN) != 0 );
            //Start counting time
            int endMov = 0;
            int startMov = millis();
            do{
              if( digitalRead( IN_PIN ) ){
                movement = true;
              }
              endMov=millis();
            }while( endMov - startMov < TIMEOUT && !movement );
                if( endMov - startMov >=LOOP_TIME ){
                  lcd.clear();
                  lcd.print("Time is out");
                }

                else{
                  lcd.clear();
                  lcd.print("Movement detected");
                  lcd.setCursor(0,1);
                  lcd.print( "Time: " );
                  lcd.print( end-start );
                }
          }
          end=millis();
        }
        while( (end-start<LOOP_TIME) && !movement );

        if( end-start>=LOOP_TIME ){
          lcd.clear();
          lcd.print("Time is out");
        }

        else{
          lcd.clear();
          lcd.print("Movement detected");
          lcd.setCursor(0,1);
          lcd.print( "Time: " );
          lcd.print( end-start );
        }
        delay(1000);
        /* Don't forget to clear the flag. */
        f_wdt = 0;
        /* Re-enter sleep mode. */
        enterSleep();
      }
      else
      {
        /* Do nothing. */
      }
    }

Does anyone has any idea why is it so?

body:
First thing in my mind would be to check/change the pull-down resistor value.

The pull-down resistor must have a larger resistance than the impedance of the logic circuit, or else it might be able to pull the voltage down by too much and the input voltage at the pin would remain at a constant logical low value

Read more [here][1].

  [1]: http://www.resistorguide.com/pull-up-resistor_pull-down-resistor/


message:
Blinking cursor on Arduino is inconsistent and misses inputs

I am trying to write a part of a program that prints time and allows the user to move a cursor across it. I have the following code, but there are a few issues with it.

    #include <Adafruit_RGBLCDShield.h>
    #include <utility/Adafruit_MCP23017.h>
    #include <Time.h>
    #include <TimeLib.h>
    Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

    void setup() {
      lcd.begin(16,2);
      setTime(12,30,15,0,0,0);
    }
    int col = 0;

    void loop() {
      uint8_t buttons = lcd.readButtons(); //create readable buttons
      char time_out[16];
      lcd.setCursor(0,0);
      sprintf(time_out, "u:u:u",hour(),minute(),second());
      lcd.print(time_out);
      lcd.setCursor(col,0);
      lcd.blink();
      delay(100);
      if (buttons) {
        lcd.clear();
        if (buttons & BUTTON_RIGHT) {
          col += 1;
        }
        if (buttons & BUTTON_LEFT) {
          col -= 1;
        }
      } //buttons
    }

If you upload this to your board, you can tell that the blinking is highly irregular, not at all aesthetically pleasing.

You'll also notice that sometimes, when pressing left/right, the input isn't registered.

I suspect this has to do something with the `delay()` function used, which pauses the entire program.

I looked into [the following method][1], but this does not work when needing to print something in a loop (as the time library requires).

Any idea how I could make this work better (regular blinking times and no miss of user input)?

Thanks a lot!

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

body:
I don't have the hardware to test but, it should be more or less like this;
(I have also normalized the code into several functions for better readability.)

    #include <Adafruit_RGBLCDShield.h>
    #include <utility/Adafruit_MCP23017.h>
    #include <Time.h>
    #include <TimeLib.h>
    Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

    unsigned long timerBlink; //Required for periodic blinking
    int intervalBlink = 100;

    void setup() {
     lcd.begin(16, 2);
     setTime(12, 30, 15, 0, 0, 0);
     timerBlink = 0;
    }
    int col = 0;

    void loop() {
     readButtons();
     printDate();
     if (millis() - timerBlink > intervalBlink) {
      blink();
     }
    }

    void readButtons() {
     uint8_t buttons = lcd.readButtons(); //create readable buttons
     if (buttons) {
      lcd.clear();
      if (buttons & BUTTON_RIGHT) {
       col += 1;
      }
      if (buttons & BUTTON_LEFT) {
       col -= 1;
      }
     } //buttons
    }

    void blink() {
     lcd.setCursor(col, 0);
     lcd.blink();
     timerBlink = millis();//Start timer for intervalBlink
    }

    void printDate() {
     char time_out[16];
     lcd.setCursor(0, 0);
     sprintf(time_out, "u:u:u", hour(), minute(), second());
     lcd.print(time_out);
    }

Instead of blocking delay function, using timeout with timestamp is a better practice.


message:
Do I Have to Change Internal Interrupt Setups when I Change Clock Speed?

The reason I ask is because I am trying to modify this code:

https://github.com/DccPlusPlus/BaseStation/blob/master/DCCpp_Uno/DCCpp_Uno.ino (Beginning at Line 289)

so that if will work on an ATmega328P-derivative board running at 3.3V and 8 MHz. I need the waveforms to be generated at the same speed, so is there anything I have to change? The original code is written for a 16 MHz uno or mega.

body:
The equation for timer period is given by the following formula, where `N` is the value of the prescaler, `TOP` is the value given by either `MAX` (i.e. `0xFF`, `0xFFFF`) or the value in register `OCRnx`, and `f` is the frequency of the I/O clock.

[![T = (N × (TOP+1)) ÷ f][1]][1]

If you're using phase-correct or phase- and frequency-correct mode, the factor (`TOP`+1) in the formula above should be replaced by 2 × `TOP`.

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


message:
How to break connection HM10 Bluetooth?

I have 2 HM10 Bluetooth modules connected to 2 Arduino Teensy running the following code.

    void setup() {
      Serial.begin(9600);
      Serial1.begin(9600);
      // If the baudrate of the HM-10 module has been updated,
      // you may need to change 9600 by another value
      // Once you have found the correct baudrate,
      // you can update it using AT+BAUDx command
      // e.g. AT+BAUD0 for 9600 bauds
    }

    void loop() {
      char c;
      if (Serial.available()) {
        c = Serial.read();
        Serial1.println(c);
      }
      if (Serial1.available()) {
        c = Serial1.read();
        Serial.print(c);
      }
    }

By pairing them using the AT commands I was able to send messages back and forth by writing to Serial1. However now when I try to send AT commands it will just send the string to the other module instead of replying OK etc. How do I break the connection and make the AT commands work again?

[The tutorial][1] I used to pair the modules.

  [1]: http://www.instructables.com/id/How-to-Use-Bluetooth-40-HM10/

body:
From the device datasheet:

System KEY function (PIO0) if Low > 1000ms:

7.3.1 If Module is in sleep mode Module will wake up immediately, if AT+NOTI value is “1”, module will send “OK+WAKE” string through UART.

**7.3.2 If Module has already connected to remote device Module will disconnect from remote device.**

7.3.3 If Module is standby mode Module will reset to default configuration. Then restart.


body:
I was able to break the connection with:
AT

The data sheet says to use AT+PWRM1, but it didn't work for me. Instead the above command dropped the connection to the remote device.

From the Datasheet:

2. Execute “AT+PWRM1” command, Module will auto into sleep mode when
power on or disconnect from remote device.


body:
To Break Connection via BT Commands, I do the following (programmatically):
command 1: `AT`
command 2: `AT+IMME1`
When the BT is in Work Mode it does not recognize regular BT commands.  The exception to this is the AT command by itself. But, it must be followed by another command (#2) within the Supervision Timeout Period which is fairly quick. IMME1 takes the BT back to AT Mode where it is no longer connected and will recognize your AT[+...] commands. If the Save Setting is enabled, it will attempt auto-reconnect too quickly...


body:
Somehow I ended up in such an endless auto-reconnect loop after activating AT+ROLE1 without setting AT+IMME1 first. Nothing seemed to help, not even pulling PIO0 low for 1s. I still don't even know which device my HM-10 was connecting to. It just autoconnected to something on boot...

The only way I could find to break out of this endless loop  was using this sketch below. The trick was that I had to wait for "OK" response after "AT" before issuing the follow-up command "AT+RENEW" to restore factory settings.

    #include <SoftwareSerial.h>

    SoftwareSerial BTserial(8, 9);

    void waitForOK()
    {
      while (!BTserial.available());

      char c = BTserial.read();
      Serial.write(c);
      c = BTserial.read();
      Serial.write(c);
    }

    void setup()
    {
      Serial.begin(9600);
      BTserial.begin(115200); // fw v700 changed default to 115200, otherwise use 9600
      Serial.println("BTserial started at 115200");

      BTserial.write("AT");
      waitForOK();
      BTserial.write("AT+RENEW");
      waitForOK();
      BTserial.write("AT+IMME1");
      waitForOK();
    }


message:
Advanced Arduino Project Help

So, I am an Engineer working on a very time tight project.

I want to create a system capable of collecting data from a Photodiode and compiling it in a way that will separate data into four columns which correspond to colours (red, green, blue, yellow) the columns will have rows of data corresponding to a number.

I have elected to use Arduino for this project but need some help on what to get and whether this is possible or not... I have an intermediate knowledge of C, C++ and previous Arduino experience, but have never undertaken something like this.

The project is envisaged to look like this.

Hardware:

 - Photodiode with RS232-C connection
 - An Arduino (Which sort is best? now I have Uno and Mega but can purchase others should these not be sufficient for the project)
 - Touchscreen Interface
 - Storage capacity (SD card or email/Bluetooth capability or something alike to collect the data to edit on PC).

The Process should is like this: Input = User interacting with GUI on Touchscreen - First page will have Four Colours Available (Once one of these inputs selected let’s say Red, jump to next page) -> Page two will have a Touch Number Pad Input (User selects number, let's say 2 in this case and hits enter), For less complexity this could be on one page correct? ->
The Data will then be read off a Photodiode communicating via RS232-C to Arduino and stored in a .csv or something similar under its previously selected values (Red, 2, Photodiode Value)

Output: A compiled list of all the data collected under their relative user inputs.

I currently have these items but am happy to purchase others.

 - S130C Thorlabs Photodiode Sensor
 - Null Modem Cable (Pins are swapped on S130C)
 - RS232 Shield (DFRobot RS232 Shield V0.1)
 - Arduino Uno, Arduino Mega
 - TouchScreen (Duinotech 2.8” TFT LCD)

After re-reading what I wrote I suppose there are a few:

 1. Could I complete this project using Uno and Mega?
 2. Is there a method for compiling data and storing/sending using Arduino?
 3. What are the capabilities of Arduino? Could a project of this complexity be done using Arduino components or is there another microprocessor or microcomputer which would be a better choice for this project?

body:
Your question is incredibly broad. However:

*1. Could I complete this project using Uno and Mega?*

Yes, almost certainly

*2. Is there a method for compiling data and storing/sending using Arduino?*

What? Yes, you can store data onto an SD card using a simple level-shifting piece of hardware like this:

[![SD card interface][1]][1]

*3. What are the capabilities of Arduino?*

This isn't a reasonable question (it's too broad). I suggest Googling for things people have done. For myself, I made a [humidity and temperature sensor](http://www.gammon.com.au/forum/?id=12106) using the same processor as in a Uno. It also runs from batteries.

---

>  ... a very time tight project ...

Time is going to be your enemy here. Learning how to drive a touchscreen, save files to an SD card, interpret RS232 data from your sensor, and make it all work reliably is not the sort of thing you will do in 3 days.

Even if you dumped all your hardware on my desk (and I know how to program Arduinos) I would estimate two or three weeks to calmly get each part going individually and then interface them all together.

---

> Would you suggest using breakout boards over shields?

Shields are well and good if they do what you want them to do. A breakout board will have more flexibility.

> because of pin availability would you suggest trying to use the Mega rather than Uno?

Depends how many pins you need. If you use SPI or I2C you can (probably) drive your display with only a handful of pins.

The Uno will probably have enough, and it has the flexibility that you can easily replace the processor chip if you damage it. You can't do that to the Mega. Plus, more code is written for the Uno so you are more likely to find libraries that work "out of the box" for a Uno.

I wouldn't be getting the "more powerful" device unless you have identified a specific reason to have it. For example, some of the faster and more powerful Arduinos (and other boards) with ARM processors may well do more under certain circumstances, but be somewhat harder to use.

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


message:
How to blink 2 led strips without delay

Hi all I use 2 sensors and 2 led strips. I want to let both led strips light up without interrupting each other while reading the different values from the inputs. But Arduino still pauses when one lights up, the other one needs to wait for the time to pass, either one misses reading the value when one is processing the output.

I know delay(wait); makes it block out the coming data, but it lets the strips light up for 6 seconds. If I remove it, the strips will light one 1 second only. What should I do? Thanks so much!

    #include <Adafruit_NeoPixel.h>
    #define PIN 6
    int ledFadeTime = 7;
    Adafruit_NeoPixel strip3 = Adafruit_NeoPixel(60, 9, NEO_GRB +NEO_KHZ800);//led pin
    Adafruit_NeoPixel strip4 = Adafruit_NeoPixel(60, 7, NEO_GRB + NEO_KHZ800);//led pin
    const int sensorPin3 = A2;//motion sensor
    const int sensorPin4 = A3; //flash sensor

    unsigned long strip3OnTime;
    unsigned long strip4OnTime;
    bool strip3On;
    bool strip4On;
    unsigned long previousMillis = 0;
    const long interval = 1000;

    void setup() {

      Serial.begin(9600);
      strip3.begin();
      strip3.show();
      strip4.begin();
      strip4.show();

      strip3On = false;
      strip4On = false;
    }

    void loop(){
     int Val3 = analogRead (sensorPin3); // sensor val
     int Val4 = analogRead (sensorPin4);

     Serial.print(Val3);
     Serial.print(" ");
     Serial.println(Val4);

       if (Val3>70) {
         rgbFadeInAndOut3(0, 0, 255, ledFadeTime);
         //analogWrite(strip3, HIGH);
         strip3On = true;
         strip3OnTime = millis();
       }
       if (Val4>70) {
         rgbFadeInAndOut4(0, 0, 255, ledFadeTime);
         //analogWrite(strip4, HIGH);
         strip4On = true;
         strip4OnTime = millis();
       }

       if(strip3On)
         if(millis() - strip3OnTime > 7000) {
           rgbFadeInAndOut3(0, 0, 1, 5000);
           strip3On = false;
         }
       if(strip4On)
         if(millis() - strip4OnTime > 7000) {
           rgbFadeInAndOut4(0, 0, 1, 5000);
           strip4On = false;
         }
     }

     void rgbFadeInAndOut3(uint8_t red, uint8_t green, uint8_t blue, uint8_t wait) {
       unsigned long currentMillis = millis();
       if (currentMillis - previousMillis >= interval){
         previousMillis = currentMillis;

       for(uint8_t b = 0; b <255; b++) {
          for(uint8_t i=0; i < strip3.numPixels(); i++) {
             strip3.setPixelColor(i, red * b/255, green * b/255, blue * b/255);
           }
          strip3.show();
         delay(wait);
       };

       for(uint8_t b=255; b > 0; b--) {
          for(uint8_t i = 0; i < strip4.numPixels(); i++) {
             strip3.setPixelColor(i, red * b/255, green * b/255, blue * b/255);
          }
          strip3.show();
          delay(wait);
       };
     };
     }
     void rgbFadeInAndOut4(uint8_t red, uint8_t green, uint8_t blue, uint8_t wait) {
        unsigned long currentMillis = millis();
        if (currentMillis - previousMillis >= interval){
         previousMillis = currentMillis;

       for(uint8_t b = 0; b <255; b++) {
          for(uint8_t i=0; i < strip4.numPixels(); i++) {
             strip4.setPixelColor(i, red * b/255, green * b/255, blue * b/255);
          }
          strip4.show();
          delay(wait);
       };

       for(uint8_t b=255; b > 0; b--) {
          for(uint8_t i = 0; i < strip4.numPixels(); i++) {
             strip4.setPixelColor(i, red * b/255, green * b/255, blue * b/255);
          }
          strip4.show();
          delay(wait);
       };
     };
     }

body:
Very simple. It takes only 3 steps.

1. Blink an led stripe with no delay.
2. Blink two led stripes, using the code developed in step 1.
3. Enjoy your blinking let stripes.

edit: since you seem to be struggling, here is one (of countless) way(s) to do #1 above.

    //blinky_ledx2.ino

    //blink two led strips independently

    //blinky rate
    #define LED_DLY   100  //duration for led1, in ms
    #define LED    12  //led to be blinked

    int led = 13;

    //run user routine, non-blocking
    void NB_run(void (*func_ptr)(void)) {
     static uint32_t millis_next=0;       //next match point

     if (millis() >= millis_next) {       //time is up
      millis_next += LED_DLY;        //advance match-up time
      func_ptr();           //execute user function
     }
    }

    //blinky example
    void blinky1(void) {
     //blink LED
     digitalWrite(LED, !digitalRead(LED));
    }

    void setup() {
       // put your setup code here, to run once:
       pinMode(led, OUTPUT);
       pinMode(LED, OUTPUT);         //LED as output
    }

    void loop() {
     NB_run(blinky1);          //run blinky1 at set intervals for LED
     digitalWrite(led, !digitalRead(led));     //blink led
    }

the heart of this is NB_run() -> it executes func_ptr() once the set time has been reached. otherwise, it returns without doing anything, as shown in the example below.

D13 is blinked constantly in the main loop, while D12 is blinked based on LED_DLY, in a non-blocking fashion.

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

I purposely wrote NB_run() so that it needs additional "parameterization" to run multiple tasks - what you have here is the basis of a generic framework for a rudimentary pseudo multi-tasker. it is not difficult at all for you to extend the code to run 2 stripes.

good luck.

edit2: it was pointed out to me, quite correctly, that something like this can be done via rtos. true, but a typical rtos has lots of overhead and requires a more substantial hardware to support.

one exception is macro-based rtos, like protothread. in that particular implementation, you will see that there is little gain in terms of code complexity, but some stylistically.

here is an implementation of running two tasks concurrently via protothread, only code for one task is shown, however.

    //thread 1
    PT_THREAD(protothread1(struct pt *pt, uint32_t pr)) {
     static uint32_t time_next=0;  //time for the next blinking

     PT_BEGIN(pt);
     while (1) {
      PT_WAIT_UNTIL(pt, millis() > time_next);
      time_next += pr;    //advance time to the next match up point
      toggleLED(LED1);    //run user task - blink led1
     }
     PT_END(pt);
    }

    void loop() {
     protothread1(&pt1, LED1_DLY);  //running thread1
     protothread2(&pt2, LED2_DLY);  //running thread2

    }

you can see that it retains largely the code structure presented earlier.

here is the outcome of that code, blinking D12/D13 at different rates.

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

  [1]: https://i.stack.imgur.com/VYRnB.png
  [2]: https://i.stack.imgur.com/VpYeK.png


message:
Crash when datalogging MPU-6050 to SD card

On an Arduino Pro Mini, I'm using Jeff Rowberg's stuff in i2cdevlib to read from the MPU6050, and using SdFat to write data to an SD card. Each part in isolation is fine, but when both DAQ and logging are in use the Arduino locks up after a few minutes, then happily restarts when reset is pressed.

I've tried disabling the interrupt and manually polling `mpu.getIntStatus()` in `loop()`, and I've also dropped the FIFO rate from 100Hz to 10Hz by changing the config in `MPU6050_6Axis_MotionApps20.h` (and confirmed that it has actually dropped) along with changing the SPI speed from SPI_FULL_SPEED to SPI_SIXTEENTH_SPEED and changing the I2C wire speed from 400kHz to 50kHz. All of these were done progressively and showed no significant change in the run times, which are scattered pretty randomly between <1 and 20 minutes. I also changed the datalogging to doing a filesystem flush on every cycle from doing it every 100 cycles, which helped performance but might have meant lots of internal buffer allocation/deallocation and memory leak risk.

I've tried putting a watchdog in but have encountered a widely known issue with this board that the watchdog is useless with the stock bootloader. I'm now working on that so I can try and use it to debug where in code the hang is, but I suspect it's going to be deep in one of the two third party libraries and I'm not going to be able to do much with it. I've attached the present iteration of code below. Does anyone have thoughts on where to go from here? Has anyone done similar with this kit?
<!-- language-all: lang-cpp -->

    #include "I2Cdev.h"

    //#include <helper_3dmath.h>
    //#include <MPU6050.h>
    #include <MPU6050_6Axis_MotionApps20.h>
    //#include <MPU6050_9Axis_MotionApps41.h>

    // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
    // is used in I2Cdev.h
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        #include "Wire.h"
    #endif

    //Includes for SdFat

    #include <FreeStack.h>
    #include <MinimumSerial.h>
    #include <SdFat.h>
    #include <SdFatConfig.h>
    #include <SdFatUtil.h>
    #include <SystemInclude.h>

    //Includes for watchdog
    #include <avr/wdt.h>

    // ************* Defines for MPU6050 *****************
    #define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno & most boards

    // ************* Variables for MPU6050 *****************

    // class default I2C address is 0x68
    // specific I2C addresses may be passed as a parameter here
    // AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
    // AD0 high = 0x69
    MPU6050 mpu;
    //MPU6050 mpu(0x69); // <-- use for AD0 high

    // MPU control/status vars
    bool dmpReady = false;  // set true if DMP init was successful
    uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
    uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
    uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
    uint16_t fifoCount;     // count of all bytes currently in FIFO
    uint8_t fifoBuffer[64]; // FIFO storage buffer

    // orientation/motion vars
    //Quaternion q;           // [w, x, y, z]         quaternion container
    VectorInt16 aa;         // [x, y, z]            accel sensor measurements
    VectorInt16 gyro;       // [x, y, z]            gyro measurements

    //VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
    //VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
    //VectorFloat gravity;    // [x, y, z]            gravity vector
    //float euler[3];         // [psi, theta, phi]    Euler angle container
    //float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

    // ************* Defines for SdFat *******************

    // The chip select line for the SD card
    #define SD_CHIP_SELECT 4
    // Log file base name.  Must be six characters or less.
    #define FILE_BASE_NAME "Data"

    // ************ Variables for SdFat *******************
    //
    // Set DISABLE_CHIP_SELECT to disable a second SPI device.
    // For example, with the Ethernet shield, set DISABLE_CHIP_SELECT
    // to 10 to disable the Ethernet controller.
    const int8_t DISABLE_CHIP_SELECT = -1;
    //
    // Test with reduced SPI speed for breadboards.
    // Change spiSpeed to SPI_FULL_SPEED for better performance
    // Use SPI_QUARTER_SPEED for even slower SPI bus speed
    const uint8_t spiSpeed = SPI_SIXTEENTH_SPEED;
    // File system object.
    SdFat sd;
    // Log file.
    SdFile file;

    int sd_writes_since_flush = 0;

    // Serial streams
    ArduinoOutStream cout(Serial);

    // input buffer for line
    char cinBuf[40];
    ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf));

    // ******************************* Misc *******************************
    int crash_timer = 0;

    // ================================================================
    // ===               INTERRUPT DETECTION ROUTINE                ===
    // ================================================================

    volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
    void dmpDataReady() {
        mpuInterrupt = true;
    }

    //******************* Setup ***************************

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

      // Set up serial comms
      Serial.begin(250000);
      while (!Serial); // wait for Leonardo enumeration, others continue immediately
      Serial.println(F("Serial initialised"));

      // initialize device
      Serial.println(F("Initializing MPU.."));

      // Set up comms to the MPU6050
      Wire.begin();
      Wire.setClock(50000); //400000= 400kHz I2C clock. Comment this line if having compilation difficulties

      mpu.initialize();

      pinMode(INTERRUPT_PIN, INPUT);
      Serial.println(F("Initializing DMP.."));

      devStatus = mpu.dmpInitialize();

        // make sure it worked (returns 0 if so)
        if (devStatus == 0) {
            // turn on the DMP, now that it's ready
            Serial.println(F("Enabling DMP..."));
            mpu.setDMPEnabled(true);

            // enable Arduino interrupt detection
            Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
            attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
            mpuIntStatus = mpu.getIntStatus();

            // set our DMP Ready flag so the main loop() function knows it's okay to use it
            Serial.println(F("DMP ready! Waiting for first interrupt..."));
            dmpReady = true;

            // get expected DMP packet size for later comparison
            packetSize = mpu.dmpGetFIFOPacketSize();
        } else {
            // ERROR!
            // 1 = initial memory load failed
            // 2 = DMP configuration updates failed
            // (if it's going to break, usually the code will be 1)
            Serial.print(F("DMP Initialization failed (code "));
            Serial.print(devStatus);
            Serial.println(F(")"));
        }

      // verify connection
      Serial.println(F("Testing device connections..."));
      Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

      Serial.println(F("Initialising SD card.."));
      if (!sd.begin(SD_CHIP_SELECT, spiSpeed)) {
        if (sd.card()->errorCode()) {
          Serial.println (F(
                 "\nSD initialization failed.\n"
                 "Do not reformat the card!\n"
                 "Is the card correctly inserted?\n"
                 "Is chipSelect set to the correct value?\n"
                 "Does another SPI device need to be disabled?\n"
                 "Is there a wiring/soldering problem?\n"));
          //Serial.println(F("\nerrorCode: ") << hex << showbase);
          //Serial.println(sd.card()->errorCode());
          //Serial.println(F(", errorData: ") << int(sd.card()->errorData());
          //Serial.println(noshowbase);
          sd.initErrorHalt();
        }
        Serial.println(F("\nCard successfully initialized.\n"));
        if (sd.vol()->fatType() == 0) {
          Serial.println(F("Can't find a valid FAT16/FAT32 partition.\n"));
          sd.initErrorHalt();
        }
        if (!sd.vwd()->isOpen()) {
          Serial.println(F("Can't open root directory.\n"));
          sd.initErrorHalt();
        }
        Serial.println(F("Can't determine error type\n"));
        sd.initErrorHalt();
      }
      Serial.println(F("Card successfully initialized."));

      getFile();

      //Serial.println(F("Enabling 2s watchdog"));
      /* Watchdog is set to 2s.
       *  We tick every 10ms so initially it was set to 60ms, however the watchdog stays enabled
       *  after reboot, and since the code takes more than 60ms to come back up we ended up in a boot loop.
       */
      //wdt_enable(WDTO_2S);

    }

    void getFile()
    {
        const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
        char fileName[13] = FILE_BASE_NAME "00.csv";

        // Find an unused file name.
      if (BASE_NAME_SIZE > 6) {
        sd.errorHalt(F("FILE_BASE_NAME too long"));
      }
      while (sd.exists(fileName)) {
        if (fileName[BASE_NAME_SIZE + 1] != '9') {
          fileName[BASE_NAME_SIZE + 1]++;
        } else if (fileName[BASE_NAME_SIZE] != '9') {
          fileName[BASE_NAME_SIZE + 1] = '0';
          fileName[BASE_NAME_SIZE]++;
        } else {
          sd.errorHalt(F("Can't create file name. May have used them all."));
        }
      }

      Serial.print(F("Trying to create file "));
      Serial.println(fileName);

      if (!file.open(fileName, O_CREAT | O_WRITE | O_EXCL)) {
          sd.errorHalt(F("file.open failed"));
        }

      file.println(F("Time/ms,acc_x,acc_y,acc_z,gyr_x,gyr_y,gyr_z"));

        // Force data to SD and update the directory entry to avoid data loss.
      if (!file.sync() || file.getWriteError()) {
        sd.errorHalt(F("write error"));
      }
      Serial.print(F("File opened; "));
      Serial.println(fileName);

    }

    void loop() {
      // put your main code here, to run repeatedly:
     // wdt_reset(); //reset watchdog
      // wait for MPU interrupt or extra packet(s) available

        int loopTO = 0;

        while (!mpuInterrupt && fifoCount < packetSize) {
            if (loopTO++ > 100000)
            {
              Serial.println(F("mpuInterrupt died?"));
              loopTO=0;
            }
        }

        // reset interrupt flag and get INT_STATUS byte
        mpuInterrupt = false;
        mpuIntStatus = mpu.getIntStatus();

        // get current FIFO count
        fifoCount = mpu.getFIFOCount();

        // check for overflow (this should never happen unless our code is too inefficient)
        if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
            // reset so we can continue cleanly
            mpu.resetFIFO();
            Serial.println(F("FIFO overflow!"));

        // otherwise, check for DMP data ready interrupt (this should happen frequently)
        } else if (mpuIntStatus & 0x02) {
            // wait for correct available data length, should be a VERY short wait
            loopTO=0;
            while (fifoCount < packetSize)
            {
              fifoCount = mpu.getFIFOCount();
              if (loopTO++ > 100000)
              {
                Serial.println(F("fifo no longer getting data?"));
                loopTO=0;
              }
            }

            // read a packet from FIFO
            mpu.getFIFOBytes(fifoBuffer, packetSize);

            // track FIFO count here in case there is > 1 packet available
            // (this lets us immediately read more without waiting for an interrupt)
            fifoCount -= packetSize;

            mpu.dmpGetAccel(&aa, fifoBuffer);

            //Gyro data is in the packet that comes back. More easily obtained using
            //dmpGetGyro(int32_t *data, const uint8_t* packet)
            //or dmpGetGyro(VectorInt16 *v, const uint8_t* packet)
            //These take the same parameters as the two versions of dmpGetAccel
            mpu.dmpGetGyro(&gyro, fifoBuffer);

            file.print(millis());
            file.print(",");
            file.print(aa.x);
            file.print(",");
            file.print(aa.y);
            file.print(",");
            file.print(aa.z);
            file.print(",");
            file.print(gyro.x);
            file.print(",");
            file.print(gyro.y);
            file.print(",");
            file.println(gyro.z);

            //Either sync here or in the 100th iteration bit.
            if (!file.sync() || file.getWriteError()) {
              sd.errorHalt(F("write error"));
            }

            if (sd_writes_since_flush++ > 10) //was 100 at 100Hz but at 10Hz that gets silly
            {
               // Force data to SD and update the directory entry to avoid data loss.
               sd_writes_since_flush = 0;
              /*
              if (!file.sync() || file.getWriteError()) {
                sd.errorHalt(F("write error"));
              }
              */
              //Also output so we know something's happening
              Serial.print(millis());

            Serial.print("\t");
            Serial.print(aa.x);
            Serial.print("\t");
            Serial.print(aa.y);
            Serial.print("\t");
            Serial.print(aa.z);
            Serial.print("\t");
            Serial.print(gyro.x);
            Serial.print("\t");
            Serial.print(gyro.y);
            Serial.print("\t");
            Serial.println(gyro.z);

            //Force a crash after 10s to test the watchdog
            //if (crash_timer++>10) while(1);

            }
            /*
            Serial.print(millis());

            Serial.print("\t");
            Serial.print(aa.x);
            Serial.print("\t");
            Serial.print(aa.y);
            Serial.print("\t");
            Serial.print(aa.z);
            Serial.print("\t");
            Serial.print(gyro.x);
            Serial.print("\t");
            Serial.print(gyro.y);
            Serial.print("\t");
            Serial.println(gyro.z);
    */
            // blink LED to indicate activity
            //blinkState = !blinkState;
            //digitalWrite(LED_PIN, blinkState);
        }

    }

body: This seems to be fixed. I've connected the modules together using short soldered leads rather than the breadboard and it's just run for 18 and a half hours before I decided to stop the test. Previously the maximum run time was less than an hour. So even with SPI at sixteenth speed and I2C at 50kHz instead of 400kHz, it seems a breadboard is too flaky when both comms mechanisms are in use. I note I didn't actually say I was on breadboard- in hindsight maybe that would've prompted immediate comment but I thought at slow data rates I'd be ruling out such things.


body: It seems that, from my experiments, this has something more to do with the serial buffer. If you print more than 55 characters in Serial.print (); using the MPU6050 and the SDCard, stack overflow errors occur. Try limit the buffer to 55 using the snprintf(); function; instead of Serial.print(); directly. Or make the serial output divided by 55 if your serial output is more than 55 per line.


body:
I had a similar problem with an SD-Card and CAN-BUS Module on an Arduino Mega Pro Mini.

My solution was to add a 470uF capacitor between VCC and GND. Problem solved!

That was the only capacitor I tried, maybe a smaller value would have done the job.
My project used about 200mA.

What I found surprising was that I had to add this capacitor when I used the USB from my PC for the power supply. The PC power supply and motherboard are high quality.

When I powered my project with a linear regulator (12V to 5V) and a switching converter all worked fine. But both had already a 470uF capacitor on the 5V side.

It's obvious that this won't be the answer in all scenarios. But it might be one of the possible answers for a system which hangs for no obvious reason.


message:
Serial.available() function for Arduino

I want to implement a function in another micro-controller which works like `serial.available()`. I don't know how it works. I read about `Serial.available()` in [this link][1].

Whenever I write a string on the terminal, it prints the length of the string. Can anyone tell me how it works?

  [1]: https://www.arduino.cc/en/serial/available

body:
It reports the difference between the head and the tail of the circular buffer the incoming characters are stored in.

The way serial reception on the Arduino works is:

1. A character is received into the internal hardware RX buffer (`UDRx`)
2. An interrupt is triggered
3. An interrupt service routine (ISR) is executed
4. The character in `UDRx` is read and, if there is room, stored in a circular buffer (`_rx_buffer`).
5. The `head` pointer of `_rx_buffer` is incremented and wrapped if needed.

When you actually read a character with `Serial.read()` the following happens:

1. If the `head` and `tail` of `rx_buffer` are equal, return `-1`
2. Get the character at `tail` from `_rx_buffer`
3. Increment `tail` and wrap if needed
4. Return the character

So when you use `Serial.available()` it just returns `head - tail` (taking into account the wrapping, so the sum is slightly more complex than a simple subtraction).

You should examine the files `HardwareSerial.h` and `HardwareSerial.cpp` in the Ardino AVR core software.


message:
127v/220v AC sensor - What's the role of this particular resistor?

After searching for a very long time for a 127v/220v (AC) sensor without using any kind of transformers, I found this very nice idea (image below):
[![][1]][1]
[1]: https://i.stack.imgur.com/ZRdhN.jpg
I'd like to understand how this module works because I'll have to replicate it in my project without actually using it. I can already tell what's the role of every component, except for both resistors. The first resistor (10k) is placed between the capacitor's legs and, therefore, I'm assuming it's just a bleeding resistor. Am I right? The second resistor (220k), between the AC source and the optocoupler, I have no clue. I was also thinking whether I can improve this sensor by adding a rectifier bridge between the AC source and the optocoupler, allowing me to use a smaller capacitor to normalize the signal. Does that make sense? Thanks!

body:
The first resistor is working with the capacitor as an RC filter. Since you are sensing AC at 50~60Hz, you need this RC filter to get a constant output instead of a pulsed output. Remember your otpo-coupler has a LED (diode) inside, so it will only produce light when voltage is positive.

The second resistor is there to limit the current from your AC 220Vrms (which is 311V peak) so that is within the opto-coupler's LED forward current range. The voltage between your LED´s pins will always be it´s forward voltage (1.2V to 1.4V), so the resistor will bring down the 311V to 1.2 to 1.4V. Without this resistor, you would have 311V between the LED pins, and this would fry the poor thing.

The equivalent input circuit is something like this:

<!-- 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/s7dba.png)

<!-- End schematic -->

**Ok so how did they figure out the 220kOhms value?**
First, take the worst case scenario: 220Vrms AC gives us 311Vpeak, and LED forward voltage is 1.2V.
So the voltage between the 311V and the diode is 311 - 1.2V = 309,8V

OHM Law: R = V/I        (R=resistance, V=voltage, I=current)

In this case, the current chosen for the LED was about 1.4mA or 0.0014A, so R = 309.8V/0.0014A

R = 221k Ohms. The closest we get to this is 220kOhms

With 127Vrms (179.6Vpeak), your LED current will be:
I = 178.4V/220000 = 811uA

I have simplified the calculations, because this is a simple case, but keep in mind that real life engineering calculations will be more complex than this.


message:
Arduino Due: enable reentrant interrupt

I'm using the TC3 interrupt on my Arduino Due to run some code periodically, like this:

    void TC3_Handler() {
      TC_GetStatus(TC1, 0); // Remove interrupt flag
      // My code...
    }

However, as I've found out, the CPU will not service the same interrupt a second time while the interrupt is running. By editing the priorities of each interrupt source, it's possible for a higher priority interrupt to preempt and run over this interrupt (so nested interrupts are possible), but priority manipulation alone does not allow **reentrant** interrupts.

I'd like to know if there is any way to make this interrupt reentrant.

body:
> does not allow reentrant interrupts.

a few suggestions:

1) understand what "reentrant interrupts" means;

2) see if you need it;

3) see what needs to be done to get it to run on your hardware;

4) see if your code does what needs to be done.

hope it helps.


body:
In your notion about the meaning of **Reentrant interrupt**, you write:
> interrupt A can preempt handling of interrupt A; interrupt A's handler can be active concurrently with itself

---

**I. The first half of the notion** correctly states a condition that might trigger re-entrance of an ISR (interrupt service routine).  Note, an ISR that allows re-entrance might or might not be called reentrant: an ISR's code is *reentrant* if it performs correctly when it is re-entered.

On most processors that use a single stack, code will be reentrant if it has no side effects and does not access variables that are not in its stack frame.  It might be reentrant even if it does have side effects or accesses non-local variables, if its actions are [idempotent](https://en.wikipedia.org/wiki/Idempotence) or if some proper concurrency protocol is implemented.

---

**II. The second half of the notion** is misleadingly stated:  true concurrency does not occur on a single-thread-of-execution processor.  However, time sharing and task overlap may occur on such a processor via task switching using either preemptive or cooperative multitasking.

As explained in the next paragraph, to the best of my knowledge preemptive serial multitasking is what would happen if you re-enable the interrupt system within an ISR.

Let's suppose ISR A is written in a reentrant fashion, and that it clears the interrupt A interrupt flag early in its processing, and enables interrupts so more A interrupts can occur and be processed.  Also suppose three interrupt A's occur in quick succession (more precisely, quickly enough that processing of one does not complete before another comes along, but not so quickly that the A flag has not been cleared, which would cause loss of an A interrupt) followed by a hiatus.  In this case, the first interrupt A occurs; the ISR entry prologue creates a stack frame for the ISR code to use, then saves a number of registers, then begins executing user code, which we suppose turns interrupts back on.  After a bit the second interrupt A occurs.  ISR entry prologue creates stack frame and saves registers.  User code enables interrupts.  Third interrupt A occurs.  ISR entry prologue creates stack frame and saves registers.  User code enables interrupts.  As we've posited a hiatus, no more A interrupts occur for a while.  So processing of interrupt 3 proceeds and finishes.  The ISR epilogue reloads registers, clears the stack frame, and returns from interrupt, restoring the previous interrupt state.  Then processing of interrupt 2 proceeds, finishes, reloads registers, returns from interrupt.  Then processing of interrupt 1 proceeds, finishes, reloads registers, returns from interrupt.  Then `loop()` [or whatever is running in the main thread of execution] resumes its work.

As you can see from this example, interrupt processing will occur in a LIFO (last-in, first-out) order if an ISR simply accommodates re-entrance.  If that is what you want, fine.  If, however, you want interrupt processing to complete in order; want to do lengthy processing  while avoiding interrupt misses; and want to process in a secondary thread of execution, ie, a callback-like system, then the thing to do is have the ISR make a queue entry (in a static or heap-based circular queue) each time it starts; return from interrupt if it was re-entered; and process queue entries until the queue is empty, using atomic operations when changing queue pointers.

---

*Edit 2:*  In §10.20.9.1 of the SAM3x/SAM3A datasheet, “Hardware and software control of interrupts”, we find
> A peripheral interrupt becomes pending for one of the following reasons:
>> • the NVIC detects that the interrupt signal is HIGH and the interrupt is not active
...

>A pending interrupt remains pending until one of the following:
>> • The processor enters the ISR for the interrupt. This changes the state of the interrupt from pending to active.  Then:
>>> • For a level-sensitive interrupt, **when the processor returns from the ISR, the NVIC samples the interrupt signal.** If the signal is asserted, the state of the interrupt changes to pending, [...] Otherwise, the state of the interrupt changes to inactive.
 • If the interrupt signal is not pulsed while the processor is in the ISR, when the processor returns from the ISR the state of the interrupt changes to inactive.

>> • Software writes to the corresponding interrupt clear-pending register bit.
...

[Emphasis added]

This suggests that although the ISR for a given interrupt source on a SAM3x/SAM3A system can be interrupted by a higher-priority source, a given source can not re-interrupt until “the processor returns from the ISR”.  Without some research or testing, it isn't clear to me if that is correct, and whether software can simulate a return from ISR without actually returning.  Setting that possibility aside, here is a workaround to allow interrupt A to recur:

Set the interrupt priority of A fairly high, say level *z*.  Set up several selected SGI's (software generated interrupts) at levels *p, q, r ...*, all lower-priority than *z*.  Initialize an *A level* variable to point to the least-priority SGI ISR among those selected.  Upon any A interrupt, the A ISR issues an *A level* SGI, saves any data that SGI ISR needs, updates *A level* to next-higher-priority SGI [if possible], and returns from interrupt.  This re-enables A interrupts and allows the most recently issued (and currently highest priority) SGI to fire and start doing its thing.  When it's done, it atomically sets *A level* equal to its own level.  Thus, while any of the SGI ISR's is processing, if another A interrupt occurs, the current SGI ISR's processing suspends; when the A interrupt is handled, the next-higher SGI ISR starts.  All higher level ISRs finish before a lower level ISR resumes.


message:
Arduino mega 2560 might be dead

I was playing with Vin and a transistor when the arduino got disconnected from my pc and after a few seconds it started to smoke. It wasn't much smoke but enough to panic and disconnect everything. I waited a few minutes and then i plugged it into my pc. The power led and the 13 pin led were on but my pc couldn't recognize my device. In arduino ide i couldn't find the port and the tx and rx leds didn't blink at all. I tried to restart my px, reset arduino, i powered it with a 12v source and i got 12v out on Vin but 0 on 5V and 3V. The 13 pin doesn't want to turn off and my pc doesn't recognize it. It is not a ch arduino and it worked perfectly until i did this. I've benn searching on internet for 2 hours now about this but i still couldn't find something relevant. In device manager it sais "unknown usb device (device descriptor request failed)" and inside proprieties at device status this is written:

"Windows has stopped this device because it has reported problems. (Code 43)

A request for the USB device descriptor failed."

I also tried to update drivers automatically and manual but didn't work. I have no idea where that smoke came from.

Is it dead? can i do anything to make it work?

body:
>  i powered it with a 12v source and i got 12v out on Vin but 0 on 5V
> and 3V.

The fuse or the Vin input diode or the 5V voltage regulator or all of them could be damaged.

> i plugged it into my pc. The power led and the 13 pin led were on but
> my pc couldn't recognize my device.  In arduino ide i couldn't find
> the port and the tx and rx leds didn't blink at all.

1. The MCU could be damaged.
2. The USB chip is dead (Because there is no rx blinking during programming).

If you connect the arduino through USB and there was not 3.3v at the 3.3v supply rail, the 3.3v voltage regulator is dead.

You had better buy a new one or if you want to fix it to gain experience go for it.


body:
I have some troubleshooting steps here: https://arduino.stackexchange.com/questions/13292/have-i-bricked-my-arduino-uno-problems-with-uploading-to-board/

Whilst specifically written for the Uno, a lot of it applies to the Mega. Depending on what you did, the entire board may not have failed.

Many of the components are SMD (surface mounted devices) and may be difficult to replace, unless you have specialized equipment.

If you "zapped" every chip by applying a negative voltage (say) then it might not be worth it.


message:
XBee not connecting

Recently, I bought an XBee shield along with a dongle and two XBee's. After assembling them, I tried to connect them using XCTU. Although the XBee on the dongle connected correctly, the computer did not detect the XBee on the shield. I tried switching the XBee's, and there was no difference. I continually an error message telling me to reset the shield. Nothing happens when I reset the shield. Although the computer recognizes that the Arduino is plugged in, it seems as though it doesn't recognize the XBee.
I have tried this with every possible configuration, and I keep getting the same message. I have also tried many other things I found online.
I have been stuck on this problem for over a week, and any help would be

Here are the materials I am using

2x Series 1 XBee

1x Sparkfun XBee Explorer Dongle

1x Sparkfun XBee Shield

1x Arduino Uno R3

Thanks in advance!

body:
Check the baud rate on xctu software, make sure it is on 9600 or you can click on default button and make sure you connect the xbee on the right port [![enter image description here][1]][1]

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


message:
i am working on a project smart watch i am getting this error please help

Arduino: 1.6.7 (Windows 10), Board: "Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)"

    WARNING: Spurious .github folder in 'Adafruit SSD1306' library
    In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:28:0,

                     from sketch\RetroWatchArduino.ino.cpp:1:

    bitmap.h:1270: error: expected primary-expression before '__attribute__'

     PROGMEM const unsigned char* const bitmap_array[] = {

     ^

    C:\Users\varun\Desktop\retrowatch-master\retrowatch-master\RetroWatch_Arduino\RetroWatchArduino\RetroWatchArduino.ino: In function 'void drawIcon(int, int, int)':

    RetroWatchArduino:898: error: 'bitmap_array' was not declared in this scope

       display.drawBitmap(posx, posy, (const unsigned char*)pgm_read_word(&(bitmap_array[icon_num])), 16, 16, WHITE);

                                                                            ^

    exit status 1
    expected primary-expression before '__attribute__'

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

[Information about the smart watch][1]

  [1]: http://www.hardcopyworld.com/ngine/aduino/index.php/archives/670

body:
PROGMEM is in the wrong loctaion. According to [the Arduino Website](https://www.arduino.cc/en/Reference/PROGMEM):

> Note that because PROGMEM is a variable modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts all of the definitions below, which are also synonymous. However experiments have indicPROGMEM ated that, in various versions of Arduino (having to do with GCC version), PROGMEM may work in one location and not in another. The "string table" example below has been tested to work with Arduino 13. Earlier versions of the IDE may work better if PROGMEM is included after the variable name.
>
>
>     const dataType variableName[] PROGMEM = {};   // use this form
>     const PROGMEM  dataType  variableName[] = {}; // or this form
>     const dataType PROGMEM variableName[] = {};   // not this one

And I will add to that list:

    PROGMEM const dataType variableName[] = {};   // and definitely NOT this one.


message:
Detecting which pin called the ISR Uno

I need an answer fast.I want to make a keyboard class to handle a few buttons attached to my arduino. I want to use interrupts.The problem is I have to use the same interrupt function for all my buttons(it would beimpractical to create a routine for each button).So inside the routine I must know at least what pin fired the interrupt. How can I solve this?(I belive it can be solved by changing some registers but that would be too complicated).PS:there are only two buttons(pins 2 and 3 are enough)

Edit:
   Isn't possible to create/call an interrupt routine inside a class? (I know that the routine actually doesn't exist initially because the object of the class type wasn't created). Can this be done?

    class Keyboard{
      private:
        struct btn{
          boolean pressed;
          uint32_t pressTime;
        };
        btn button1;

      public:
        void int_handler(){

        }
        Keyboard(){
          attachInterrupt(digitalPinToInterrupt(2),this->int_handler,RISING);
          attachInterrupt(digitalPinToInterrupt(3),this->int_handler,RISING);
        }
    };

body:
You only have two external interrupts on the Uno, so a simple solution would be to call an "intermediate" routine, which remembers the button number. eg.

      attachInterrupt(digitalPinToInterrupt(2),this->int_handler2,RISING);
      attachInterrupt(digitalPinToInterrupt(3),this->int_handler3,RISING);

Those two functions could then call your main function passing down 2 or 3 depending on which one was called.

eg.

    void int_handler2 ()
      {
      int_handler (2);
      }

    void int_handler3 ()
      {
      int_handler (3);
      }

If you have more switches than that you can use pin-change interrupts. The typical way of detecting which one fired is to see which bits are different this time, compared to last time.

See [my page about interrupts](http://www.gammon.com.au/interrupts).


body:
I solved this in a more..compressed way.
I already store the state of the buttons(pushed down or up-that is if they set their connected pin to 0 or 1).So I can have a single routine called by the microcontroller and then inside it decide what pin changed states(clever):

    #define btn1Pin 2
    #define btn2Pin 3

    class Timer{
      //....
    };
    uint32_t Timer::start_time;
    class KeyboardBtn{
      private:
        const static byte clicksDelay=255;
        struct btn{
          byte state=1;   //(0-keyDown / 1-keyUp) 2-Click
          byte pin;
          Timer clickLapse;
        };
        volatile static btn buttons[2];

      public:
        KeyboardBtn(){
          buttons[0].pin=btn1Pin;
          buttons[1].pin=btn2Pin;
          attachInterrupt(digitalPinToInterrupt(btn1Pin),keyPress,CHANGE );
          attachInterrupt(digitalPinToInterrupt(btn2Pin),keyPress,CHANGE );
        }
        static void keyPress(){
          //digitalRead ==1 then button up
          for(int i=0;i<2;i++){
            if(bitRead(buttons[i].state,0)==digitalRead(buttons[i].pin)) continue;
            //i is the switched button
          }
        }
        byte stateChanged(byte key){
          //code
        }
    };
    volatile KeyboardBtn::btn KeyboardBtn::buttons[2];

    KeyboardBtn btn;
    void setup() {
      pinMode(btn1Pin,INPUT_PULLUP);
      pinMode(btn2Pin,INPUT_PULLUP);
    }

    void loop(){
    }


message:
Power Supply Ticking, Light Flashing

My Arduino came with a 9V 1A power supply to use with it.  I decided to test it out with my multimeter.  I put the red lead in the connector and the black on the outside.  Sure enough I read 9V.  However when I tested the amps this did not work.  The meter read a low value and the power supply started making a ticking noise and a light started flashing on it.

I did have the multimeter on the correct settings.  Looking online I now realize that you cannot test the amps this way and as I was essentially testing a circuit with no load on it.

What I would like to know is what the power supply was doing when it was ticking and flashing.  It is alive and well so I suppose it was some sort of internal protection.

body:
It was "hiccuping" in order to prevent damage from the short circuit condition. Once the short circuit condition is removed, the PSU restores normal operation.

From the reference:
"The operation of hiccup is as follows. When the current-sense circuit sees an over-current event, the controller shuts off the power supply for a given time and then tries to start up the power supply again. If the over-load condition has been removed, the power supply will start up and operate normally; otherwise, the controller will see another over-current event and shut off the power supply again, repeating the previous cycle."


body:
> I was essentially testing a circuit with no load on it.

No, you were imposing a very *high* load. An ammeter (amp meter) should be in *series* with the circuit under test. For example:

    ----(-)-- Power supply (+)-----(+)- Amp meter (-)---|
    |                                                   |
    |                                                   |
    ---(-)---- Circuit under test ----(+)----------------

When in amps mode the meter has a very low resistance, and measures the voltage drop over that low resistance (probably 0.1 ohms or less). Thus putting the meter *across* the power supply shorts it out.

Hence the noise it makes while trying to recover. The power supply turns itself off and on until the short goes away.

Also you are lucky you didn't blow the fuse in your meter. They are normally fused in case you accidentally do something like that.

---

>  Isn't low resistance considered a low load and not a high load?

A low resistance *in series* is a low load. A low resistance *in parallel* is a high load.

Assuming your meter presented a resistance of 0.15 ohms on the 10A range (as mine does) then using Ohms Law we can see that this would give a current of:

    I = V / R
    I = 9 / 0.15
    I = 60 amps

So, you are trying to draw 60 amps from your 1A power supply, which then turns off.

---

>  If the multimeter is rated at 10A and the power supply can provide at most 3A, then why is there a risk of blowing the fuse in the meter?

It depends on the range on the meter. Mine has a 10A range and a milliamp range. The 10A range is fused to slightly more than 10A (naturally) and the milliamp range has a maximum of 400 mA. If you had tested with the milliamp range you would have blown the fuse. Yes, it would survive on the 10A range, if your power supply cannot output 10A.

There will be lots of web pages about measuring amps with a meter, [here is one](https://www.youtube.com/watch?v=HWA9WqSEjg8).


message:
Navigating menus using buttons on Arduino

I have made a very short version of my code. It has the basic problem I am facing. I explain my code and problem below.

    #include <Adafruit_RGBLCDShield.h>
    #include <utility/Adafruit_MCP23017.h>
    Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

    void setup() {
      lcd.begin(16, 2); //format of display
    }

    int menu = 0;
    int subMenu = 99;
    void loop() {

      uint8_t buttons = lcd.readButtons();

      lcd.setCursor(0,0);

      if (menu == 0) {
      lcd.print("Select menu option");
        if (buttons & BUTTON_SELECT) {
          lcd.clear();
          menu = 99;
          subMenu = 1;
        }
      }

      if (subMenu == 1) {
        lcd.print("in sub menu 1");
        if (buttons & BUTTON_SELECT) {
           lcd.clear();
           lcd.setCursor(0,1);
           lcd.print("shouldnt happen");
        }
      }
    }

I am setting a variable `menu`, which will keep track of what main menu I am on, and a `subMenu`, which keeps track of what sub-menu I am on.

The default value of `menu` (0) prints on the LCD "Select Menu Option".

When pressing SELECT, the LCD is cleared. The `menu` is being set to an unknown number, so that it doesn't print anything, and `subMenu` is set to 1.

If `subMenu` is equal to 1 (which it will be if the user chooses presses SELECT), the LCD prints "in sub menu 1".

Inside this, if the button SELECT is clicked, it should print "shouldnt happen".

The issue I am facing is that when clicking SELECT for entering the menu 1, the SELECT is also carried out to the sub-menu, so instead of waiting for a second key press to confirm going into the sub menu, it goes straight into it.

This makes sense because it is check that SELECT has been pressed, prints a new page, with the button SELECT still having been pressed, so it validated the condition for key press in the sub menu as well.

**The user input to LCD display response should be the following:**

Select menu option -> presses SELECT -> in sub menu 1 -> presses SELECT -> shouldnt happen

**Currently however, it is like this:**

Select menu option -> presses SELECT -> in sub menu 1 shouldnt happen

How can I make it so that these key presses only act on the menu on which they are?

Thanks, let me know if something confuses you, I can explain in more details

body:
I'm not sure about built-in buttons, however on my projects I always add a debounce feature to any buttons.  Adjust this to your uses. If there's any issues let me know and I'll test it properly as I'm not at my programming workstation to fully test at the moment.

For example:

    // Updated to include if statements and copy/pasted version of successfully
    // compiled version.

    // Had to use LiquidCrystal library as I don't have the AdaFruit Display libraries.
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    //

    int menu = 0, subMenu = 99, debounce = 200;
    unsigned long pMillis = 0, cMillis;

    void setup(){
      lcd.begin(16,2);
    };

    void loop(){
      cMillis = millis(); // sets cMillis to current millis()
      //uint8_t buttons = lcd.readButtons();
      lcd.setCursor(0,0);
      if(cMillis >= (pMillis + debounce)){
        if (menu == 0) {
          lcd.print("Select menu option");
          /*if (buttons & BUTTON_SELECT) {
           *  lcd.clear();
           *  menu = 99;
           *  subMenu = 1;
           *  };
           */
        };
        if (subMenu == 1) {
          lcd.print("in sub menu 1");
          /*if (buttons & BUTTON_SELECT) {
           *  lcd.clear();
           *  lcd.setCursor(0,1);
           *  lcd.print("shouldnt happen");
           *  };
           */
        };
      pMillis = cMillis; // sets pMillis to cMillis for the next iteration of the loop()
      };
      // I always put something similar to this at the end
      // to make sure that when millis() cycles back to 0
      // pMillis is reset to less than cMillis.
      if(cMillis < pMillis){
        pMillis = cMillis; // sets pMillis to cMillis for the next iteration of the loop()
      };
    };

Edit/Update:  This compiles fine using the standard LiquidCrystal library, I am unable to test the AdaFruit display as I don't have one.  If this still doesn't work, I'll upload it to the Arduino when I get back and see what's up.

New test:

    // Your libraries here

    int menu = 0,
        subMenu = 99,
        debounce = 200;

    unsigned long pMillis = 0,
              cMillis;

    void setup(){
      lcd.begin(16,2);
    }

    void loop(){
      cMillis = millis(); // sets cMillis to current millis()
      //uint8_t buttons = lcd.readButtons();

      if(buttons & BUTTON_SELECT){ // I used "if(digitalRead(buttonPin) == HIGH){ ... }"
        if(cMillis >= (pMillis + debounce)){
          //I'd normally put counter/menu logic in here for the different buttons, for example:
          //"subMenu += 1;
          // if(subMenu >= totalSubMenus) { subMenu = 0; };"
          subMenu = 1;
          pMillis = cMillis;
        }
      }

      if(menu == 0){
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Select Menu Option");
        menu = 99;
      }
      if(subMenu == 1){
        lcd.clear();
        lcd.setCursor(0,1);
        lcd.print("In Sub Menu 1");
      }

      if(cMillis < pMillis){
        pMillis = cMillis; // sets pMillis to cMillis for the next iteration of the loop()
      }
    }


message:
What types of connectors should I use to connect an HC-06 to an Arduino?

I am new to electronics and I need to connect an Arduino Uno with an HC-06 Bluetooth module.

The problem is that I don't know what types of connectors I should use.

I know I need some Dupont wires but there are 3 types: **male to male** - **male to female** - **female to female**.

So my question is: what type of connector should I use?

body:
I'm not sure on the exact package of you HC-06. All of the ones I have are like this picture. If you have one like this, you will need male to female jumper cables. I would recommend a breadboard as well if you plan on connecting anything additional.

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

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


message:
Correct Capacitors to use with L7805 Voltage Regulator

I am making my own arduino.  I am in the process of hooking up power to the Atmega328.

In both these articles they use the L7805 voltage regulator with two 10uF capacitors.

https://www.arduino.cc/en/Main/Standalone

http://www.instructables.com/id/How-to-Build-an-Arduino-Uno-on-a-BreadBoard/?ALLSTEPS

I am looking at the datasheet for the regulator at http://pdf.datasheetcatalog.com/datasheet_pdf/sgs-thomson-microelectronics/L7805CD2T_to_L7885CV.pdf

The data sheet provides a number of figures for how to correctly hook up the L7805 in different situations (pages 4, 16-23).  I think Figure 13 represents our situation (Fixed Output Regulator).  In the figure they use 0.33uF and 0.1uF
capacitors.  Could someone explain why the examples use 10uF and the data sheet specifies 0.33uF and 0.1uF?

body:
The answers are in the notes:

> 2. Although no output capacitor is need for stability, it does improve transient response.
> 3. Required if regulator is locate an appreciable distance from power supply filter.

So  the values aren't critical to the operation, but you should have them there. Bigger capacitors give more energy to the regulator and more energy to your circuit (input and output capacitors respectively) but at the cost of lower frequency response. The actual values you select depend on your circuit, not the regulator. 10µF is a good "ballpark" figure to use in most circumstances.

The input capacitor reduces the impedance of the power source by providing a local source of power. The output capacitor is like the "reservoir" capacitor you should have at the power entry to all boards anyway, and reduces the impedance to the rest of your circuit.

For the higher frequency responses you should have smaller value decoupling capacitors by all your active components anyway.

You can also add more smaller capacitors to the output of the regulator to improve high frequency responsiveness if needed - you're not just limited to the one capacitor.


body:
> Could someone explain why the examples use 10uF and the data sheet specifies 0.33uF and 0.1uF?

One obvious reason is that those two examples are non compliant with the datasheet.

But generally speaking the ordinary 78xx regulators use emitter output and are quite tolerant to the output capacitance. 10if is not a bad number.

However, there are also variants of 78xxx that take their output from the collector. They are more sensitive to output capacitance, as most ldos are.

Generally it is a good idea to stay within the datasheet but that doesn't mean you shouldn't step out from time to time.


message:
Controlling Dynamixel Ax-12 With Arduino Mega

I want to controll two dynamixel ax-12 servos using a arduino mega and I don`t know the commands that I should send to them using Serial.

Could anyone help me with this?
(And please keep in mind that I don`t want any more hardware. Just arduino board)

body:
 With [Dynamixel library](http://savageelectronics.blogspot.fi/2011/08/actualizacion-biblioteca-dynamixel.html) you can use servo this easily:

    #include <DynamixelSerial.h>

    void setup(){
       Dynamixel.begin(1000000,2);  // Inicialize the servo at 1Mbps and Pin Control 2
    }

    void loop(){
        Dynamixel.move(1,0);
        delay(2000);
        Dynamixel.move(1,500);
        delay(2000);
        Dynamixel.move(1,1000);
        delay(2000);
    }

Example moves servo and makes pauses of 2 sec.

Installation is easy:

> Installation:
>
> Copy the files from DynamixeSerial to your IDE libraries folder.

DynamixelSerial folder can be found here: https://sourceforge.net/projects/dynamixelforarduino/files/?source=navbar


message:
I want to obtain the output of GPS at every 5 secs and store them onto database using Arduino uno,GPS SKG 13BL and GSM module??

I am on a project,in which I need to store the output of GPS from SKG 13BL to a database using Arduino UNO and GSM module.I wrote the following code

    #include <SoftwareSerial.h>
    #include <AltSoftSerial.h>
    #include <NMEAGPS.h>

    SoftwareSerial GSM(2, 3); // RX, TX: Connect TXD to RX & RXD to TX

    static const int RXPin = 8, TXPin = 9;
    AltSoftSerial gpsPort(RXPin, TXPin);
    static const uint32_t GPSBaud = 9600;

    NMEAGPS gps;
    gps_fix fix;
    uint8_t fixCount = 0;
    char dt[15],tm[15];

    enum _parseState {
      PS_DETECT_MSG_TYPE,

      PS_IGNORING_COMMAND_ECHO,

      PS_HTTPACTION_TYPE,
      PS_HTTPACTION_RESULT,
      PS_HTTPACTION_LENGTH,

      PS_HTTPREAD_LENGTH,
      PS_HTTPREAD_CONTENT
    };

    enum _actionState {
      AS_IDLE,
      AS_WAITING_FOR_RESPONSE
    };

    byte actionState = AS_IDLE;
    unsigned long lastActionTime = 0;

    byte parseState = PS_DETECT_MSG_TYPE;
    char buffer[80],url[80];
    byte pos = 0;

    int contentLength = 0;

    void resetBuffer() {
      memset(buffer, 0, sizeof(buffer));
      pos = 0;
    }

    void sendGSM(const char* msg, int waitMs = 500) {
      GSM.println(msg);
      while(GSM.available()) {
        parseATText(GSM.read());
      }
      delay(waitMs);
    }

    void setup()
    {
      GSM.begin(9600);
      Serial.begin(9600);
      gpsPort.begin(GPSBaud);

      Serial.println(F("GPS LOADING....."));
      Serial.println(F("Testing by : "));
      Serial.println(F("Billa"));
      Serial.println();

      sendGSM("AT+SAPBR=3,1,\"APN\",\"vodafone\"");
      sendGSM("AT+SAPBR=1,1",3000);
      sendGSM("AT+HTTPINIT");
      sendGSM("AT+HTTPPARA=\"CID\",1");
    }

    void loop()
    {
      unsigned long now = millis();

      while (gps.available( gpsPort )) {
        fix = gps.read();

        // Once every 5 seconds...
        if (++fixCount >= 5) {
          displayInfo();
          fixCount = 0;
        }
      }

      if ((gps.statistics.chars < 10) && (millis() > 5000)) {
         Serial.println( F("No GPS detected: check wiring.") );
         while(true);
         block=1;
        }
      }

      if ( actionState == AS_IDLE ) {
        if ( now > lastActionTime + 5000 ) {
          sprintf(url, "AT+HTTPPARA=\"URL\",\"http://*****.000webhostapp.com/hinderset.php?date=%s\"", dt); // passing date only now as part of testing
          sendGSM(url);
          sendGSM("AT+HTTPACTION=0");
          lastActionTime = now;
          actionState = AS_WAITING_FOR_RESPONSE;
        }
      }

      while(GSM.available()) {
        lastActionTime = now;
        parseATText(GSM.read());
      }
    }

    void displayInfo()
    {
      Serial.print(F("Location: "));
      if (fix.valid.location) {
        Serial.print( fix.latitude(), 5 );
        Serial.print( ',' );
        Serial.print( fix.longitude(), 5 );
      } else {
        Serial.print(F("INVALID"));
      }

      Serial.print(F("  Speed: "));
      if (fix.valid.speed) {
        Serial.print(fix.speed_kph());
        Serial.print(F(" KMPH "));
      } else {
        Serial.print(F("INVALID"));
      }

      // Shift the date/time to local time
      NeoGPS::clock_t localSeconds;
      NeoGPS::time_t  localTime;
      if (fix.valid.date && fix.valid.time) {
        using namespace NeoGPS; // save a little typing below...

        localSeconds = (clock_t) fix.dateTime; // convert structure to a second count
        localSeconds += 5 * SECONDS_PER_HOUR + 30 * SECONDS_PER_MINUTE; // shift timezone
        localTime = localSeconds;              // convert back to a structure
      }

      Serial.print(F("  Date : "));
      if (fix.valid.date) {
        sprintf(dt,"d/d/20%d",fix.dateTime.date,fix.dateTime.month,fix.dateTime.year);
        Serial.print(dt);
      } else {
        Serial.print(F("INVALID"));
      }

      Serial.print(F("  Time : "));
      if (fix.valid.time) {
        if (localTime.hours>12)localTime.hours-=12;//To convert 24 hr format to 12 hr format
        sprintf(tm,"d:d:d",localTime.hours,localTime.minutes,localTime.seconds);
        Serial.print(tm);
      } else {
        Serial.print(F("INVALID"));
      }

      Serial.println();
    }

    void parseATText(byte b) {

      buffer[pos++] = b;

      if ( pos >= sizeof(buffer) )
        resetBuffer(); // just to be safe

      /*
       // Detailed debugging
       Serial.println();
       Serial.print("state = ");
       Serial.println(state);
       Serial.print("b = ");
       Serial.println(b);
       Serial.print("pos = ");
       Serial.println(pos);
       Serial.print("buffer = ");
       Serial.println(buffer);*/

      switch (parseState) {
      case PS_DETECT_MSG_TYPE:
        {
          if ( b == '\n' )
            resetBuffer();
          else {
            if ( pos == 3 && strcmp(buffer, "AT+") == 0 ) {
              parseState = PS_IGNORING_COMMAND_ECHO;
            }
            else if ( b == ':' ) {
              //Serial.print("Checking message type: ");
              //Serial.println(buffer);

              if ( strcmp(buffer, "+HTTPACTION:") == 0 ) {
                Serial.println("Received HTTPACTION");
                parseState = PS_HTTPACTION_TYPE;
              }
              else if ( strcmp(buffer, "+HTTPREAD:") == 0 ) {
                Serial.println("Received HTTPREAD");
                parseState = PS_HTTPREAD_LENGTH;
              }
              resetBuffer();
            }
          }
        }
        break;

      case PS_IGNORING_COMMAND_ECHO:
        {
          if ( b == '\n' ) {
            Serial.print("Ignoring echo: ");
            Serial.println(buffer);
            parseState = PS_DETECT_MSG_TYPE;
            resetBuffer();
          }
        }
        break;

      case PS_HTTPACTION_TYPE:
        {
          if ( b == ',' ) {
            Serial.print("HTTPACTION type is ");
            Serial.println(buffer);
            parseState = PS_HTTPACTION_RESULT;
            resetBuffer();
          }
        }
        break;

      case PS_HTTPACTION_RESULT:
        {
          if ( b == ',' ) {
            Serial.print("HTTPACTION result is ");
            Serial.println(buffer);
            parseState = PS_HTTPACTION_LENGTH;
            resetBuffer();
          }
        }
        break;

      case PS_HTTPACTION_LENGTH:
        {
          if ( b == '\n' ) {
            Serial.print("HTTPACTION length is ");
            Serial.println(buffer);

            // now request content
            GSM.print("AT+HTTPREAD=0,");
            GSM.println(buffer);

            parseState = PS_DETECT_MSG_TYPE;
            resetBuffer();
          }
        }
        break;

      case PS_HTTPREAD_LENGTH:
        {
          if ( b == '\n' ) {
            contentLength = atoi(buffer);
            Serial.print("HTTPREAD length is ");
            Serial.println(contentLength);

            Serial.print("HTTPREAD content: ");

            parseState = PS_HTTPREAD_CONTENT;
            resetBuffer();
          }
        }
        break;

      case PS_HTTPREAD_CONTENT:
        {
          // for this demo I'm just showing the content bytes in the serial monitor
          Serial.write(b);

          contentLength--;

          if ( contentLength <= 0 ) {

            // all content bytes have now been read

            parseState = PS_DETECT_MSG_TYPE;
            resetBuffer();

            Serial.print("\n\n\n");

            actionState = AS_IDLE;
          }
        }
        break;
      }
    }

When I tested them in separate modules they worked and obtained result But now When I wrote the above code it is showing me "NO GPS DETECTED".Can you please help me in resolving the problem.The objective is I need to **obtain the output from GPS at every 5 secs** (5 secs interval between each output) and store them into database using GSM module

body:
### There are three problems:

**1)** You are using `delay`.

**2)** You are *still* using `SoftwareSerial`.  It blocks interrupts for long periods of time, interfering with other parts of your sketch.  I told you this in [your previous post](https://stackoverflow.com/questions/43006844).

**3)** Starting the HTTP action is not synchronized with the GPS clock.  The Arduino `millis()` clock is not synchronized with the GPS atomic clock.  They will drift in and out of sync over time.  I also told you this in the same previous post.

### The solution:

**1)** Don't use `delay`.  The GPS device continues to send characters, and they get dropped when the Arduino is blocked at the `delay`.

Instead, just send the command and let your nice `parseATTText` handle the response as it comes in, without waiting.  If there are multiple commands to send, add an extra state for each command.  When a response for the first command arrives, send the second command *and* step to the next state.

You can use `delay` in `setup` if you don't care about the responses to those initial commands.  Or you could add one SETUP_xxx state for each command to your FSM and let them happen in `loop`.  `parseATTText` will advance through those STARTUP states, sending each of those commands.

**2)**  Use [NeoSWSerial](https://github.com/SlashDevin/NeoSWSerial).

**3)**  Move the HTTPPARA command into the GPS loop with `displayInfo`:

      while (gps.available( gpsPort )) {
        fix = gps.read();

        // Once every 5 seconds...
        if (++fixCount >= 5) {
          displayInfo();

          // Send the next report if the previous one is finished
          if ( actionState == AS_IDLE ) {
            sprintf(url, "AT+HTTPPARA=\"URL\",\"http://*****.000webhostapp.com/hinderset.php?date=%s\"", dt); // passing date only now as part of testing
            sendGSM(url);
            parseState = PS_HTTPPARA_RESPONSE; // a new state
            actionState = AS_WAITING_FOR_RESPONSE;
          }

          fixCount = 0;
        }
      }

You should move `sendGSM("AT+HTTPACTION=0")` into `parseATTText` as a `case PS_HTTPPARA_RESPONSE`, and step to the next state (PS_DETECT_MSG_TYPE?)

If you reset `fixCount` inside the `if (actionState == IDLE)` block, it will send a new location when the previous one finally completes, perhaps after 6 new fixes.

Resetting  `fixCount` outside the block (as above) means it may send the 5th location, skip the 10th because it's NOT IDLE, and then send the 15th location.  If you want it to send the 5th, then the 11th if it's not busy, reset `fixCount` inside the `if` block.