Menu with switch case not behaving correctly I hope this the right place to post this question :)

I'm trying to display a menu on a SSD1351 OLED display, to which I communicate with U8glib. I'm trying to obtain an Init screen, then, with a long press on a button (Menu), get in to a menu with 3 options (let's say option1, option2 and back). I got it working this way:

#include <Button.h>  // https://github.com/JChristensen/Button.git
#include "U8glib.h"
#include <Wire.h>

#define PULLUP true
#define INVERT true
#define DEBOUNCE_MS 20

Button ok(2, PULLUP, INVERT, DEBOUNCE_MS);
Button menu(5, PULLUP, INVERT, DEBOUNCE_MS);
Button down(3, PULLUP, INVERT, DEBOUNCE_MS);
Button up(4, PULLUP, INVERT, DEBOUNCE_MS);
U8GLIB_SSD1351_128X128_332 u8g(8, 9, 7);
uint8_t screen = 0;
uint8_t menu_current = 0;
void setup() {
  u8g.setFont(u8g_font_unifont);
  u8g.setDefaultForegroundColor();
  drawScreen();
}

void loop() {
  ok.read();
  menu.read();
  up.read();
  down.read();
  if (menu.pressedFor(1000) && screen == 0) {
    screen = 1;
    menu_current = 0;
    drawScreen();
  }
  if (screen == 1) {
    if (up.wasReleased()) {
      if (menu_current > 0) {
        menu_current--;
        drawScreen();
      }
    }
    if (down.wasReleased()) {
      if (menu_current < 2) {
        menu_current++;
        drawScreen();
      }
    }
    if (ok.wasReleased()) {
      switch (menu_current) {
        case 0:
          screen = 2;
          break;
        case 1:
          screen = 3;
          break;
        case 2:
          screen = 0;
          break;
          break;
      }
      drawScreen();
    }
  }
  if (screen == 2 || screen == 3) {
    if (menu.wasReleased()) {
      screen = 1;
      menu_current = 0;
      drawScreen();
    }
  }
}

void drawScreen() {
  u8g.firstPage();
  do {
    whatToDraw();
  } while (u8g.nextPage());
}

void whatToDraw() {
  switch (screen) {
    case 0: {
        u8g.drawStr(0, u8g.getFontLineSpacing(), F("Init"));
      } break;
    case 1: {
      const char *menu_strings[3] = { "option1", "option2", "Back" };
      uint8_t i, h;
      u8g_uint_t w, d;
      u8g.setFontRefHeightText();
      u8g.setFontPosTop();
      h = u8g.getFontAscent() - u8g.getFontDescent();
      w = u8g.getWidth();
      for ( i = 0; i < 3; i++ ) {
        d = (w - u8g.getStrWidth(menu_strings[i])) / 2;
        u8g.setDefaultForegroundColor();
        if ( i == menu_current ) {
          u8g.drawBox(0, i * h + 1, w, h);
          u8g.setDefaultBackgroundColor();
        }
        u8g.drawStr(d, i * h, menu_strings[i]);
      }
    }
    break;
    case 2: {
      u8g.drawStr(0, u8g.getFontLineSpacing(), F("Option1"));
    }
    break;
    case 3: {
      u8g.drawStr(0, u8g.getFontLineSpacing(), F("Option2"));
    }
    break;
    break;
  }
}

Everything seems to be working except the back option: when I select it, the display gets blanked instead of visualizing screen 0 ("Init"). Variables seem to be set correctly. Does anybody have an idea why this isn't working?

Thank you :)

Dario

EDIT: copied the whole sketch as requested :)

Summary: I tested @noospy project (with some modifications) and it works flawlessly.

I had to rename Button.h to ButtonM.h due name conflict with another button library. Also, I'm using new version U8g2, so I had to change some types and eliminate some calls. Finally, I used the I2C version of the OLED screen.

This is my adapted code:

#include <ButtonM.h>  // https://github.com/JChristensen/Button.git
#include "U8g2lib.h"
#include <Wire.h>

#define PULLUP true
#define INVERT true
#define DEBOUNCE_MS 20

Button ok(2, PULLUP, INVERT, DEBOUNCE_MS);
Button menu(5, PULLUP, INVERT, DEBOUNCE_MS);
Button down(3, PULLUP, INVERT, DEBOUNCE_MS);
Button up(4, PULLUP, INVERT, DEBOUNCE_MS);

//U8GLIB_SSD1351_128X128_332 u8g(8, 9, 7);
// Screen
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

uint8_t screen = 0;
uint8_t menu_current = 0;

void setup() {
    u8g.begin(); // Added
    u8g.setFont(u8g_font_unifont);
//  u8g.setDefaultForegroundColor();

    drawScreen();
}

void loop() {
    ok.read();
    menu.read();
    up.read();
    down.read();

    if (menu.pressedFor(1000) && screen == 0) {
        screen = 1;
        menu_current = 0;
        drawScreen();
    }

    if (screen == 1) {
        if (up.wasReleased()) {
            if (menu_current > 0) {
                menu_current--;
                drawScreen();
            }
        }

        if (down.wasReleased()) {
            if (menu_current < 2) {
                menu_current++;
                drawScreen();
            }
        }

        if (ok.wasReleased()) {
            switch (menu_current) {
                case 0:
                    screen = 2;
                    break;
                case 1:
                    screen = 3;
                    break;
                case 2:
                    screen = 0;
                    break;
                break;
            }
            drawScreen();
        }
    }

    if (screen == 2 || screen == 3) {
        if (menu.wasReleased()) {
            screen = 1;
            menu_current = 0;
            drawScreen();
        }
    }
}

void drawScreen() {
    u8g.firstPage();
    do {
        whatToDraw();
    } while( u8g.nextPage() );
}

void whatToDraw() {
    switch (screen) {
        case 0: {
            u8g.drawStr(0,getFontLineSpacing(),"Init");
        } break;
        case 1: {
            const char *menu_strings[3] = { "option1", "option2", "Back" };
            uint8_t i, h;
            int w, d;

            u8g.setFontRefHeightText();
            u8g.setFontPosTop();

            h = u8g.getFontAscent()-u8g.getFontDescent();
            w = u8g.getWidth();
            for( i = 0; i < 3; i++ ) {
                d = (w-u8g.getStrWidth(menu_strings[i]))/2;
//                u8g.setDefaultForegroundColor();
                if ( i == menu_current ) {
                    u8g.drawBox(0, i*h+1, w, h);
//                    u8g.setDefaultBackgroundColor();
                }
                u8g.drawStr(d, i*h, menu_strings[i]);
            }
         } break;

         case 2: {
             u8g.drawStr(0,getFontLineSpacing(),"Option1");
         } break;

         case 3: {
             u8g.drawStr(0,getFontLineSpacing(),"Option2");
         } break;

         break;
    }
}

int getFontLineSpacing() {
  return 24;
}

Hardware

Arduino Pro Mini 3.3v 8MHz
1306 0.96 inch White Color I2C IIC Communication 128 * 64 OLED Display.
4x push buttons with 1K pullup resistors.

So, I don't know what your problem is, but your code is impecable.


GPS(Incorrect time showing) Anyone help? It shows incorrect time. Please help.

  /* Conexion pines
     Arduino        GPS
        D3           RX
        D4           TX
  */

  #include <SoftwareSerial.h>  //incluimos SoftwareSerial
  #include <TinyGPS.h>         //incluimos TinyGPS

  TinyGPS gps;  //Declaramos el objeto GPS
  SoftwareSerial serialgps(10,11);      //Declaramos el pin 4 (Tx del GPS) y 3 (Rx del GPS)

  //Declaramos la variables para la obtención de datos
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long chars;
  unsigned short sentences, failed_checksum;

  void setup()
  {
   Serial.begin(9600);  //Iniciamos el puerto serie
   serialgps.begin(9600); //Iniciamos el puerto serie del gps

   //Imprimimos en el monitor serial:
   Serial.println("");

  }

  void loop()
  {
   while(serialgps.available())
   {
    int c = serialgps.read();
    if(gps.encode(c))
    {
     float latitude, longitude;
     gps.f_get_position(&latitude, &longitude);
     Serial.print("Latitud/Longitud: ");
     Serial.print(latitude,5);
     Serial.print(", ");
     Serial.println(longitude,5);
     gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);
     Serial.print("Date: "); Serial.print(day, DEC); Serial.print("/");
     Serial.print(month, DEC); Serial.print("/"); Serial.print(year);
     Serial.print(" Time: "); Serial.print(hour, DEC); Serial.print(":");
     Serial.print(minute, DEC); Serial.print(":"); Serial.print(second, DEC);
     Serial.print("."); Serial.println(hundredths, DEC);
     Serial.print("Altitud (metros): "); Serial.println(gps.f_altitude());
     Serial.print("Rumbo (grados): "); Serial.println(gps.f_course());
     Serial.print("Velocidad(kmph): "); Serial.println(gps.f_speed_kmph());
     Serial.print("Satelites: "); Serial.println(gps.satellites());
     Serial.println();
     gps.stats(&chars, &sentences, &failed_checksum);

     delay(10000);
    }
   }
  }

Like Majenko's comments suggested, you must shift the UTC time to your local time.  The Time library can help you do this.

There are some other problems:

You cannot wait 10 seconds without processing the characters. The Arduino receive buffer only has room for 64 characters. The GPS device could have sent 10000 characters during that time, so most of them will get dropped. This prevents the GPS library from parsing a GPS data successfully.  It will eventually "see" a complete set of data, sometime after the 10 seconds.  You may see data once every 11 seconds, not 10.
You are printing the several values even though they may not be valid.  For example, if you are not moving, or you do not have good satellite reception, the GPS device may not provide a speed.
The Arduino millis() clock will not be synchronized with the GPS clock. You could use the GPS updates as an exact 1-second clock. Simply count 10 fixes as they arrive, and this will mean that 10 seconds have elapsed.
You should use a different serial port and/or library. This answer describes the various choices: HardwareSerial (i.e. Serial on pins 0 & 1), AltSoftSerial (8 & 9 on an UNO) or NeoSWSerial (any two pins).

Here is a NeoGPS version of your sketch that addresses these issues:

#include <NeoSWSerial.h>
#include <NMEAGPS.h>

NMEAGPS gps;  //Declaramos el objeto GPS
gps_fix fix;  // all GPS fields, including date/time, location, etc.
uint8_t fixCount;
NeoSWSerial serialgps(10,11);

void setup()
{
 Serial.begin(9600);  //Iniciamos el puerto serie
 serialgps.begin(9600); //Iniciamos el puerto serie del gps

 //Imprimimos en el monitor serial:
 Serial.println( F("Test") );

}

void loop()
{
 // Check for GPS characters and parse them
 if (gps.available( serialgps ))
 {
  // Once per second, a complete GPS fix structure is ready.  Get it.
  fix = gps.read();

  // Count elapsed seconds
  fixCount++;

  if (fixCount >= 10)
  {
    fixCount = 0; // reset counter

    // adjust from UTC to local time
    if (fix.valid.time)
      adjustTime( fix.dateTime );

    printGPSdata();
  }
 }
}

void printGPSdata()
{
  Serial.print( F("Latitud/Longitud: ") );
  if (fix.valid.location) {
    Serial.print( fix.latitude(), 5 );
    Serial.print( F(", ") );
    Serial.print( fix.longitude(), 5 );
  }
  Serial.println();

  Serial.print( F("Date: ") );
  if (fix.valid.date) {
    Serial.print( fix.dateTime.date  ); Serial.print('/');
    Serial.print( fix.dateTime.month ); Serial.print('/');
    Serial.print( fix.dateTime.year  );
  }

  Serial.print( F(" Time: ") );
  if (fix.valid.time) {
    Serial.print( fix.dateTime.hours ); Serial.print(':');
    if (fix.dateTime.minutes < 10)
      Serial.print( '0' );
    Serial.print(fix.dateTime.minutes); Serial.print(':');
    if (fix.dateTime.seconds < 10)
      Serial.print( '0' );
    Serial.print( fix.dateTime.seconds );
    Serial.print('.');
    if (fix.dateTime_cs < 10)
      Serial.print( '0' );
    Serial.print( fix.dateTime_cs );
  }
  Serial.println();

  Serial.print( F("Altitud (metros): ") );
  if (fix.valid.altitude)
    Serial.print( fix.altitude() );
  Serial.println();

  Serial.print( F("Rumbo (grados): ") );
  if (fix.valid.heading)
    Serial.print( fix.heading() );
  Serial.println();

  Serial.print( F("Velocidad(kmph): ") );
  if (fix.valid.speed)
    Serial.print( fix.speed_kph() );
  Serial.println();

  Serial.print( F("Satelites: ") );
  if (fix.valid.satellites)
    Serial.println( fix.satellites );
  Serial.println();
  Serial.println();
}

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

void adjustTime( NeoGPS::time_t & dt )
{
  NeoGPS::clock_t seconds = dt; // convert date/time structure to seconds

  // Offset to the local time
  const int32_t          zone_hours  = +8L;
  const NeoGPS::clock_t  zone_offset = zone_hours * NeoGPS::SECONDS_PER_HOUR;
  seconds += zone_offset;

  dt = seconds; // convert seconds back to a date/time structure

} // adjustTime

If you want to try it, NeoGPS, AltSoftSerial and NeoSWSerial are available from the IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries. NeoGPS is smaller, faster, more reliable and more accurate than all other GPS libraries.

Even if you don't use it, there are many suggestions on the Installation and Troubleshooting pages.


Serial string readout analyzed and logged onto an SD card I have a sensor that gives me this string, serially read @9600:

@T;+019.8;H;043.6;51

This burst arrives automatically about every second. It means:

"@" start of the string
"T;" means the Temperature is coming now, after that ";".
"+019.8" the Temp value (fixed number of digits, with a leading +/- sign.
";" separator.
"H;" means the Humidity value is coming now after the ";".
"043.6" the Humidity value (fixed number of digits: so 000.0 to 100.0).
";" separator.
"51" is a 2 digit checksum.

Then a pause of about 1 second >> next string with new values.
I want to Serial.print them separately, and put then into a log file on the SD card of the Arduino Ethernet Shield.

On a next step I will show these values on a local display and a webpage, and add (resettable) alarm settings with individual hysteresis settings...

Any advice to solve this string-breakup and SD card logging?

There are a number of ways that this can be accomplished.

If the string is always of a fixed length and the characters are always in the same place (this may require packing), then you could:

pull the required sections out, one character at a time, using the char array (i.e. string) index. However, in this case, this is rather long-winded and clumsy solution
Similar to above, use strncpy() to copy contiguous characters, see Given a starting and ending indices, how can I copy part of a string in C?
A more elegant method would be to use sprintf(), see How to copy a string into a char array in C++ without going over the buffer

Or you can use regular expressions (regexp) and patten matching. See How to read response from server using an Ethernet shield?
use sscanf, see Extract binary data from text string. Like Perl pack, not just regexp


Error Compiling for board Arduino Nano while using Adafruit GFX Whys is this happening to me??
I have to meet a deadline please help!!
Here is my code.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for SSD1306 display connected using software SPI (default case):
#define OLED_MOSI   11
#define OLED_CLK   12
#define OLED_DC    9
#define OLED_CS    8
#define OLED_RESET 10
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
  OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);
void setup()
{
  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
}

  display.display();
  delay(2000);

  display.clearDisplay();

  display.drawPixel(10, 10, SSD1306_WHITE);

  display.display();
  delay(2000);
  display.invertDisplay(true);
  delay(1000);
  display.invertDisplay(false);
  delay(1000);

  }
void loop()
{
drawLine(20,60,5,50,256);

}

The Error

C:\Users\hp\AppData\Local\Temp\ccyB6dO1.ltrans0.ltrans.o: In function
loop': C:\Users\hp\Desktop\Sunfox\Sunfox\BP_Plus_ECG\February_11\OLED_Testing_w_Adafruit\Test_2\Test_2/Test_2.ino:51: undefined reference to drawLine(unsigned int, unsigned int, unsigned
int, unsigned int, unsigned int)' collect2.exe: error: ld returned 1
exit status exit status 1 Error compiling for board Arduino Nano.

Currently, you defined a forward declaration for drawLine, however I assume you want to call the method (function) inside display.
So change
drawLine(20,60,5,50,256);

into
display.drawLine(20,60,5,50,256);

And you can remove the forward declaration, because this method is already defined in the library.
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);

Note, if you call drawLine without an instance (which is display), then the linker tries to find the drawLine function which it cannot find, so you get a linker error (see ld returned in your error, together with undefined reference).


Signal a LOW level interrupt with an RTC I'm trying to figure out how to use an RTC to send interrupts to my arduino. I'm using a DS3232. I can get an 'edge' interrupt, with the following toy code (I know the code is silly, it's just a short example to test if I have actually set the RTC to send the interrupt, and that the Arduino receives it):

/*----------------------------------------------------------------------*
 * Minimal example of setting a recurring alarm with the DS3232 RTC     *
 * Attach an LED to pin 7, which will flash when the alarm fires.       *
 *                                                                      *
 * Attach the RTC SQ/INT pin to Uno pin 2, with a 10K pull-up to VCC.   *
 * Ard pin A4 -> RTC SDA, Ard A5 -> RTC SCL, 5v -> vcc, GND -> GND      *
 *----------------------------------------------------------------------*/

#include <DS3232RTC.h>        //http://github.com/JChristensen/DS3232RTC
#include <Time.h>             //http://playground.arduino.cc/Code/Time
#include <Wire.h>             //http://arduino.cc/en/Reference/Wire

#define WAKE_PIN 2
#define LED_PIN 7

void setup(void)
{
    pinMode(LED_PIN, OUTPUT);

    // RTC config:
    RTC.squareWave(SQWAVE_NONE);
    pinMode(WAKE_PIN, INPUT_PULLUP);
    attachInterrupt(INT0, wakeUp, FALLING);
    RTC.setAlarm(ALM2_EVERY_MINUTE, 0, 0, 0, 1);
    RTC.alarm(ALARM_2);
    RTC.alarmInterrupt(ALARM_2, true);
}

void loop(void)
{
  if(RTC.alarm(ALARM_2)){
    digitalWrite(LED_PIN, HIGH);
    delay(5000);
    digitalWrite(LED_PIN, LOW);
  }

}

void wakeUp (){
// no-op, just checking if the interrupt fired
}

Why doesn't this work if I set the interupt to "LOW", ie., attachInterrupt(INT0, wakeUp, LOW);?

The reason I ask is I'm trying to use an RTC to wake from low power mode, and I think this doesn't work with a 'falling' interrupt.

That page is incorrect, although it reflects what the datasheet says.
The processor can be woken from RISING/FALLING/CHANGE/LOW. I queried this with Atmel and got this response:

Commented by Manoraj Gnanadhas (Atmel)
2015-01-20 06:23:36 GMT
[Recipients: Nick Gammon]
Hello Nick,
Our design team has confirmed that “Note-3 mentioned under Table 10-1” is a datasheet bug. So you can use any type of interrupt (Rising edge/ Falling edge / Low level / Any logical change) to wake up from sleep mode. Sorry for the inconvenience caused.
Best Regards,
Manoraj Gnanadhas

This is mentioned on my page about interrupts.

Why does LOW hang the processor? The LOW interrupt is not an edge interrupt but a continuous one. Thus, while the signal is LOW the interrupt is being continually called, with only one processor instruction being executed after each call to the ISR (which itself takes around 5.125 µs). So, the ISR is not being interrupted, but effectively only one instruction of your code is being executed every 5.125 µs (probably about 1/40th of the usual speed).

and see how much of my problem is due to using an old and buggy IDE

It's nothing to do with the IDE. Change to a FALLING interrupt and your problems should go away. You may also want to clear the interrupt flag (as documented on my page) in case the interrupt event has already happened before you go to sleep. Specifically:
EIFR = bit (INTF0);  // clear flag for interrupt 0


Problems with compiling more then one sketch in the Arduino IDE I found this ESP8266-MQTT program on Github.
How can I compile this thing with the Arduino IDE?
I only can open one sketch at a time. If I try to compile this then parts of the program are missing for AVRDUDE - but they are in the same folder.
Please can you help me?

That sketch is written for the ESP8266, not the ESP32. The two are very different chips, and the libraries used are very different.
You will have to learn how the sketch works, and how the ESP32 libraries work, and port the sketch to the ESP32 once you have learned how.


Looking for circuit diagram for evaluation of a pulsed signal How can I evaluate a pulsed signal in Arduino? The signal comes from an car alarm system and is called (-) output 200 mA. Arduino and the car have the same GND. Can I attach the output through a resistor to PB0 (D8) or PD5 (D5)?
Alarm system is called Ampire. Probably the same as Viper. I just wanted to read these pulses, but I do not know exactly how I connect this output correctly with Arduino.
This is the description for this Output:

HN1/9 BROWN/WHITE – 200mA (-) Horn honk output: This wire supplies a 200mA (-) output that can be used to honk the vehicle’s horn. It provides a pulsed output when the security system is armed/disarmed and in trigger sequence or in panic mode. In most vehicles with (-) horn circuits this wire can control the vehicle’s horn without adding a relay. If the vehicle has a (+) horn circuit, an optional relay must be used to interface with the vehicle’s horn circuit.

I found a user manual at AMPIRE Car Alarm System for High-Speed CAN-Bus.

  N1/9 BROWN/WHITE – 200mA (-) Horn honk output:

  This wire supplies a 200mA (-) output that can be
  used to honk the vehicle’s horn. It provides a pulsed output when the security system is armed/disarmed
  and in trigger sequence or in panic mode. In most vehicles with (-) horn circuits this wire can control the
  vehicle’s horn without adding a relay. If the vehicle has a (+) horn circuit, an optional relay must be used
  to interface with the vehicle’s horn circuit.

  IMPORTANT!
   Never use this wire to drive anything but a relay or a low-current input! This transistorized output can only supply (-) 200mA and connecting directly to a solenoid, motor or other high current device will cause the module to fall

Judging by that this output will sink up to 200 mA. You could conceivably set an Arduino pin to INPUT_PULLUP and let this output drive it low to indicate it is active.

Personally I think I would use an optocoupler, in case there were unexpected voltages on that pin. You would need a series resistor to limit current through the LED in the optocoupler, say 1 k would be about right if you were connecting it to the 12V car system.

Vf = 1.2V (say)
Voltage over resistor = 12 - 1.2 = 10.8 volts
Current through LED = 10 mA
Limiting resistor = 10.8 / 0.01 = 1080 ohms

Now the output of the optocoupler can sink your Arduino pin, which you have configured as input pullup.

Write a test sketch to see what you are getting through it, but a multimeter should probably tell you, if it just flashes it slowly.

Suggested schematic:


I can't upload sketches to my Arduino 101 When connected to USB green Power LED on but doesn't upload sketch(that says press master reset therefore i've pressed several time but timeout). And main thing is device doesn't show in device manager.(I'm working on windows10).

Have I "bricked" it?
What steps can I take to work out what is wrong?
What can I do to fix it?

I've search in many sites but doesn't give me detail about hardware repairing guide for arduino 101.

I've checked working usb cable and another laptop but not work.I think hardware problem.Once arduino getting hot near usb.

It's hard to tell, but you can try a lot of options:

Use another USB port
Use another USB cable
Reinstall the Arduino IDE
Remove the device in the device manager and try reinstalling the Arduino IDE again
Try another Arduino (to see if the USB/install is ok)
Try on a different computer/laptop


Looking to optimize this code and add a loop So I want to optimize this code and add a loop to the two red LEDs. The process is green LED is flashing, press button, yellow LED blink for 3 secs and then alternate flashing between the two red LEDs until the button is released.
 int switchState = 0;
    int green = 3;
    int yellow = 4;
    int red1 = 5;
    int red2 = 6;
    int button = 2;

    void setup()
    {
      pinMode(green, OUTPUT) ;
      pinMode(yellow, OUTPUT) ;
      pinMode(red1, OUTPUT) ;
      pinMode(red2, OUTPUT) ;
      pinMode(button, INPUT) ;
    }

    void loop()

    { //start void loop 1
      switchState = digitalRead(button);

      if (switchState == LOW)         //button not pressed
      {
        digitalWrite(green, HIGH);      //green LED on
        digitalWrite(yellow, LOW);
        digitalWrite(red1, LOW);
        digitalWrite(red2, LOW);

        delay(500);

        digitalWrite(green, LOW);     //blink green LED

        delay(500);
      }//end if

      else        //Button pressed
      {

        digitalWrite(green, LOW);
        digitalWrite(yellow, HIGH);   //Blink yellow LED for 3 sec
        digitalWrite(red1, LOW);
        digitalWrite(red2, LOW);

        delay(250);

        digitalWrite(yellow, LOW);

        delay(250);

        digitalWrite(yellow, HIGH);

        delay(250);

        digitalWrite(yellow, LOW);

        delay(250);

        digitalWrite(yellow, HIGH);

        delay(250);

        digitalWrite(yellow, LOW);

        delay(250);

        digitalWrite(yellow, HIGH);

        delay(250);

        digitalWrite(yellow, LOW);

        delay(250);

        digitalWrite(yellow, HIGH);

        delay(250);

        digitalWrite(yellow, LOW);

        delay(250);

        digitalWrite(yellow, HIGH);

        delay(250);

        digitalWrite(yellow, LOW);

        delay(250);

        digitalWrite(yellow, HIGH);

        delay(250);

        digitalWrite(yellow, LOW);

        void loop()
        {

          digitalWrite(red1, HIGH);
          digitalWrite(red2, LOW);

          delay(250);

          digitalWrite(red1, LOW);
          digitalWrite(red2, HIGH);

          delay(250);

        }     //end void loop 2

      }     //end button press

    }     //end void loop 1

You could use a for loop so you don't need to repeat the yellow blinking led code 7 times.
To keep the red leds alternating, you use a while loop.
int switchState = 0;
int green = 3;
int yellow = 4;
int red1 = 5;
int red2 = 6;
int button = 2;

void setup()
{
  pinMode(green, OUTPUT) ;
  pinMode(yellow, OUTPUT) ;
  pinMode(red1, OUTPUT) ;
  pinMode(red2, OUTPUT) ;
  pinMode(button, INPUT) ;
}

void loop()

{ //start void loop 1
  switchState = digitalRead(button);

  if (switchState == LOW)         //button not pressed
  {
    digitalWrite(green, HIGH);      //green LED on
    digitalWrite(yellow, LOW);
    digitalWrite(red1, LOW);
    digitalWrite(red2, LOW);

    delay(500);

    digitalWrite(green, LOW);     //blink green LED

    delay(500);
  }//end if

  else        //Button pressed
  {

    digitalWrite(green, LOW);
    digitalWrite(red1, LOW);
    digitalWrite(red2, LOW);

    //Blink yellow LED for 3 sec
    for (byte i=0; i<7; i++)
    {
      digitalWrite(yellow, HIGH);
      delay(250);
      digitalWrite(yellow, LOW);
      delay(250);
    }

    // alternate the two red leds, while the button is pressed
    while (digitalRead(button) == HIGH)
    {
      digitalWrite(red1, HIGH);
      digitalWrite(red2, LOW);
      delay(250);

      digitalWrite(red1, LOW);
      digitalWrite(red2, HIGH);
      delay(250);

    }     //end while loop

  }     //end button press

}     //end void loop


Why does the PIN 13 LED of Uno R3 blink every time I upload some code? I was driving a relay from Arduino Uno R3 Pin 13. I observed that every time I upload some code the led on the board designating pin 13 would blink. I'm curious why this is so. I understand that the serial LED blinks cause there's a serial transmission but why an IO pin?

See What happens when code is uploaded using the bootloader? - the flashing is by design.

Probably the reason is to confirm that the bootloader has started.


How to concatenate strings I am new to the Arduino platform so please bear with me. I have a program to display rolling text on a LED matrix which is for the Tinyduino platform

#include "Charliplexing.h"
#include "Font.h"
#include "Arduino.h"

void setup()
{
  LedSign::Init();
}

static char test[]="HELLO";

void loop()
{
  for (int8_t x=DISPLAY_COLS, i=0;; x--) {
    LedSign::Clear();
    for (int8_t x2=x, i2=i; x2<DISPLAY_COLS;) {
      int8_t w = Font::Draw(test[i2], x2, 0);
      x2 += w, i2 = (i2+1)%strlen(test);
      if (x2 <= 0)  // off the display completely?
        x = x2, i = i2;
    }
    delay(80);
  }
}

Then I have some code to read temperature and humidity data for the same Tinyduino platform

#include <Wire.h>
#include <SI7021.h>

SI7021 sensor;

void setup()
{
  Serial.begin(115200);
  Wire.begin();
  Serial.print("Initializing sensor... ");
  if(!sensor.begin()){
    Serial.println("Sensor not found!");
    while(true);
  }
  Serial.println("Success!");
}

void loop()
{
  int celcius=sensor.getCelsiusHundredths()/100;
  int relativeHumidity=sensor.getHumidityPercent();
  Serial.print(celcius);
  Serial.print(" deg Celsius\t");
  Serial.print(relativeHumidity);
  Serial.println("% relative humidity");

  delay(500);
}

I am trying to integrate this together so that Arduino reads the temperature and humidity sensor data and then displays it on the LED matrix as text. I have some code that is integrated from the above two examples

#include "Charliplexing.h"
#include "Font.h"
#include "Arduino.h"
#include <Wire.h>
#include <SI7021.h>

SI7021 sensor;

void setup()
{
  Serial.begin(115200);
  Wire.begin();
  Serial.print("Initializing sensor... ");
  if(!sensor.begin()){
    Serial.println("Sensor not found!");
    while(true);
  }
  Serial.println("Success!");
  LedSign::Init();
}

static char test[100]="";

void loop()
{
  int celcius=sensor.getCelsiusHundredths()/100;
  int relativeHumidity=sensor.getHumidityPercent();
  test=celcius+" deg celsius"+" "+relativeHumidity+" relative humidity";

  for (int8_t x=DISPLAY_COLS, i=0;; x--) {
    LedSign::Clear();
    for (int8_t x2=x, i2=i; x2<DISPLAY_COLS;) {
      int8_t w = Font::Draw(test[i2], x2, 0);
      x2 += w, i2 = (i2+1)%strlen(test);
      if (x2 <= 0)  // off the display completely?
        x = x2, i = i2;
    }
    delay(80);
  }
  delay(500);
}

Here is the error message that the IDE throws out

test:28: error: invalid operands of types 'const char*' and 'const char [2]' to binary 'operator+'

 test=celcius+" deg celsius"+" "+relativeHumidity+" relative humidity";
                             ^

Using library LOL in folder: C:\Program Files (x86)\Arduino\libraries\LOL (legacy)
Using library Wire at version 1.0 in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire
Using library Temp in folder: C:\Program Files (x86)\Arduino\libraries\Temp (legacy)
exit status 1
invalid operands of types 'const char*' and 'const char [2]' to binary 'operator+'

Any suggestions on how to resolve this error is welcome.

You cannot "add" character arrays like that. You may try to use a
String object instead, as these do support the + operator as a way
to concatenate them:

String message = (String(celcius) + " deg Celcius, "
               + relativeHumidity + " relative humidity");
const char *c_message = message.c_str();

And then you use c_message in place of your test variable.
Note that only the first element (celcius here) needs to be explicitly
converted to a String object. The other conversions happen implicitly.

Edit: Updated the code to avoid using the internal state of a
(possibly destroyed) temporary object.


Can I use a MCP23017 to connect multiple RC522 modules? I want to connect multiple (exactly 64) RFID-RC522 modules to one Nodemcu ESP8266.
I already know, that it is possible to connect multiple RC522's by just using different pins for the SDA pin, while the rest of the RC522 pins can be connected to the same pins on the ESP8266. But not that many, of course.
My research on "how do I get more pins", got me to the MCP23017 port expander.
Further research is not exactly clear, if I can use these pins as ChipSelect/SlaveSelect pins for the RC522.
The two libaries I found for MCP23017 (blemasle/arduino-mcp23017 and Adafruit-MCP23017 seem not to support this, when I use miguelbalboa/rfid (which I have to use, as there seems to be no alternative), because the MCP-Libs do not provide a "Pin Number" for the MFRC522 constructor(?).
So, is this just a "software" thing, or a technical limitation, and what I want is simply not possible? My research was not exactly clear about this, but I'm also very new to electronics and might be researching in the wrong direction.

Sure, you can use IO expanders for the chip-select pins of SPI devices. You will have to modify the device libraries to support them, though, because no one is going to do that by default unless it's a very very specific library.
However you will probably not have much luck with your project anyway, since you will more than likely run into problems with fan-out and bus capacitance before you even remotely approach 64 devices on your bus.
You would need to be adding extra bus drivers and partition your bus to reduce and spread the load - at which point it would be simpler and cheaper to just use multiple microcontrollers with just a few RC522s one each.


How to writte simple string compare? I new to Arduino and I'm attempting to writte a simple string compare code like this:

void loop()
{
  distance(cm);
  delay(200);
}

void distance(char[3] unit)
{
  if (unit[] == "cm")
    Serial.println("cm");
}

Could somebody please advise me how to writte it correctly?
Thanks in advance!

if (strcmp (unit,"cm") == 0) {

    // matches cm

}

For syntax like this the intellisense in products such as Atmel Studio or Visual Studio can really help. Whilst you still need to understand what you might be looking for the intellisense makes all the available Arduino functions visible from the code. If you install the Arduino plugin then there will be an Arduino reference explorer in both ide's which explains everything.


Why does "!=LOW" != "HIGH"? I'm learning about accessing ports directly on the ATMEGA 328 using an Arduino Uno. The program sets up pin 13 as an output and pin 2 as an input. I then enable the pull up resistor on pin 2.

I read Pin 2 and set the LED high or low depending on if pin 2 is high or low.

Why is it that I cannot seem to use == HIGH in my if statement instead of != LOW?

void setup() {
  MCUCR &= ~(1 << 4); //disables pull-up disable (redundant as default is off)
  DDRB |= (1 << 5); //sets pin 13 (B5 on ATMEGA 328) as output
  DDRD &= ~(1 << 2); //sets pin 2 (D2 on ATMEGA 328) as input (redundant as default is input)
  PORTD |= (1 << 2); //since it's an input sets pull-up resistor ON
  PORTB &= ~(1 << 5); //sets pin 13 (B5 on ATMEGA 328) as LOW

}

void loop() {
  if ((PIND & (1 << 2)) != LOW) PORTB |= (1 << 5); //sets pin 13 (B5 on ATMEGA 328) as HIGH
  else PORTB &= ~(1 << 5); //sets pin 13 (B5 on ATMEGA 328) as LOW
   delay(100);

}

Because

((PIND & (1 << 2)) != LOW)

means exactly

(PIND & 4) != 0

and that is true if PIND is 4, 5, 6, 7, 12, 13, ... (any number having 4 in it binary), so it yelds

4 != 0

Which is definitively not equal

4 == 1

BTW: in C any integer != 0 is true and 0 is false, so you can as well write:

if (PIND & (1 << 2)) PORTB |= (1 << 5); //sets pin 13 (B5 on ATMEGA 328) as HIGH


XBee on Arduino Fio - how to read the status of a local digital XBee output pin? I am using a Fio to control a set of relays. The unit uses an XBee (series 1 Pro) in transparent mode to receive commands over serial UART and everything works fine. The XBee is also configured for digital Input/Output Line Passing and the XBee on the Fio "mirrors" on an output pin the input state on a remote XBee and also this works fine.

How can I interrogate from the Fio the state of the output pin (e.g. D0) of the local (receiving) XBee? Is there an AT command that I could send via Serial.println("ATxx") that would trigger the XBee to send back over UART the status of the pin (high or low)?

You cannot read the state of output pins via an AT command, you can only read the state of input pins using the ATIS command.

See: http://ftp1.digi.com/support/documentation/90000982_S.pdf


Raspberry Pi 3B+ BLE communication to Arduino Nano 33 IOT I have an Arduino Nano 33 IOT and it uses BLE. I want it to talk to my Pi 3B+ and send all of its sensor data. I cannot figure out a way to do it using Python for the Pi and ArduinoBLE library for my Nano IoT. Is it possible?

For completeness, it appears an appropriate Python library can be installed with:
pip3 install adafruit-circuitpython-ble

The test code, used with the Arduino code 'Echo' from the ArduinoHardwareBLE library is below.  This was updated to let you choose the name of the device (here, MY_BLE)  rather than any random device that has UART capability.  It also allows you to send a small file from a few lines, with a "#" denoting a comment (first character in the line).  ESC and a return quits the program.
# Connect to an "eval()" service over BLE UART.

from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService

ble = BLERadio()

uart_connection = None

def send_stuff(s):
    uart_service.write(s.encode("utf-8"))
    uart_service.write(b'\n')
    readline=uart_service.readline().decode("utf-8")
    while(len(readline)>0):
        print(readline)
        readline=uart_service.readline().decode("utf-8")

while True:

    if not uart_connection:
        print("Trying to connect...")
        print("ESC then RETURN to exit.")
        for adv in ble.start_scan(ProvideServicesAdvertisement):
            if UARTService in adv.services:
                regular_name = adv.complete_name
                if(regular_name=='MY_BLE'):
                    uart_connection = ble.connect(adv)
                    print("Connected")
                    # for some reason, we have to read a line...
                    uart_service = uart_connection[UARTService]
                    print(uart_service.readline().decode("utf-8"))
                    break
        ble.stop_scan()

    if uart_connection and uart_connection.connected:
        uart_service = uart_connection[UARTService]
        while uart_connection.connected:
            s = input("Prompt: ")
            if(len(s)>0):
                if(ord(s[0])==27):
                    print("done.")
                    exit()
                else:

                    # Check if "!" character is used; if so, send contents of a file
                    if(s[0]=="!"):
                        print("sending commands")
                        count=0
                        file1=open('commands.txt','r')
                        Lines=file1.readlines()
                        for line in Lines:
                            count=count+1
                            tmp=line.strip()
                            if(len(tmp)>0):
                                if(tmp[0]=='#'):
                                    print("comment:" + tmp)
                                else:
                                    print("Line{}: {}".format(count, tmp))
                                    send_stuff(tmp)

                    else:
                        send_stuff(s)


Why are there two sets of tools and bootloaders in the Arduino IDE? After digging around on a separate problem, I found that avrdude, avr-gcc and some more tools can be found in two different locations:

(1): C:\Program Files\Arduino\hardware

(2): C:\Users\<user>\AppData\Local\Arduino15\packages\arduino

These two folders also both contain similar copies of the hardware directory where all the bootloader hex-files and source code is stored:

(3): C:\Program Files\Arduino\hardware\arduino\avr

(4): C:\Users\<user>\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.17

I say similar because the bootloaders\caterina folder in (4) contains quite a few hex-files that are missing in (3).

When burning a bootloader, looking at verbose output from the Arduino IDE reveals that hex-file and executable of avrdude from (2) are used, not (1).

What is the reason for this? My guess would be that location (1) is deprecated, but why choose to put stuff like this into Appdata in the first place?

Arduino IDE comes with a "platform" (the arduino AVR) in the Arduino\hardware folder.
Then you can add/upgrade platforms with the boards manager.
These will be installed in C:\Users\\AppData\Local\Arduino15\packages.
The reason for this is that Arduino IDE wants to be able to "work out of the box".
If they did not deliver the platform inside the installation/zip a "installation finishing" job needs to run after opening the Arduino IDE.


Connecting to the Sparkfun Redboard on Mac OS X Sierra I'm trying to connect to my Sparkfun Redboard (Arduino UNO compatible) on Mac OS X 10.12.3 (Sierra). The board comes with a USB mini to USB A FTDI cable. The board lights up and gets power over USB, but I don't see the right USB serial port in the Arduino IDE (I only see the Bluetooth port).

I've installed the VCP FTDI drivers v2.3 to no avail. When that didn't work, I also installed the CH340 CH341 drivers (but I doubt I need those). Rebooting the computer didn't help either.

I can only load the FTDI VCP v2.3 drivers using an explicit command sudo kextload /Library/Extensions/FTDIUSBSerialDriver.kext/. When I run kextstat | grep FTDI, I get:

 155    0 0xffffff7f83892000 0x7000     0x7000     com.FTDI.driver.FTDIUSBSerialDriver (2.3) ECC3AF36-431D-370D-86F2-5237785E9CF8 <127 41 5 4 3 1>

But it still doesn't show up in the Arduino IDE.

I've heard that Apple's own USB FTDI drivers (AppleUSBFTDI) could cause problems, but it seems these are never loaded. If I try to unload the Apple FTDI driver (sudo kextunload –b com.apple.driver.AppleUSBFTDI), I get the following:

(kernel) Kext com.apple.driver.AppleUSBFTDI not found for unload request.

Failed to unload com.apple.driver.AppleUSBFTDI - (libkern/kext) not found.

Any tips are welcome. Thanks!

I'm using MacOS Sierra and an Arduino Pro Mini (from Sparkfun) with a breakout USB-to-UART board that uses an FTDI FT232 chip. I'm using the default Apple FTDI drivers (the ones that are bundled with Sierra) and I'm having no problems whatsoever.

Some people have reported problems using the manufacturer (FTDI) drivers that they had already installed after upgrading to Sierra. Some of them solved it by uninstalling the conflicting drivers and relying on the default Apple FTDI drivers uninstalling the conflicting drivers and relying on the default Apple FTDI drivers instead. It's worth a try.

OTOH, the CG340 driver doesn't currently work under Mac OS Sierra. Fortunately, Adrian Mihalko patched the driver and made it available at GitHub, along with some troubleshooting instructions.


Is there a way to play .mp3 files from an SD card on Arduino? Is there a way to have mp3 files on an SD card in the SD card shield for the Arduino and play an mp3 file on that SD card with a buzzer?

If possible also with something like:

playmp3(thismp3.mp3);

So that if I execute that command, the Arduino will play thismp3.mp3 through a buzzer.

Thank you.

If you're not specifically trying to make the arduino itself do the decoding and playback, you can get something like the Mini DFPlayer which would let you do essentially what you're asking for and offloads the decoding and playback so your arduino can do something else while the audio is playing.


RC drag strip finish line with mph calculation (using 1" spaced lasers) My question is: how do I read multiple inputs at the same time without using interrupts on an UNO.  I'm building an RC drag strip with tree and finish line that will calculate run time as well as calculate each run in mph.  I'm using lasers and non modulated laser detectors for the beams and I'm using a 1" beam gap(between 1st beam and 2nd beam) at the finish line(for mph calculation). My concern comes in when two cars come close enough at the finish line for one to break the first beam at set the win flag but the car in the other lane is close enough to cross the 1st beam before the 1st car actually crosses the 2nd beam then the detection loop is going to miss one of them. (just a note: a few of these cars can top 100 mph when crossing the line)

ONE:

What you can do is use a while loop waiting for the first pulse and then wait until the last pulse, for an idea look at this code from Gadjet, he made a chronograph with a similar operation, you would just need to adapt the design, this might not be as accurate for an 1". Also it will be the issue of having ties between cars. This is short as I don't like this option.

TWO:

Another option, although using what you don't want to use, would be using the interrupts on the Arduino. I am basing the following on the fact that you are using two cars.

What you can do is have a finish line for both vehicles and detect a break with a interrupt, one interrupt pin per lane(UNO has to interrupts).

The trick here is that you place both the outputs from one lane onto a single interrupt pin with a edge detector type of circuit1 to generate a pulse while the vehicle crosses a point, especially important as it will be in the inch area for a while. The code handles the double pulse on one pin. I know this works as I used this on a ballistic chronograph which works in microseconds detecting shots >2000fps over a 0.406 foot distance.

1 This is an example of the circuit you would use at the output of each sensor before the OR gates:

The hardware would just become a duplicate for each lane, and to combine the input on one pin you can use an OR gate IC or you can use diode OR gate:

Interrupts are actually easy to use with Arduinos, and there are a lot of examples out there.

Have a look at the below flow chart to get an idea of operation in the code:

A small thing would be that the code ignores a interrupt once the cars have passed so it doesn't calculate a second time.


'serialWrite' was not declared in this scope Please help me! Once I click the upload button.
I get the following error:

  'serialWrite' was not declared in this scope

Here is my code:

int buttonPin
void setup ()
{
beginSerial(9600);
pinMode (buttonPin, INPUT);
}
void loop ()
{
if (digitalRead(buttonPin) == HIGH)
serialWrite('H');
else
serialwrite('L');
delay(1000);
}

It should be Serial.write to notice the period.

Which would make your code:

int buttonPin
void setup ()
{
    Serial.begin(9600);  # There was an error on this line as well
    pinMode (buttonPin, INPUT);
}
void loop ()
{
    if (digitalRead(buttonPin) == HIGH)
    Serial.write('H');
    else
    Serial.write('L');
    delay(1000);
}

Have a look at https://www.arduino.cc/en/Serial/Write for a complete example


Copying String into another String I have an array of Strings in my code:

String BitSequence [257];

Each string will have 23~64 characters. At one point in my code, I have to use "myString.remove()" command and I don't want to apply any changes to my original strings. I need to make a copy and perform my commands on the copied string. I did:

MycopyString = BitSequence [1];

but it doesn't work. What tricks do I need to do here to make a copy?

I don't want to apply any changes to my original strings

You should read about PROGMEM and/or the __FlashStringHelper ( F-Macro ) . Probably you can even handle that vast amount of constant texts on your Nano controller, which is meant to be a controller, not a text processing computer.


ESP32: Disable Brownout Detector I have an ESP-WROOM-32 and I'm using Arduino IDE to push code on it. My ESP is powered via 2 AA batteries and got one power supply problem.

It works well on new battery but after a bit, I will always get this error repeatedly:

  ets Jun  8 2016 00:22:57

  rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0,
  SPIWP:0xee
  clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
  mode:DIO, clock div:2 load:0x3fff0018,len:4 load:0x3fff001c,len:812
  load:0x40078000,len:0 load:0x40078000,len:11584 entry 0x40078a60

  Brownout detector was triggered

So, I know that it's possible to disable that feature in ESP32. My question is how to do it?

What I have done that didn't work:

Add this code in my Arduino IDE:

#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
setup(){
    WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
}

Change Arduino\hardware\espressif\esp32\tools\sdk\sdkconfig with:

CONFIG_BROWNOUT_DET=                //previous was "=y"
CONFIG_BROWNOUT_DET_LVL_SEL_0=      //previous was "=y"
CONFIG_BROWNOUT_DET_LVL_SEL_1=
CONFIG_BROWNOUT_DET_LVL_SEL_2=
CONFIG_BROWNOUT_DET_LVL_SEL_3=
CONFIG_BROWNOUT_DET_LVL_SEL_4=
CONFIG_BROWNOUT_DET_LVL_SEL_5=
CONFIG_BROWNOUT_DET_LVL_SEL_6=
CONFIG_BROWNOUT_DET_LVL_SEL_7=
CONFIG_BROWNOUT_DET_LVL=           //previous was "=0"

For me brownout issue was solved by removing the esp32 from Arduino IDE board manager + removing files from disk and use install procedure "Using Arduino IDE with the development repository" - https://github.com/espressif/arduino-esp32/

I guess it will use newer version of arduino-esp32 that has some brownout protection due to CONFIG_REDUCE_PHY_TX_POWER being activated by default. Also you should probably learn how to decrease wifi power + deep sleep for longer battery usage.


Does SMS format depend on the sender's mobile? I want to read the SMS using Arduino and GSM module, I want to perform conditional programming based on the received SMS.

What I found really interesting is SMS format is different if I send message from different phones.

Output of my code is

Case 1:(From a smartphone)

Mobile Number is: +91954xxxxxxx
Message Text: 5+22" Hello Arduino

Case 2:(From a normal phone)

Mobile Number is: +91984yyyyyyy
Message Text: Hello Arduino

Does it really depend on the sender's mobile phone? If yes, how to move further to make my code independent on the sender mobile.

My code is

//===final code

char RcvdMsg[200] = "";
int RcvdCheck = 0;
int RcvdConf = 0;
int index = 0;
int RcvdEnd = 0;
char MsgMob[15];
char MsgTxt[50];
int MsgLength = 0;

void Config() // This function is configuring our SIM900 module i.e. sending the initial AT commands
{
   delay(1000);
   Serial.print("ATE0\r");
   Response();
   Serial.print("AT\r");
   Response();
   Serial.print("AT+CMGF=1\r");
   Response();
   Serial.print("AT+CNMI=1,2,0,0,0\r");
   Response();
}

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

void loop()
{
   RecSMS();
}

void Response() // Get the Response of each AT Command
{
   int count = 0;
   Serial.println();
   while(1)
   {
      if(Serial.available())
      {
         char data =Serial.read();
         if(data == 'K'){Serial.println("OK");break;}
         if(data == 'R'){Serial.println("GSM Not Working");break;}
      }
      count++;
      delay(10);
      if(count == 1000){Serial.println("GSM not Found");break;}

   }
}

void RecSMS() // Receiving the SMS and extracting the Sender Mobile number & Message Text
{
   if(Serial.available())
   {
      char data = Serial.read();
      if(data == '+'){RcvdCheck = 1;}
      if((data == 'C') && (RcvdCheck == 1)){RcvdCheck = 2;}
      if((data == 'M') && (RcvdCheck == 2)){RcvdCheck = 3;}
      if((data == 'T') && (RcvdCheck == 3)){RcvdCheck = 4;}
      if(RcvdCheck == 4){RcvdConf = 1; RcvdCheck = 0;}

      if(RcvdConf == 1)
      {
         if(data == '\n'){RcvdEnd++;}
         if(RcvdEnd == 3){RcvdEnd = 0;}
         RcvdMsg[index] = data;

         index++;
         if(RcvdEnd == 2){RcvdConf = 0;MsgLength = index-2;index = 0;}
         if(RcvdConf == 0)
         {
            Serial.print("Mobile Number is: ");
            for(int x = 4;x < 17;x++)
            {
               MsgMob[x-4] = RcvdMsg[x];
               Serial.print(MsgMob[x-4]);
            }
            Serial.println();
            Serial.print("Message Text: ");
            for(int x = 46; x < MsgLength; x++)
            {
               MsgTxt[x-46] = RcvdMsg[x];
               Serial.print(MsgTxt[x-46]);
            }

            Serial.println();

            //****Resetting all the variables*****//

            //RcvdMsg[200]={0};
            RcvdCheck = 0;
            RcvdConf = 0;
            index = 0;
            RcvdEnd = 0;
            MsgMob[15];
            MsgTxt[50];
            MsgLength = 0;

            Serial.flush();

         }
      }
   }
}

If you're not trying to capture the mobile number or whatever SMS text was sent, but only react to specific SMS messages, then don't try to parse the whole message, but design the protocol between any arbitrary phone and your Arduino to be detectable independent of everything else, e.g.:

#L 5 on        ; set an LED state

#M 3 137       ; set a motor speed


NODEMCU vs AT for esp8266 I have recently started working on esp8266 wifi module and arduino uno.
I am a little confused.

I have created a small Web page with esp8266 AT commands.
Now I want use it for receiving data such as changes on the Arduino inputs.

I have seen many similar implementations using jQuery for that purpose,
but I don't know where to place that jQuery file.

Furthermore, is it possible to use NODEMCU firmware and still toggle arduino pins and transmit data to esp8266?

I want to use Arduino for:

reading voltage levels
publish the values read to the Web page
toggle a relay when a button on the Web page is pressed.

Please kindly help me out or point me in the right direction to search

This is quite a huge topic to cover in one answer, but I will do my best.

The NodeMCU can be used in three distinctly different ways.  First is the AT mode, where you have installed the AT firmware.  In this mode the NodeMCU is purely a slave device to the Arduino.  Once you have got the Arduino to configure the NodeMCU in the right way to receive data on a socket it will send that data back to the Arduino verbatim through the serial port with special tags added (indicating what the data is, and which socket it arrived on, etc).  It is then up to you to receive that data, interpret it in whatever way you desire (as a HTTP GET request most likely) and craft the correct response (if any) and send it to the NodeMCU to send back (again using the AT commands).

What you send through the socket is entirely up to you.  By the sounds of things you will be making a simple GET request from a web browser to perform an operation, and maybe respond with some data to display in the web page.  That can be easy, or it can be hard - it's as hard as you want to make it.  The simplest way is to rely on an external web server to serve the main content and structure of the page, then use jQuery or Prototype to make an AJAX call to your NodeMCU and receive back any data there may be.  In this case everything will be on your external web server except the single (or few) URL(s) that perform operations and return data.  That includes the jQuery (which is just Javascript, it's loaded from your web server into the browser and executed), any code for buttons, images, HTML, everything (on the web server, that is).

The other two ways the NodeMCU can operate are both very different to that.  They differ mainly in the language that is used with them.  You can use the NodeMCU with its own LUA language to get it to do almost anything you want.  That includes receiving the HTTP GET request and serving the data for it, all without the help of the Arduino.  In fact, doing that, there is little need for the Arduino any more - the NodeMCU has an analog input and multiple digital IO lines - it also has SPI available for interfacing with external ADC chips if you want more than one analog input.  So you can have everything internal to the NodeMCU without needing the Arduino at all.  If you do want to keep the Arduino then you can interface to it through the serial port (as you would in AT mode) but using your own custom protocol in whatever way you see fit.

The third way is to program the NodeMCU as if it were itself an Arduino.  There is an ESP8266 core for the Arduino IDE (and for UECIDE Beta as well) which allows you to program the NodeMCU in the same language and with a similar API, as the Arduino.  This even more removes the need for the Arduino.  You can get the Arduino core from Github here: https://github.com/esp8266/Arduino

Incidentally, the Xtensa core in the ESP8266 is considerably more powerful than your typical Arduino, being 32-bit, having its own DSP, and with much more RAM and Flash memory.  It kind of makes the Arduino redundant.


Parsing Data and Comparing two string in arduino I am working on my final assignment. The problem is I want to make a prototype tool, with 2 string compare. If I send data "OK DISC DISCLOSED: 341513DB689AOK RSSI: -056 OK NAME: CarBT1 OK DISCE" will be parsed and bring up data "CarBT1 OK DISCE" if the data is correct then the LED will turn on, but my program isn't working? does anyone know the problem?

String dataIn;
String dt[10];
int i;
boolean parsing=false;
const int pinLED = 8;
String readString;

void setup (){
  Serial.begin(9600);
  pinMode(pinLED, OUTPUT);
  Serial.print("Sketch:   ");   Serial.println(__FILE__);
  Serial.print("Uploaded: ");   Serial.println(__DATE__);
  Serial.println(" ");
  while(!Serial){
    ;
  }
}

void loop (){
  if(Serial.available()>0) {
  char inChar = (char)Serial.read();
  dataIn += inChar;
  if (inChar == '\n'){
  parsing = true;
  }
}
if(parsing){
  parsingData();
  parsing=false;
  dataIn="";
}
while(Serial.available()){
  delay(3);
  char c =  Serial.read();
  readString += c;
}
readString.trim();
  if(readString.length()>0){
    if(readString == "CarBT1 OK+DISCE"){
      digitalWrite(pinLED, HIGH);
      Serial.println("Switching On");
   }
  if(readString == "off"){
      digitalWrite(pinLED, LOW);
      Serial.println("Switching Off");
   }
readString = "";
 }
}

void parsingData(){
int j=0;
Serial.print("data masuk : ");
Serial.print(dataIn);
Serial.print("\n");
dt[j]="";
for(i=1;i<dataIn.length();i++){
  if ((dataIn[i] == ':') || (dataIn[i] == ':')){
  j++;
  dt[j]="";
}
  else{
  dt[j] = dt[j] + dataIn[i];
  }
 }
}
Serial.print("data 1 : ");
Serial.print(dt[0]);
Serial.print("\n");
Serial.print("data 2 : ");
Serial.print(dt[1]);
Serial.print("\n");
Serial.print("data 3 : ");
Serial.print(dt[2]);
Serial.print("\n\n");
Serial.print("data 4 : ");
Serial.print(dt[3]);
Serial.print("\n\n");
}

I think that the biggest problem that you are encountering is that reading a line from serial is not as straightforward as you would like. I don't have a quick and easy solution for you, but there is much on this issue that you can look at.

You have two serial read while loops. The first exits as soon as there are no characters to read (even though some may be on the way). When "\n" is read, you set parsing but it does not mean that \n is removed from dataIn.

The second serial read while loop is using a delay(3) after detecting that a character is available, but that character could have arrived after the first read and be the only character in the buffer, for example.

I suspect that the reason that your String comparison does not work is simply because the Strings are not equal.

Your String looks like something read from an HM-10/11 or something similar. I have had some success reading those transmissions by doing the following:

Make sure the serial buffer is empty. When a character is available, read it into your building String, but continue looking for characters that are available for a set amount of time (maybe a couple of seconds). Continue looking for characters until the time has elapsed and not as soon as there are no characters available (because more may be coming). Alternatively, keep building the string until you recognize the "DISCE" marking the end of that transmission.

A problem, however, is that, in my experience, if it is a very long line (that can occur when there are many devices out there), you will never get that "DISCE". I assumed that this was a firmware issue.

Hope it helps.


Do I Have to Change Internal Interrupt Setups when I Change Clock Speed? 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.

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.

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.


POST data from Arduino to website I am working on a project where I am trying to send data using HTTP and POST method from my Arduino Mega2560 to a website which I host on localhost. I am living to a students' accommodation and thus, I do not have access to the router. However, I have bought a router and have connected it to the wall via the WAN. Also, the Arduino is connected to one of the ethernet plugs of the router via an Ethernet shield and my laptop to another ethernet plug. I am trying to retrieve the data from the website, but I cannot seem to load them.

Arduino Code

#include <dht.h>
#include <SPI.h>
#include <Ethernet.h>

dht DHT1;
int temperatureSensorPin1 = 25;

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
EthernetClient client;
EthernetServer server(80);

long previousMillis = 0;
unsigned long currentMillis = 0;
long interval = 250000;
String data;

long lastUpdate = 0;

void setup() {

  Serial.begin(9600);
  if(Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
  }

  data = "";

  pinMode(temperatureSensorPin1, INPUT);
}

void loop() {

int temp1 = DHT1.read11(temperatureSensorPin1);

switch (temp1)
  {
    case DHTLIB_OK:
        Serial.print("OK,\t");
        break;
    case DHTLIB_ERROR_CHECKSUM:
        Serial.print("Checksum error,\t");
        break;
    case DHTLIB_ERROR_TIMEOUT:
        Serial.print("Time out error,\t");
        break;
    case DHTLIB_ERROR_CONNECT:
        Serial.print("Connect error,\t");
        break;
    case DHTLIB_ERROR_ACK_L:
        Serial.print("Ack Low error,\t");
        break;
    case DHTLIB_ERROR_ACK_H:
        Serial.print("Ack High error,\t");
        break;
    default:
        Serial.print("Unknown error,\t");
        break;
  }

  currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
  }
  String data="temp1="+String(DHT1.temperature, 0)+"&temp2="+String(DHT2.temperature, 0)+"&temp3="+String(DHT3.temperature, 0)+"&temp4="+String(DHT4.temperature, 0)+"&temp5="+String(DHT5.temperature, 0)
                  +"&hum1="+String(DHT1.humidity, 0)+"&hum2="+String(DHT2.humidity, 0)+"&hum3="+String(DHT3.humidity, 0)+"&hum4="+String(DHT4.humidity, 0)+"&hum5="+String(DHT5.humidity, 0)+"&gas="+gasValue;

  Serial.println(Ethernet.localIP());
  if(client.connect("192.168.0.1", 80)) {
    client.println("POST /home/visualisation.php HTTP/1.1");
    client.println("Host:  192.168.0.1");
    //client.println("User-Agent: Arduino/1.0");
    //client.println("Connection: close");
    client.println("Content-Type: application/x-www-form-urlencoded;");
    client.print("Content-Length: ");
    client.println(data.length());
    client.println();
    client.print(data);
    //Serial.println(data);
    Serial.println("We have connection");
  }

  if(client.connected()) {
    Serial.println("We have abc");
    client.stop();
  }

  delay(4000);
}

PHP Code

<?php
$temp1 = "";
if(isset($_POST['temp1'])) {
    $temp1 = $_POST['temp1'];
}
echo $temp1;
?>

Windows ip configuration
[Router ip configuration][2]

Is the connection that I have made the appropriate one? How should I do it in order to work?

P.S.: I would like to clarify that I do not have an extended knowledge regarding networking.

Router ip configuration
LAN
MAC Address: 60-E3-27-E7-70-7A
IP Address: 192.168.0.1
Subnet Mask: 255.255.255.0

Wireless
Wireless Radio: Enable
Name (SSID): TP-LINK_707A
Mode: 11bgn mixed
Channel Width: Automatic
Channel: Auto (Current channel 3)
MAC Address: 60-E3-27-E7-70-7A
WDS Status: Disable

WAN
MAC Address: 60-E3-27-E7-70-7B
IP Address: 100.66.166.2    Dynamic IP
Subnet Mask: 255.255.255.192
Default Gateway: 100.66.166.1

DNS Server: 77.244.128.44 , 77.244.128.45

The ip that I have Arduino send data to is the router's and thus, I should have used the 192.168.0.100 ip which is the one of my computer.

I also needed to save the value to a database to notice the changes because echo $temp1; did not seem to work, probably I should have it included into HTML label tags. Anyway, I just loaded the value from the database into a PHP variable and I was able to accomplish the task.


Should all unused analog input ports be tied to ground for accurate A2D measurements? I am using the A0 port on my Arduino Uno to read the voltage output from an LM35 temperature sensor.  I observed that the reading fluctuates a lot if I leave the remaining analog input ports A1 to A5 floating. Would floating analog inputs affect the accuracy of readings on input ports connected to some signals.

Any floating pin will act as an antenna, and may interfere with values around it, this is one of the major disadvantages of using analog.

To get the most accurate readings with minimal amount of interference, you can pull all unused inputs to ground.

The accuracy will not change, as the accuracy is determined by the sensor itself. However it will reduce the amount of noise / interference, which will give you more accurate readings.

These pull to grounds can be accomplished by configuring the unused analog pins as digital outputs, and setting them low.

pinMode(A1, OUTPUT);
digitalWrite(A1, LOW);


Making a composite waveform using a single TIMER interrupt I'm writing software for a laser tag gun, which under the system we use needs the output waveform to be a carrier wave of 57600Hz with a signal wave of 1800HZ for about 50ms

Using the Tone library (https://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation) and a transistor AND gate, I've had this working using two timers, however I really want to shrink it down to one timer so that I can use the other for sound (using the TMRPCM library which only needs timer1).

I've modified the Tone library cut down to what I need, with the following methods:

void TagTone::beginPulse(uint8_t tonePin)
{
    _pin = tonePin;
    _timer = 2;

    // 8 bit timer
    TCCR2A = 0;
    TCCR2B = 0;
    bitWrite(TCCR2A, WGM21, 1);
    bitWrite(TCCR2B, CS20, 1);
    timer2_pin_port = portOutputRegister(digitalPinToPort(_pin));
    timer2_pin_mask = digitalPinToBitMask(_pin);

    int duration = 50; //50 milliseconds
    uint8_t prescalarbits = 0b001;
    int32_t signal_toggle_count = 0;

    // Note: may need prescaler reimplemented if using 16Mhz, fine on current 8Mhz
    ocr = F_CPU / (CARRIER_FREQUENCY * 2) - 1;
    prescalarbits = 0b001;

    TCCR2B = (TCCR2B & 0b11111000) | prescalarbits;

    toggle_count = 2 * CARRIER_FREQUENCY * duration / 1000; // how many times the carrier toggles before pulse ends

    // want to AND with 1800 Hz signal

    // as duration now set to 50: toggle_count for carrier = 5760
    // equivalent toggle count for signal = 180
    signal_toggle_count = 2* SIGNAL_FREQUENCY * duration / 1000;

    // want to flip signal state every 32 carrier pulses
    signal_cycle_count = 32; //toggle_count / signal_toggle_count;
}

// duration (in milliseconds).

void TagTone::playPulse()
{

    OCR2A = ocr;
    timer2_signal_toggle_count = signal_cycle_count;
    timer2_toggle_count = toggle_count;
    bitWrite(TIMSK2, OCIE2A, 1);

}

ISR(TIMER2_COMPA_vect)
{
    if(timer2_toggle_count  < 0)
    {
        *timer2_pin_port ^= timer2_pin_mask & signal_state; // flip

        if (timer2_signal_toggle_count > 0)
        {
          timer2_signal_toggle_count--;
        }
        else
        {
            signal_state ^= signal_state;
            timer2_toggle_count -= timer2_signal_toggle_count;
            timer2_signal_toggle_count = signal_cycle_count;
        }
    }
    else
    {
        TIMSK2 &= ~(1 << OCIE2A);                 // disable the interrupt
        *timer2_pin_port &= ~(timer2_pin_mask);   // keep pin low after stop
    }
}

What I hope this is doing is 32 toggles at the carrier speed (ie 16 full cycles of 57600Hz), followed by 32 'silent' toggles where nothing happens, followed by another 32 at carrier speed, etc.  I should then be able to fire using:

digitalWrite(signalPin, HIGH);
carrierTone.playPulse();
delay(60);
digitalWrite(signalPin, LOW);

But that doesn't set off the sensor, whereas the simple code below works.

carrierTone.play(57600, 50);
signalTone.play(1800, 50);

Woo, solved it.  My ISR code was completely wrong.  Works using:

ISR(TIMER2_COMPA_vect)
{
  if (timer2_signal_toggle_count != 0)
  {
    // toggle the pin
    if(signal_state == 1)
        *timer2_pin_port ^= timer2_pin_mask;

    if (timer2_toggle_count > 0)
      timer2_toggle_count--;
    else
    {
        TIMSK2 &= ~(1 << OCIE2A);                 // disable the interrupt
        *timer2_pin_port &= ~(timer2_pin_mask);   // keep pin low after stop
    }
     timer2_signal_toggle_count --;
  }
  else
  {
    timer2_signal_toggle_count = signal_cycle_count;
    timer2_toggle_count --;
    if(signal_state == 1)
    {
        signal_state = 0;
        *timer2_pin_port &= ~(timer2_pin_mask);
        //*timer2_pin_port ^= timer2_pin_mask;
    }
    else
    {
        signal_state = 1;
        *timer2_pin_port ^= timer2_pin_mask;
    }
  }
}

I was trying to just AND the signal state into the original pin state, which was completely the wrong thing to do.


How to use Infra Red (IR) to reset arduino board I am a big noob I know that

but can this code be used to reset arduino board (instead of pressing the usual reset button on the board)

I want to reset the board as If am pressing the reset button using IR

int receiverpin = 2; // pin 1 of IR receiver to Arduino digital pin 2
#include <IRremote.h>
IRrecv irrecv(receiverpin); // create instance of irrecv
decode_results results;
void setup()
{
irrecv.enableIRIn(); // start the receiver
}
void(* resetFunc) (void) = 0; //declare reset function @ address 0

void loop()
{
 if (irrecv.decode(&results)) // have we received an IR signal?
{
if(results.value == 0x2FD847B) //if the button press equals the hex
{
  resetFunc();
}
{
irrecv.resume(); // receive the next value
}
}
}

Kind of, yes.  That doesn't actually reset the Arduino, it just sends the program to address 0.

There are two other ways of performing the reset that do a proper full reset:

Enable the watchdog timer and let it time out to reset the CPU.
Connect an IO pin to the RESET pin - keep it in INPUT most of the time but set it to OUTPUT and LOW when you want to reset.

By just jumping to address 0 you aren't resetting the internal peripherals and registers to their reset state, so things like timers and such will still be running when they shouldn't be, etc.  It's better by far to do a real reset instead of just jumping to 0 like that.


Auto Reset during programming Arduino I know this that when you try to program a pro mini without a DTR pin it will give you a error as the atmega needs to be reset during programming. So I had a doubt why does the microcontroller needs to be reset and clearly at which time you know at which moment does it reset ?

A Reset is necessary to activate the Bootloader and allow programming. Without the DTR signal the Reset button has to be pressed just before starting the upload from the Arduino IDE.


Scanning for I2C addresses I'm trying to find the I2C address of an IMU plugged into my Arduino using the code from this URL: http://playground.arduino.cc/Main/I2cScanner.  However, the program stalls at this stage:

Why could this be happening?

When the I2C scanner stops, it halts in the function Wire.endTransmission. The cause is a hardware problem of the I2C bus. For example the SDA or SCL are shortcut to something or pull-up resistors are missing (as already mentioned by TisteAndii) or the sensor module is not powered.

I assume that the IMU module has already pull-up resistors for SDA and SCL on the module. Which IMU module is it ? How did you connect it ? Do you have other I2C modules to test the I2C bus ?


Can anyone tell me the best books for studying UAV? It's kind of hard to get full guide from the internet. I just wanna buy a book for UAV guide. I gotta make DIY drones. I'd appreciat it if you recommend good books.

Not a book, but try the following course from EdX, the online MOOC:
https://www.edx.org/course/tumx/tumx-autonavx-autonomous-navigation-1658


Very easy Arduino code challenge for you brainiacs to solve I've searched the forum for similar problems and still can't see my obvious issue. I'm working on a simple Halloween prop and I'm using an Arduino for the first time. I've tested each individual 'event' (i.e. fog machine, mp3, actuator, and LED strip) with a loop and all four have worked on continuous loop with no issue.

As soon as I combine them all together, the program runs successfully exactly one time. After that final 10 second delay, when I expect the program to start the loop again, it crashes. If it helps, right during the start of the next loop, the relay light turns on on the relay board for RELAY_1_A and sort of just flickers while the actuator hums. I usually shut it down quickly at this point. As soon as I turn the system back on, it successfully runs through another iteration until the loop hangs.

I'm happy to provide pictures or even a video of the issue if that helps. My guess is that you guys will spot my coding issue right away. Maybe some kind of memory overflow or something like that.

I know my code could be much more efficient but I'm just looking for the glaring problem that is keeping the loop from working.

#include <SPI.h>
#include <SdFat.h>
#include <SdFatUtil.h>
#include <SFEMP3Shield.h>

const int RELAY_1_A = 7; //the one with the issue
const int RELAY_1_B = 8;

SdFat sd;
SFEMP3Shield MP3player;
void setup() {
  // initialize the digital pins as an output.
  pinMode(10, OUTPUT); //Fog machine on Relay1 on 5V relay board
  pinMode(3, OUTPUT); //LED strip off breadboard MOSFET
   pinMode(RELAY_1_A, OUTPUT); //12V relay for actuator on Relay1 on 12V relay board
   pinMode(RELAY_1_B, OUTPUT); //12V relay for actuator on Relay2 on 12V relay board

  //start the shield
  sd.begin(SD_SEL, SPI_FULL_SPEED);
  MP3player.begin();
  MP3player.setVolume(10, 10);
}

void loop() {
  MP3player.playTrack(2);  // Play MP3. Track 1 is coffin and track 2 is bird
  delay(5000);              // wait for 5 seconds
  digitalWrite(10, LOW);   // Turns ON fog machine
  delay(3000);
  digitalWrite(10, HIGH);   // Turns OFF fog machine
  digitalWrite(3, HIGH);   // Turn the LED on (HIGH is the voltage level)

  delay(5000);              // wait for 5 seconds

  retractActuator();       //Open coffin
  delay (9000);
  stopActuator();      //Close coffin
  delay (9000);
  extendActuator();      //Close coffin
  delay(8000);
  digitalWrite(RELAY_1_B, HIGH);  //Turns off this relay during the wait period before next loop

  digitalWrite(3, LOW);    // Turn the LED off by making the voltage LOW
  delay(10000);              // wait for 20 seconds

}
void extendActuator() {
  //Set one relay one and the other off
  //this will move extend the actuator
  digitalWrite(RELAY_1_A, HIGH);
  digitalWrite(RELAY_1_B, LOW);
}

void retractActuator() {
  //Set one relay off and the other on
  //this will move retract the actuator
  digitalWrite(RELAY_1_A, LOW);
  digitalWrite(RELAY_1_B, HIGH);
}

void stopActuator() {
 //Set both relays off
 //this will stop the actuator in a braking
 digitalWrite(RELAY_1_A, HIGH);
 digitalWrite(RELAY_1_B, HIGH); }

You are attempting to use IO pins that are already in use by the MP3 shield.

According to your subsequent research, only digital pins 0,1,5, and 10 are available for use.

You should shy away from using pins 0 and 1 since they are also connected to the computer through the USB interface and are used for uploading sketches.  You will find that either you can't upload sketches with the relays connected to those pins, or the relays will "randomly" switch on and off while you're uploading a sketch.

Don't forget that the analog pins A0-A5 can also be used as digital pins, so you can quite happily drive your relays using any of those.


Connect HX711 to a three wire load cell I have the following load cells:

I'm using the following HX711 amplifier

Every guide i can find on the internet describes how to connect a load cell with four wires to the amplifier. How can i connect a load cell with three wires to the amplifier?

Thanks in advance.

A datasheet for the HX711 is https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/hx711_english.pdf  (On your board, it looks like E+ is AVDD and E- is AGND.)

Each of your two load cells could be a half-bridge of a wheatstone bridge, with excitation on the white and black, and sensing on the red like:

I have a similar loadcell with the colors as Blue-Red-Black, (instead of White-Red-Black as above, or the Red-White-Black in your image) with my red sensing wire in the middle.  The positive strain resistance (increasing resistance with increasing load) is between the Blue and Red, while the negative strain (decreasing resistance with decreasing load) is between the Red and the Black. The ~1000 ohm resistance in each leg changes by tenths of an ohm with hand pressure on the button, when the outer portion is supported, but the inner portion is not supported.  Your cells do not have the bridge-button part that create a balanced twist along the center portion, so it might be hard to reliably apply a load your cell.

To make positive deflections of the cells combine to unbalance the Wheatstone bridge, wire one cell's white and black opposite to the other cell, and attach them to E+ and E-, with the reds connected to A+ and A- like this:

   HX711.E+ : Cell1.White + Cell2.Black
   HX711.E- : Cell1.Black + Cell2.White
   HX711.A+ : Cell1.Red
   Hx711.A- : Cell2.Red

The labelling on the schematic isn't quite right-- the "Reference 1K" are actually the negative-strain portions of the cells, and might be better labelled as "-Active 1k Ohm".

If it moves in the wrong direction/wrong sign with increasing force, switch the reds or multiply by -1.

If you have only one three-wire cell, use a couple 1K resistors, or a 2K potentiometer to balance the existing cell as the other half of the Wheatstone bridge.  One issue with using discrete (10%, 5%, 1%?) resistors is that the precision and tolerances when configured as a voltage divider may produce a significantly different result as compared with the balance in a lead cell and its full-scale signal (+/-0.1%) in a loadcell.  A the center tap of a potentiometer can provide for tuning to match the load cell voltage.

Per @wirewrap's comment, the colors on the wire could be different than the picture I posted.  You can make certain by measuring the resistances between the wires and exciting on the pair with the greatest resistance, and sensing on the middle terminal.


Arduino motor and motor driver I have a little problem. I have a motor driver (L298N). When I engage in electricity, my 2 motors start and after 5 second stop. Then they stop for about 2 seconds, and then start and in a moment (0.5 second) turn off. This make still around (go about 0.5 s, stop for 2 seconds...). And my motor driver is very hot after 1 minute.

Is it possible that it is because of weak voltage? (The motor driver is for 6-35 V, and I have a 6 V battery).

L298n:
enter image description here

There is my code on Arduino:

const int motorPin1  = 9;
const int motorPin2  = 10;
const int motorPin3  = 6;
const int motorPin4  = 5;

void setup() {
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
}

void loop() {
  forw(3000);
  back(3000);
}

int fast = 255;

void forw(int timer) {
  analogWrite(motorPin1, 0);
  analogWrite(motorPin2, fast);
  analogWrite(motorPin3, 0);
  analogWrite(motorPin4, fast);
  delay(timer);
}

void back(int timer) {
  analogWrite(motorPin1, fast);
  analogWrite(motorPin2, 0);
  analogWrite(motorPin3, fast);
  analogWrite(motorPin4, 0);
  delay(timer);
}

The L298 is a very old, obsolete design based on bipolar transistors, which means it has a lot of internal losses.

The energy consumed in those losses shows up as heat.

It also has some degree of overload or overtemperature protection, so what you are observing is an automatic shutdown.  Or perhaps, your motor is causing the battery voltage to sag and resetting your Arduino at which point the sketch resumes after a bootloader delay.  6v is really too low an input voltage to the Arduino's regulator, but too high for direct input without the regulator.

You need to make sure that the current draw of your motors is reasonable, and you likely want to replace the terrible L298 with a more modern, low less FET driver.  You will need to select one rated for the actual current draw of your motor: you should consider not only free rotation of the motor, but the increased current draw if it is mechanically stalled.


Undefined reference to Class::function() I have three files:

main.cpp
RotaryEncoder.h
RotaryEncoder.cpp

Note that the RotaryEncoder class acts as a wrapper to the Encoder library. I am getting the following build report and I haven't been able to find the bug for the past couple days:

Build output from PlatformIO on VS Code

Processing uno (platform: atmelavr; board: uno; framework: arduino)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/uno.html
PLATFORM: Atmel AVR 1.15.0 > Arduino Uno
HARDWARE: ATMEGA328P 16MHz, 2KB RAM, 31.50KB Flash
PACKAGES: toolchain-atmelavr 1.50400.190710 (5.4.0), framework-arduinoavr 4.1.2
LDF: Library Dependency Finder
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 7 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <Encoder>
Building in release mode
Compiling .pio/build/uno/src/main.cpp.o
Linking .pio/build/uno/firmware.elf
/var/folders/t1/fyh283nd1m7dxbrjlkjtf_kc0000gn/T//ccZN56Tq.ltrans0.ltrans.o: In function `main':
<artificial>:(.text.startup+0x2dc): undefined reference to `RotaryEncoder::getCount()'
collect2: error: ld returned 1 exit status
*** [.pio/build/uno/firmware.elf] Error 1

Explicit Error

  In function 'main':
  :(.text.startup+0x2dc): undefined reference to 'RotaryEncoder::getCount()'.

main.cpp

#include <Arduino.h>
#include "RotaryEncoder.h"

#define cartEncoderPhaseA 3
#define cartEncoderPhaseB 4
#define pendulumEncoderPhaseA 2
#define pendulumEncoderPhaseB 5

// Initialize encoders
const double ENCODER_PPR = 2400.0;
RotaryEncoder cartEncoder(cartEncoderPhaseA, cartEncoderPhaseB, ENCODER_PPR);
RotaryEncoder pendulumEncoder(pendulumEncoderPhaseA, pendulumEncoderPhaseB, ENCODER_PPR);

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

void loop()
{
  long cartCount = cartEncoder.getCount();
}

RotaryEncoder.h

#pragma once

#include <Encoder.h>

class RotaryEncoder
{
private:
    Encoder encoder;
    double encoderPPR;
    double angleLowerBound;
    double angleUpperBound;

    double convertEncoderCountToRadians(long encoderCount);
    double normalizeAngle(double angle);

public:
    RotaryEncoder(int phaseA, int phaseB, double encoderPPR);
    long getCount();
    double getRadiansAndOffsetBy(double angleOffset);
    void setAngleLowerAndUpperBounds(double lowerBound, double upperBound);
};

RotaryEncoder.cpp

#include "RotaryEncoder.h"

RotaryEncoder::RotaryEncoder(int phaseA, int phaseB, double encoderPPR)
: encoder(phaseA, phaseB), encoderPPR(encoderPPR)
{}

inline long RotaryEncoder::getCount()
{
    return encoder.read();
}

inline double RotaryEncoder::getRadiansAndOffsetBy(double angleOffset)
{
    long encoderCount = getCount();
    double angleInRadians = angleOffset + convertEncoderCountToRadians(encoderCount);
    angleInRadians = normalizeAngle(angleInRadians);

    return angleInRadians;
}

inline double RotaryEncoder::convertEncoderCountToRadians(long encoderCount)
{
    return ((double)encoderCount / (encoderPPR)) * (2.0 * PI);
}

inline double RotaryEncoder::normalizeAngle(double angle)
{
    // Constrain an angle between [-pi, pi). Output is in radians
    // see: https://stackoverflow.com/questions/11498169/dealing-with-angle-wrap-in-c-code

    angle = fmod(angle + PI, 2 * PI);

    if (angle < 0)
        angle += 2 * PI;

    return angle - PI;
}

inline void RotaryEncoder::setAngleLowerAndUpperBounds(double lowerBound, double upperBound)
{
    angleLowerBound = lowerBound;
    angleUpperBound = upperBound;
}

The inline modifier doesn't make a sense for methods definitions in separate cpp file. And obviously it makes the code compilable but methods aren't recognized as methods definitions and also it's not recognized as error (that's kinda weird).

Anyway, if you wan't inline methods, do it directly inside of class definition.


No matching function call for timer? I am using the Timer library here with the Adafruit feather m0:
https://github.com/JChristensen/Timer
https://playground.arduino.cc/code/timer
I cannot figure out why I am getting the error:

no matching function for call to 'Timer::every(int, void (&)())'

Here is that part of the code:

void setup(){
      everyAlt = t.every(100, readAltimeter);
      everyLaunch = t.every(500, detectLaunch);
      t.oscillate(blueled, 500, HIGH);
    }

    void readAltimeter(){
      alts[altPlace] = bmp.readAltitude()-zeroAlt;
      altPlace++;
    }

    void detectLaunch(){
      tempSpeed = 0;
      int x = 0;
      while (x < 5){
        tempSpeed += abs((alts[x]-alts[x+1])*10);
      }
      if (tempSpeed/5 > 5){
        t.stop(everyLaunch);
      }
    }

I am pretty new to arduino so any help would be much appriciated!

Had the wrong version. Correct version downloaded from the current master: github.com/JChristensen/Timer


Interesting issue with my wifi Car project Hello so i build a nodemcu wifi controlled car, everything works fine expect i have one small issue, currently i have 2 9v batterys, one of them is connected to motor controller and other one is connected to nodemcu.. but the nodemcu's 9v battery gets hot in a minute and stops working. What am i doing wrong? + is connected to vcc and - is connected to grnd on nodemcu.

the nodemcu's 9v battery gets hot in a minute and stops working. What am i doing wrong?

You're using a 9V battery.

Those batteries are useless. They have very little capacity, and can provide very little current. The NodeMCU needs a lot of current.

Choose a better battery. Maybe a Li-Poly battery would be good (mobile phone batteries are good for this).


How to set address for using more than MPU9250 I am trying to build a project that contains more than one MPU 9250, until now I'm still confused to MPU9250. If I were going to that, does anybody here know how to set addresses to each of the MPU's I am going to use? Thank you for spending time reading my question. I hope someone will help me get through this.

This is the type of information which a Data Sheet is intended to communicate.  In I2C mode the AD0 pin selects between two possible addresses,

1101000 for AD0=0 and
1101001 for AD0=1.

In SPI mode you can presumably have as many as you like by giving each its own chip select.

That said, using multiple sensors may not be very useful unless your apparatus is flexible - only the 3 accelerometer axis would be expect to yield different values based on position relative to the center of rotations.


4 consecutive bytes in buffer to unsigned long I wonder if there's a smarter way to get these 4 consecutive bytes from a buffer, concatenated in a unsigned long.

// the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:

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

Seems overkill to me, thinking these 4 bytes are already consecutive in the buffer.

Result should be unchanged i.e. having the value in a variable.

If they were in the same endian order as a long (little-endian on an Arduino, which they don't appear to be) you could just point to them:

uint32_t *l = (uint32_t *)&packetBuffer[40];

Then use *l to access the content as a long.

However since they look to be in a big-endian order it's not that simple. The simplest thing you can do is just re-combine them with bit-shifting:

uint32_t l = ((uint32_t)packetBuffer[40] << 24) | ((uint32_t)packetBuffer[41] << 16) |
             ((uint32_t)packetBuffer[42] << 8) | (uint32_t)packetBuffer[43];


Using TFT touchscreen with Arduino Uno R3 via I2C I've recently gotten into Arduino, due to a friend asking to be part of a project. The project requires a few 24V LED strips to be controllable via PWM, probably over MOSFETs (we have someone else in the team that will look after the electronics, I will be mostly responsible for the code) and also various sensors to measure the environment. However, the project should also include a touchscreen that will be used for programming these LEDs based on time and date, and displaying the data from these sensors, or program further events based on their input.

As far as I understand it should be possible to drive a TFT touchscreen via I2C? I've done some googling over the past two hours or so and could barely find any information about what screens to use for such projects, no tutorials, nor if there are any libraries available.

Is it doable to do a project of this magnitude with a Uno R3, or should I consider a Due or Mega?

I have a touchscreen shield right here, but it leaves me with only one PWM and one analogue pin if I don't plan on using the SD card that is on its back.

Maybe I'll find the answer myself, but I have literally only joined the Arduino/microcontroller fun a few days ago and am reading up on the whole topic in a 'for dummies' book which is very interesting, but it only touches on I2C at the very end and I don't want to confuse myself too much by jumping ahead and reading about stuff that doesn't directly answer my questions. So I turn to you guys for at least pointing me in the right direction on what I should read up on or linking me to tutorials.

Also, if you guys have any books to recommend on the topic I'll be glad to take recommendations.

Thanks in advance

A TFT touchscreen actually normally consists of two completely separate items:

TFT Display
Touchscreen and optional interface chip

While you can get both of those together on a board with both using I2C it is quite rare. It is far more common to find boards with either SPI or 8- (or 16-) bit parallel interfaces for the TFT screen, and SPI (or sometimes 4 channel analog - a direct connection to the touch screen itself) for the touch screen.

I2C is really only used for very small screens. The slow speed of the I2C protocol means that updating the display is very slow, which results in very poor performance for anything bigger than, say 128x128 pixels. It's usually used for things like small OLED displays rather than larger TFT displays.

Touchscreens with I2C are normally capacitative rather than the cheap resistive, so tend to be a little more expensive and harder to work with. The most common touch screen chip, the XPT2046, is SPI.

Fitting everything you want to do into an Uno is going to be tight, and not just because of the number of IO pins a display usually demands. Working with displays usually means lots of graphics (icons, symbols, fonts, etc), and that means a lot of flash memory. A Mega2560 would be a better choice for that if you want to remain with 8-bit.

However better graphical results would be obtained using a more powerful board. The Arduino Due, with its 32-bit ARM chip, would allow you to do much more graphical manipulation, such as drawing nice graphs etc.

My personal preference, though, is to use a PIC32 based board and the chipKIT core, coupled with my own powerful DisplayCore library. But then I'm biased.


Blew my Arduino. Did I wire this correctly? Hi,

I am currently doing a project and it seems that I may have blown my Arduino Nano (or maybe not). The power LED of the Nano was still on and I believe the L pin blinks once every time I press the reset button.

I wanted to use 4AA alkaline batteries to power my project. The servo is a continuous servo rated for 4-6V and 15-200mA from Parallax. Given that the Nano runs optimally when powered at 7-12V, I decided to buy a step-up converter (adjustable output voltage). It looks like this although I bought it elsewhere:

https://www.ebay.com.au/i/283603471149?chn=ps&norover=1&mkevt=1&mkrid=705-139619-5960-0&mkcid=2&itemid=283603471149&targetid=752505019384&device=c&mktype=pla&googleloc=9071392&poi=&campaignid=1979582348&mkgroupid=72745766764&rlsatarget=pla-752505019384&abcId=1139426&merchantid=7364522&gclid=Cj0KCQjwt5zsBRD8ARIsAJfI4Bh8cSOKugFrugHz-gA-s8nXclnO7H8iQ-WX46FRdhDLchwbl6UyWLgaAr4oEALw_wcB

When I tried to test it with the servo running, my Nano stopped working after several seconds later. Did I wire them up wrongly? I also measured the output of the step-up converter when it was running with a voltmeter between the two terminals of the step-up's output. Would it be possible to short it that way?

Appreciate any help I can get. Thanks

It would be best if everything ran at the same voltage. (And it is necessary that everything uses the same ground.)  Which is possible as there are 5V Arduino boards.  Interestingly, the Arduino nano, according to this schematic, runs at 5V.

In order to use the Arduino Nano at 5V, instead of using VIN / Pin 1, you should be able to skip the Arduino's 5V regulator and use +5V / Pin 4.  But this must be a regulated 5V power source.

Now, why are you having problems controlling the servo?

It is difficult to tell, but your boost switching power supply negative input may not be directly connected to the negative output.  With out a common ground, it may be difficult to create the proper signal to control the servo.

To be specific, if the ground or negative side of the servo power supply is not at the same potential as the ground or negative side of the Arduino power supply, controlling the servo may be difficult at best and at worst you could burn something out on the servo or Arduino.

To check, measure with a volt meter to see if there is any difference between the boost switcher negative input and negative output.

To solve this problem consider using a USB power supply plugged into the Arduino Nano and powering the servo off the 5V at pin 4 of the Nano.  Or, keep using your 6V battery and 6V to 9V boost switching power supply.  Connect this as you are to VIN Pin 1.  The Arduino Nano's 5V power regulator should kick in and provide 5V at pin 4.


Can we have 2 HC12 on a single Arduino (1 to receive and other to transmit)? I'm working on a project and I need to send 2 datas and receive them at the same time.
My question is: Is it possible to have 2 Arduinos both have 2 HC12 (total 4), because I want each Arduino to send and receive data at the same time.
It's hard for me to have 4 Arduinos.

Yes you can - one on Serial pins 0/1 and the other using SoftwareSerial on any other pins. Note that the one on SoftwareSerial will interfere with the one on Serial as it disables interrupts while sending or receiving.
It may be better to use an Arduino which has multiple hardware serial ports. Maybe one of the Teensy boards would be better for your needs.
Alternatively if (and I am not familiar with the modules enough to know if this is right or not) they operate as a transparent serial bridge then you could connect one module to the TX pin for transmission and the other to the RX pin for reception - reading from serial receives from one, and writing to serial transmits through the other.
Also note that you will have to ensure that both pairs of modules are running on different channels to prevent interference between them.