body:
I'm working on a project with Arduino to make LED timer with fading feature. After doing some research finally I wrote some code but it's not working until now
P.S i don't have any knowledge in coding at all T_T

**Edit:** Adding more details about the issue;
when trying to check upload this error is always shown.

    Arduino: 1.8.5 (Windows 10), Board: "Arduino/Genuino Uno"

    \SunRisetimer.ino: In function 'void loop()':

    SunRisetimer:55: error: 'startOff' was not declared in this scope

         startOff();
    \SunRisetimer.ino: In function 'void startOn()':

    SunRisetimer:89: error: variable or field 'startOff' declared void

     void startOff

    SunRisetimer:91: error: expected '}' before ';' token

    analogWrite(uled, 1);

    SunRisetimer:116: error: expected '}' at end of input

     }
    exit status 1
    'startOff' was not declared in this scope

**Code:**

    #include <DS3231.h> //Include the clock library

    // Changable Vars
    int fadeTimeOn = 30; // How long the light will fade to max
    int fadeTimeOff = 30; // How long the light will fade to min
    int setHourOn = 9; // Set hours to wake (military time)
    int setMinOn = 15; // Set minute to wake
    int setHourOff = 9; //set off h
    int setMinOff = 30; //
    int uled = 9; // Set pinout with with PWM

    // Set up Vars
    DS3231  rtc(SDA, SCL);
    Time t;
    void start();

    void setup()
    {
      pinMode(uled, OUTPUT);
      Serial.begin(9600); // Match to serial monitor
      rtc.begin();
    }

    void loop()
    {
      t = rtc.getTime(); // Make a time class called 't'

      // Send Day-of-Week
      Serial.print(rtc.getDOWStr());
      Serial.print(" ");

      // Send date
      Serial.print(rtc.getDateStr());
      Serial.print(" -- ");

      // Send time
      Serial.println(rtc.getTimeStr());

      if (t.hour == setHourOn && t.min == setMinOn) // Check if it's time to wake up!
      {
        startOn();
      }

      // Wait one second before repeating
      delay (1000);

     if (t.hour == setHourOff && t.min == setMinOff) // Check if it's time to off!
      {
        startOff();
      }

      // Wait one second before repeating
      delay (1000);
    }

    void startOn()
    {
      // Fix for SB LED
      analogWrite(uled, 1);
      delay((fadeTimeOn * 60000)/50);
      analogWrite(uled, 2);
      delay((fadeTimeOn * 60000)/50);
      analogWrite(uled, 3);
      delay((fadeTimeOn * 60000)/50);
      analogWrite(uled, 4);
      delay((fadeTimeOn * 60000)/50);
      analogWrite(uled, 4);
      delay((fadeTimeOn * 60000)/50);
      analogWrite(uled, 5);
      delay((fadeTimeOn * 60000)/50);

    for (int i = 6 ; i <= 255; i++)
        {
        analogWrite(uled, i);
        delay(((fadeTimeOn * 60000)/306));
        Serial.print(" mil sec ");
        Serial.print(((fadeTimeOn * 60000)/306));
        Serial.print(" PWM " );
        Serial.print(i);
        {
    }

    void startOff
    {
      analogWrite(uled, 1);
      delay((fadeTimeOff * 60000)/50);
      analogWrite(uled, 5);
      delay((fadeTimeOff * 60000)/50);
      analogWrite(uled, 4);
      delay((fadeTimeOff * 60000)/50);
      analogWrite(uled, 3);
      delay((fadeTimeOff * 60000)/50);
      analogWrite(uled, 2);
      delay((fadeTimeOff * 60000)/50);
      analogWrite(uled, 1);
      delay((fadeTimeOff * 60000)/50);

      // Fade script
      for (int i = 6 ; i <= 255; i++)
      {
        analogWrite(uled, i);
        delay(((fadeTimeOff * 60000)/306));
        Serial.print(" mil sec ");
        Serial.print(((fadeTimeOff * 60000)/306));
        Serial.print(" PWM " );
        Serial.print(i);

      }

    }

title: how to make this work auto on off led with fading

Answers: 1

body:
Look at your function definitions:

    void startOn() // works
    void startOff    // doesn't work

You are missing the `()` after `startOff`.


body:
So I have this code to get ntp time and display it on serial port. But I want to display it on a 1.30 inch I2C oled with a SH1106 controller using the U8G2 library. The only problem is I don't know the correct syntax. I have tried

    Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs
    per day)
    int ho = ((epoch  % 86400L) / 3600+9);
    itoa(ho,hours,10);
    u8g2.clearBuffer();         // clear the internal memory
    u8g2.setFont(u8g2_font_ncenB14_tr); // choose a suitable font
    u8g2.drawStr(0,20,hours);

and also

    {
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.firstPage();
    do {
    u8g2.setCursor(0, 20);
    u8g2.print(hours,DEC);
    u8g2.setCursor(33, 20);
    u8g2.print(minutes,DEC);
    }
    while ( u8g2.nextPage() );
    }

This is my code

    //This is a code to display ntp time using Nodemcu

    #include <ESP8266WiFi.h>
    #include <WiFiUdp.h>
    #include <Arduino.h>
    #include <U8g2lib.h>

    #ifdef U8X8_HAVE_HW_SPI
    #include <SPI.h>
    #endif
    #ifdef U8X8_HAVE_HW_I2C
    #include <Wire.h>
    #endif

    U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);

    char ssid[] = "123456";     //  your network SSID (name)
    char pass[] = "123456";     // your network password

    //Your UTC Time Zone Differance  India +5:30
    char HH = 5;
    char MM = 30;

    unsigned int localPort = 2390;      // local port to listen for UDP packets

    //* Don't hardwire the IP address or we won't get the benefits of the pool.
    //* Lookup the IP address for the host name instead */

    //IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server

    IPAddress timeServerIP; // time.nist.gov NTP server address

    const char* ntpServerName = "time.nist.gov";

    const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes
    // of the message

    byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing
    //packets

    // A UDP instance to let us send and receive packets over UDP
    WiFiUDP udp;

                                  //SETUP

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

    // We start by connecting to a WiFi network
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, pass);

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

    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());

    Serial.println("Starting UDP");
    udp.begin(localPort);
    Serial.print("Local port: ");
    Serial.println(udp.localPort());
    }

    //  Send an NTP request to the time server at the given address

    unsigned long sendNTPpacket(IPAddress& address)
    {
    Serial.println("sending NTP packet...");
    // set all bytes in the buffer to 0
    memset(packetBuffer, 0, NTP_PACKET_SIZE);

    // Initialize values needed to form NTP request
    // (see URL above for details on the packets)
    packetBuffer[0] = 0b11100011;   // LI, Version, Mode
    packetBuffer[1] = 0;     // Stratum, or type of clock
    packetBuffer[2] = 6;     // Polling Interval
    packetBuffer[3] = 0xEC;  // Peer Clock Precision
    // 8 bytes of zero for Root Delay & Root Dispersion
    packetBuffer[12]  = 49;
    packetBuffer[13]  = 0x4E;
    packetBuffer[14]  = 49;
    packetBuffer[15]  = 52;

    // all NTP fields have been given values, now
    // you can send a packet requesting a timestamp:

    udp.beginPacket(address, 123); //NTP requests are to port 123
    udp.write(packetBuffer, NTP_PACKET_SIZE);
    udp.endPacket();

    u8g2.begin();
    }
                                  //LOOP

    void loop()
    {
    char hours;
    char minutes;
    char seconds;

    // get a random server from the pool
    WiFi.hostByName(ntpServerName, timeServerIP);

    sendNTPpacket(timeServerIP);

    // send an NTP packet to a time server
    // wait to see if a reply is available
    delay(1000);

    int cb = udp.parsePacket();
    if (!cb) {
    Serial.println("no packet yet");
    }
    else {
    Serial.print("packet received, length=");
    Serial.println(cb);

    // We've received a packet, read the data from it
    udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract 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);

    // now convert NTP time into everyday time:
    Serial.print("Unix time = ");
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;
    // print Unix time:
    Serial.println(epoch);

    // print the hour, minute and second:
    minutes = ((epoch % 3600) / 60);
    minutes = minutes + MM; //Add UTC Time Zone

    hours = (epoch  % 86400L) / 3600;
    if(minutes > 59)
    {
    hours = hours + HH + 1; //Add UTC Time Zone
    minutes = minutes - 60;
    }
    else
    {
    hours = hours + HH;
    }

    Serial.print("The UTC time is ");       // UTC is the time at Greenwich //Meridian (GMT)

    Serial.print(hours,DEC); // print the hour (86400 equals secs per day)
    Serial.print(':');

    if ( minutes < 10 ) {
    // In the first 10 minutes of each hour, we'll want a leading '0'
    Serial.print('0');
    }
    Serial.print(minutes,DEC); // print the minute (3600 equals secs per minute)
    Serial.print(':');

    seconds = (epoch % 60);
    if ( seconds < 10 ) {
    // In the first 10 seconds of each minute, we'll want a leading '0'
    Serial.print('0');
    }
    Serial.println(seconds,DEC); // print the second
    }
    // wait ten seconds before asking for the time again
    delay(10000);
    }

Adding the second block of code (print one) to the main code gives me correct time on the oled screen but only when the ntp receives a packet. Otherwise its some 10 digit number. How do I get rid of the number and keep displaying the time till it is update with a valid newer value. I have attached images of display.

![Correct time][1]

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

![10 digit value](https://i.stack.imgur.com/kjjyC.jpg)

title: Problem to display Ntp time on an oled using U8G2 lib

Answers: 1

body:
EDIT: I checkout Internet access is working OK. Problem is the server.

Your sketch works well (after some refactoring) against my local LAN NTP server and ntp.shoa.cl, but not against time.nist.gov, the one in your sketch.

It looks like the NTP server time.nist.gov itself is having problems. `ntpdate` reports:

    > look@gear ~/Downloads/mover $ ntpdate -q time.nist.gov server
    > 129.6.15.28, stratum 0, offset 0.000000, delay 0.00000 11 Feb 13:11:05 ntpdate[5855]: no server suitable for synchronization found

so that may explain that your code fails.

Anyway, I refactored your code before testing before `delays` are source of all kind of problems. I run OK at the first test.

I only modify `loop`; everything else is the same. I made it a state machine with three states: `idle`, your are reading to send an UDP packet; `reading`, you are trying to read the answer; and `waiting`, where you spend 10 seconds doing nothing.

I also move all printing to a new `processPacket` function, to keep `loop` short and easy to read.

Never use delay(). Use the scheme provide here to wait using millis().

    void loop() {
     enum st {idle, reading, waiting};
     static st status;
     static unsigned long prev = 0;
     unsigned long now = millis();

     switch(status) {
     case idle:
      // get a random server from the pool
      WiFi.hostByName(ntpServerName, timeServerIP);

      sendNTPpacket(timeServerIP);
      status = reading;
      prev = now;
      break;

     case reading:
      if(now - prev > 1000L) {
       int cb = udp.parsePacket();

       if(cb) {
        status = idle;
        Serial.print("packet received, length=");
        Serial.println(cb);
        processPacket();
       } else {
        Serial.println("no packet yet");
       }

       prev = now;
      }

      break;

     case waiting:
      if(now - prev > 10000L) {
       status = idle;
       prev = now;
      }
     }
    }

    void processPacket()
    {
     char hours;
     char minutes;
     char seconds;

     // We've received a packet, read the data from it
     udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
     //the timestamp starts at byte 40 of the received packet and is four bytes,
     // or two words, long. First, esxtract 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);

     // now convert NTP time into everyday time:
     Serial.print("Unix time = ");
     // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
     const unsigned long seventyYears = 2208988800UL;
     // subtract seventy years:
     unsigned long epoch = secsSince1900 - seventyYears;
     // print Unix time:
     Serial.println(epoch);
     // print the hour, minute and second:
     minutes = ((epoch % 3600) / 60);
     minutes = minutes + MM; //Add UTC Time Zone
     hours = (epoch  % 86400L) / 3600;
     if(minutes > 59) {
      hours = hours + HH + 1; //Add UTC Time Zone
      minutes = minutes - 60;
     } else {
      hours = hours + HH;
     }
     Serial.print("The UTC time is ");       // UTC is the time at Greenwich //Meridian (GMT)
     Serial.print(hours,DEC); // print the hour (86400 equals secs per day)
     Serial.print(':');
     if(minutes < 10) {
        // In the first 10 minutes of each hour, we'll want a leading '0'
      Serial.print('0');
     }
     Serial.print(minutes,DEC); // print the minute (3600 equals secs per minute)
     Serial.print(':');
     seconds = (epoch % 60);
     if(seconds < 10) {
      // In the first 10 seconds of each minute, we'll want a leading '0'
      Serial.print('0');
     }
     Serial.println(seconds,DEC); // print the second
       u8g2.setFont(u8g2_font_ncenB14_tr);
     u8g2.firstPage();
     do {
        u8g2.setCursor(0, 20);
        u8g2.print(hours,DEC);
        u8g2.drawStr(25, 17,":");
        u8g2.setCursor(33, 20);
        u8g2.print(minutes,DEC);
        }
     while(u8g2.nextPage());
      }

And this is the output:

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

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


body:
I have implemented a very simple program that turns a LED off when a switch is pressed.

My code works, but, when the LED is in high state, the LED blinks fast then turns off.

When I try to use the switch, the LED lights up without me even touching the switch. It seems like there is an invisible current that flows.

Observing carefully, I found out that the body of my laptop is probably causing this issue. My laptop has a metal body.

Since my Arduino is powered via USB from my Laptop, on "HIGH" state and I touch the body of my laptop, the LED turns off but when I let go of my laptop, the LED turns back on but blinks very fast.

Pushing the switch button, turns off the LED but when I release the button, the LED lights up but blinks very fast again.

I tried using a power adapter set to 12V but it just lights up the LED on the arduino board but not the LED on the breadboard.

I tried plugging the USB to a desktop, it lights up the LEDs on the arduino board but not the LED on the breadboard as well.

The schema is like below.
[![enter image description here][1]][1]

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

My code works. It's just the rapid blinking stuff. Is it the static electricity or noise or something that is causing this issue?

    const int ledPin = 13;
    const int buttonPin = 7;

    int buttonState = 0;

    void setup(){
      Serial.begin(9600);
      pinMode(ledPin, OUTPUT);
      pinMode(buttonPin, INPUT);
    }

    void loop(){
      buttonState = digitalRead(buttonPin);
      if(buttonState == HIGH) {
        digitalWrite(ledPin, HIGH);
        Serial.println("LED ON +++++++++++");
      }
      else{
        digitalWrite(ledPin, LOW);
        Serial.println("LED OFF ------------");
      }
    }

title: Arduino keeps blinking when LED is in high

Answers: 0


body:
I've only started using Arduino in the last week, and I'm having a problem with the servo supplied with the kit I purchased. It's a SG90 microservo. I'm trying to connect the servo as shown on the [Arduino tutorial site][1]:

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

But when I connect the power and ground pins to the board, the board powers down and disconnects from the USB. I've had the servo working before without a problem.

Yesterday I was trying out another tutorial without any luck, and I noticed the servo getting hot (not too hot to touch though).

Could I have accidentally fried the control board in the servo?

  [1]: https://www.arduino.cc/en/Tutorial/Sweep
  [2]: https://i.stack.imgur.com/ZRNo3.png

title: Servo causes disconnection

Answers: 1

body:
Have a look at the current requirements of the SG90 and compare this to the maximum current available from an Arduino Uno.

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

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

Another thing to look at is how much current your computer's USB port can supply. My laptop, for example, can only supply 500mA per USB port.

My advise is to use a separate 5V power supply for the servo.


body:
My Arduino IDE does not compile any project since I updated from Mac OSX 10.6.8 to 10.11.6.

I even tried reinstalling and also manually installing the original AVR-toolchain. But the behaviour did not change.

I still get the following error messages

    signal: bus error
    Fehler beim Kompilieren für das Board Arduino/Genuino Uno.

English translation of the error message is:

    Error compiling for board Arduino/Genuino Uno.

 - Is this problem known? I could not find information about it.
 - Are there any known solutions to it?
 - Can I start Arduino IDE in debug
   mode to give some usefull output what exactly causes the crash?

**EDIT**

I am using the current IDE 1.8.5 and also tried the nightly builds. I also tried some older versions down to 1.6.0.

**EDIT 2:**

Arduino 1.0.5 produces the following error:

    cc1plus: internal compiler error: Segmentation fault: 11
    Please submit a full bug report,
    with preprocessed source if appropriate.
    See <http://gcc.gnu.org/bugs.html> for instructions.

Thanks for your help!

**EDIT 3**

After installing UECIDE (what went smoothly) I am facing the same problem. The error happens in the AVR toolchain when calling the avr-gcc 4.9.2 compiler. In UECID the output tab shows the following output (I added linebreaks for readability):

    ~/Library/uecide/compilers/avr-gcc/bin/avr-g++
      -c /var/folders/2h/8pdnzj197tq906bzs81ksn6m0000gn/T/build-faf1be1e-2186-438b-9e1a-c56f50ce26d1/MySource.cpp
      -o /var/folders/2h/8pdnzj197tq906bzs81ksn6m0000gn/T/build-faf1be1e-2186-438b-9e1a-c56f50ce26d1/MySource.cpp.o
      -mmcu=atmega328p -g -std=gnu++11 -fno-threadsafe-statics
      -fno-exceptions -ffunction-sections -fdata-sections
      -DF_CPU=16000000L -DARDUINO=106 -DARDUINO_UNO -DARDUINO_ARCH_AVR
      -I~/Library/uecide/cores/arduino/arduino
      -I~/Library/uecide/boards/Arduino/arduino-uno
      -I/var/folders/2h/8pdnzj197tq906bzs81ksn6m0000gn/T/build-faf1be1e-21
    86-438b-9e1a-c56f50ce26d1
      -I~/pro/Arduino/MySource -Os -w

The status tab of UECID only shows `Compiling Failed`.

**EDIT 4**

After starting UECID from console with `--debug --verbose` options specified it did print the failing command to console:

    ~/Library/uecide/compilers/avr-gcc/bin/avr-g++
       -c /var/folders/2h/8pdnzj197tq906bzs81ksn6m0000gn/T/build-5ccb5f12-fcd1-4893-8c41-39fc056ec544/MySourve.cpp
       -o /var/folders/2h/8pdnzj197tq906bzs81ksn6m0000gn/T/build-5ccb5f12-fcd1-4893-8c41-39fc056ec544/MySourve.cpp.o
       -mmcu=atmega328p -g -std=gnu++11 -fno-threadsafe-statics
       -fno-exceptions -ffunction-sections -fdata-sections
       -DF_CPU=16000000L -DARDUINO=106 -DARDUINO_UNO -DARDUINO_ARCH_AVR
       -I~/Library/uecide/cores/arduino/arduino
       -I~/Library/uecide/boards/Arduino/arduino-uno
       -I/var/folders/2h/8pdnzj197tq906bzs81ksn6m0000gn/T/build-5ccb5f12-fcd1-4893-8c41-39fc056ec544
       -I~/pro/Arduino/MySourve -Os -w

This command is identical to the one created by Arduino.

I found another hint on a [bug in gcc 4.8 that seems not to be AVR specific][1].

After reducing the command line to

    ~/Library/uecide/compilers/avr-gcc/bin/avr-g++
      -c /var/folders/2h/8pdnzj197tq906bzs81ksn6m0000gn/T/build-5ccb5f12-fcd1-4893-8c41-39fc056ec544/MySource.cpp
      -o /var/folders/2h/8pdnzj197tq906bzs81ksn6m0000gn/T/build-5ccb5f12-fcd1-4893-8c41-39fc056ec544/MySource.cpp.o

the crash stays the same: `Segmentation fault 11`

  [1]: https://github.com/arduino/Arduino/issues/2336

title: AVR-Toolchain for Arduino crashes on Mac OSX 10.11.6: Hints or debugging help needed

Answers: 0


body:
I am new to arduino and therefore not much experience in handling codes, please be forgiving and help me!

For my school project, make use of arduino to make 4 capacitive sensors (which has already been successful). Now I am trying to make use of the 4 sensors to be shown in a table format(one for each output) so that I can use that data to be plotted into either Excel or Matlab. Hence I would like to ask how do I group up my data into different columns? Also is it possible to get convert my results into binary format so that it would be easier when trying to plot the data?

My arduino code is here:

    #include <CapacitiveSensor.h>

    CapacitiveSensor   cs_2_4 = CapacitiveSensor(2,4); // 1M resistor between pins 4 & 8, pin 8 is sensor pin, add a wire and or foil
    CapacitiveSensor   cs_5_7 = CapacitiveSensor(5,7);
    CapacitiveSensor   cs_8_10 = CapacitiveSensor(8,10);
    CapacitiveSensor   cs_11_13 = CapacitiveSensor(11,13);
    void setup()
    {
       cs_2_4.set_CS_AutocaL_Millis(0xFFFFFFFF);// turn off autocalibrate on channel 1 - just as an example
       cs_5_7.set_CS_AutocaL_Millis(0xFFFFFFFF);
       cs_8_10.set_CS_AutocaL_Millis(0xFFFFFFFF);
       cs_11_13.set_CS_AutocaL_Millis(0xFFFFFFFF);
     Serial.begin(9600);
       pinMode(3,OUTPUT);
       pinMode(6,OUTPUT);
       pinMode(9,OUTPUT);
       pinMode(12,OUTPUT);
    }

    void loop()
    {
     long sensor1 =  cs_2_4.capacitiveSensor(50);
     long sensor2 =  cs_5_7.capacitiveSensor(50);
     long sensor3 =  cs_8_10.capacitiveSensor(50);
     long sensor4 =  cs_11_13.capacitiveSensor(50);

    Serial.println(sensor1);  // print sensor output
        Serial.print("\t");
        Serial.println(sensor2);
        Serial.print("\t");
        Serial.println(sensor3);
        Serial.print("\t");
        Serial.println(sensor4);
     if(sensor1 >= 1000)
       {
        digitalWrite(3,HIGH);
       }
      else{
        digitalWrite(3,LOW);
       }
         if(sensor2 >= 1000)
       {
        digitalWrite(6,HIGH);
       }
       else{
        digitalWrite(6,LOW);
       }
        if(sensor3 >= 1000)
       {
        digitalWrite(9,HIGH);
       }
       else{
        digitalWrite(9,LOW);
       }
        if(sensor4 >= 1000)
       {
        digitalWrite(12,HIGH);
       }
       else{
        digitalWrite(12,LOW);
       }

       }

And with that code above the output I receive when I use the serial monitor is:

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

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

title: How do I get multiple readings(binary) based on my arduino output?

Answers: 1

body:
>     Serial.println(sensor1);  // print sensor output
    Serial.print("\t");
    Serial.println(sensor2);
    Serial.print("\t");
    Serial.println(sensor3);
    Serial.print("\t");
    Serial.println(sensor4);

If you want 4 columns don't use `println` for each number, as that starts a new line.

---

> Also is it possible to get convert my results into binary format so that it would be easier when trying to plot the data?

Yes it's possible however I don't see how that makes anything easier.


body:
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.

title: Is there a way to play .mp3 files from an SD card on Arduino?

Answers: 3

body:
It's not as easy as that. The SD card and playing audio are two different things.

However, probably the easiest way is to buy an MP3 shield (but that spoils the fun to make it yourself).

On the other hand, to make it yourself, takes quite some effort.

Also, the audio quality will be very low.
Besides that, decoding MP3 is far from trivial.

In case you want to make it yourself:

- First write a program to read (stream) bytes from the SD card
- Write an MP3 decoder (maybe/probably there are open source variants)
- Forward the MP3 bytes to the decoder
- Forward the audio bytes to the buzzer

Of course, there are time constraints otherwise you hear gaps in the music.

body: If you're not specifically trying to make the arduino itself do the decoding and playback, you can get something like the [Mini DFPlayer](https://www.dfrobot.com/product-1121.html) 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.

body:
I believe MP3 uses licensed software that is implemented on decoder chips like VS1053.
Usually one would use a board like this, with an SD card for holding the massive amount of info that makes a sound.
<http://www.oddwires.com/mp3-decoder-module-vs1053-for-arduino/?gclid=EAIaIQobChMInKS7lJGm2QIVE4_ICh1kTQa4EAQYAiABEgIKH_D_BwE>
You then send commands to the unit to tell it to start, stop, advance, etc.


body:
I am new to Arduino. Sorry if my question sounds wrong.

Interest areas: Multiple devices inter-connected on the cloud.
Single GSM for equipment in a typical panel connectivity for non-electrical parameter sensing devices e.g. Temperature, humidity.
Mechanical operations & connection status
Parameters of individual devices [non-communication capable]
Connectivity with cloud

Interest areas: Connectivity for electromechanical devices – Contactors, MCBs, RCCB etc
Parameters possible on IOT
Device Status possible on IOT
Size [Compactness] of the IOT solution to be integrated
Aux Power requirement & possible ways to provide the same
Memory retention
Remote access/control and driving of the devices
The estimated cost of the IoT connectivity devices should be a fraction of the device cost [e.g. Contactor of 9A].
Voltage level high

I am trying to read the status of more than 50 contactors i.e whether they are in ON\OFF\trip state using Arduino and display it on screen.

Can I use a single microcontroller to read the status of 50 or more contactors?

I searched on the net and I found out it can be done using shift registers or a latching system, but I didn't understand the method at all.

Please, can anyone explain me the method of doing this?Thanks.

title: How do I get status of contactors using Arduino (more than 50 contactors)

Answers: 2

body:
Yes you can.

There are special ICs, called Shift-In registers to do this job. You can daisy chain 4 of them, each capable of handling 8 outputs or inputs.

The most known is for outputs (e.g. LEDs) which is a 74HC595 (called shift-out register).

For inputs. you can use a CD4021BE. See the [Shiftin Example][1] how to use them.
It will cost 3 pins (except VCC/GND) to control 32 inputs, so you need 6 pins for 50 (max 64). You need 50 / 8 = 7 of these ICs, but they are very cheap (10 for about 2 dollars).

Note that you will receive either a 0 or 1, so it's up to you how to detect trip states.

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

body:
Due to lack of specifics, I cannot be more precise with my answer, but since you are working with "high" voltage (I'll assume 220V/415V) I would suggest the best solution to monitoring the current will be current transformers.

These are non-intrusive devices that you pass a single conductor through. It generates a small current in proportion to a large current flowing through the conductor.

This small current is then converted into a small voltage by passing it through a resistor and then measuring the voltage across that resistor.

Since it is AC you are dealing with simple digital IO pins will not suffice (except see below) - no matter how many you have. You need analog inputs, and you need to be able to sample that analog signal fast enough to at least capture the peaks and troughs of the incoming waveform. That means sampling at many times the frequency of the supply. For 50Hz you want to sample either at, say, 500 sps or more, or to sample at a rate that isn't a multiple of, or factor of, 50, but for a longer period of time.

Interfacing an AC voltage like this involves adding an offset voltage to it so that the zero point of the AC voltage lies in the middle of the ADC's range. This is most often done by feeding a voltage of 50% Vcc into the current transformer as a "virtual ground", so all output from it is superimposed on this offset voltage.

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

Once you know the peak to peak voltage across the load resistor of the current transformer you can use that to calculate the peak to peak current the current transformer generated (Ohm's law), and thus the current through the central conductor.

This not only gives you the actual current through the conductor, but by simple logical reasoning, also gives you the state of the contactor: no current = contactor is off.

To reduce programming complexity at the cost of increased BOM cost it could be possible to build a simple rectifying and smoothing circuit (i.e., a simple integrating circuit) from diodes and a capacitor (either a single diode and a capacitor as a half-wave rectifier and smoothing, or a full-wave rectifier and smoothing) which will give you a simple DC voltage proportional to the current. Don't forget to take into account the voltage drop of the diode (or diodes) when doing your calculations, of course.

The integrating circuit could also be used, if you don't care about the current, to directly drive a digital input, as long as the voltage generated under normal load is above the threshold (VIH) of the IO pin, and never exceeds the maximum input voltage for the pin (a little over 5V).  Adding a 5.1V zener diode and series resistor can help protect the input. The same should be done to an analog input as well to protect it from overvoltage.

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

One important thing with this integrating circuit, though, is that any downward changes in the current will take time to be reflected in the output. That is caused by the time C1 takes to discharge down to the new voltage level through R1. Balancing these values so you get a reasonable amount of responsiveness yet minimum amount of ripple on the signal will take a little experimentation and calculation.

You can read more about current transformers and interfacing them to an Arduino [here](https://openenergymonitor.org/forum-archive/node/156.html).

----

For interfacing so many sensors to an Arduino you can, depending on if you are wanting to measure the current directly, or integrate the current to a DC voltage and use it as a threshold to a GPIO pin:

* Use shift registers (Parallel-to-Serial) for digital threshold reading,
* Use IO expanders (eg MCP23017) for digital threshold reading,
* Use external ADC chips (eg MCP3208) to provide more ADC inputs, or
* Use analog multiplexers (eg CD4051) to switch different analog voltages to a limited number of ADC inputs

Another option is to break your system down into smaller, more manageable, chunks.  Group your signals into small subsections and have each subsection handled by a separate controller - be that an Arduino (maybe a Mini, or a Micro, or something) to handle a small group of signals. These can then feed their data into a more powerful management system (maybe a Raspberry Pi) through a serial protocol of some form (or wirelessly if you want to spend extra money), which then forwards the readings on to your chosen web service.


body:
I'm trying to use an accelerometer for user input to a device. The idea is that the user input will be tied to "taps" on the accelerometer, one tap means something, two taps something else, etc.

I'm using an Adafruit Feather M0 as my microcontroller, controlling an accelerometer that feeds me x,y,z-data at a sampling rate of 100 Hz. I now then want to high pass filter the data with a cutoff frequency of 10 Hz, since taps on the accelerometer give rise to much higher frequencies than other "noise", such as movement.

The accelerometer uses a FIFO buffer to output the data, so I collect 20 samples at a time, and I want to filter those 20 samples with a high pass filter to see if there is a tap within that sampling window. I am currently using the filter function on Arduino playground, https://playground.arduino.cc/Code/Filters.

However, and here is my problem; When I implement this in my code, the filtering "restarts" each window, so that my filtered data looks like this:

    [X], [Y], [Z]
    0.00,0.00,0.00
    -39.67,94.13,-85.18
    -29.89,71.66,-64.18
    -24.02,53.99,-49.08
    -17.39,40.78,-37.09
    -13.00,30.51,-27.74
    -9.80,22.99,-20.91
    -7.58,17.00,-16.17
    -7.01,13.88,-14.01
    -4.86,12.04,-10.53
    -4.02,9.96,-8.71
    -2.44,8.05,-7.04
    -1.99,6.57,-5.74
    -1.60,5.26,-3.80
    -2.76,3.27,-4.45
    -1.43,2.67,-3.63
    -1.16,2.16,-2.13
    -0.94,2.55,-1.72
    -0.76,1.26,-0.58
    -0.62,0.21,-1.29

    0.00,0.00,0.00
    -40.26,94.51,-84.88
    -30.38,70.55,-64.78
    -22.13,53.89,-48.04
    -17.42,40.60,-37.69
    -13.91,29.87,-27.68
    -10.99,23.61,-22.67
    -10.05,19.04,-16.00
    -5.78,14.79,-13.94
    -4.69,12.82,-11.31
    -3.84,9.69,-9.27
    -3.14,7.91,-7.56
    -2.52,6.35,-6.08
    -2.07,5.22,-4.18
    -0.88,4.29,-3.43
    -2.35,4.32,-3.62
    -0.29,3.54,-2.97
    -1.07,2.94,-3.29
    -1.63,0.74,-1.02
    -0.50,1.38,-1.60

    0.00,0.00,0.00
    -40.51,95.10,-85.37
    -30.32,70.41,-65.39
    -22.86,53.10,-49.31
    -17.26,40.83,-35.71
    -13.45,31.81,-27.81
    -9.37,22.43,-20.92
    -7.80,17.62,-15.74
    -6.50,13.01,-13.10
    -4.04,9.56,-8.16
    -3.02,7.15,-6.85
    -2.29,5.42,-4.43
    -2.70,3.63,-4.46
    -1.38,4.56,-3.61
    -1.14,2.95,-2.16
    -1.73,2.38,-1.75
    -1.32,2.59,-2.10
    -1.05,0.47,-1.67
    -0.04,1.12,-1.28
    -0.03,0.90,-1.03

I don't understand why this happens, and why the data in the subsequent windows aren't suppressed from the start. I have implemented a very similar solution in Python which works very well with the filtering. Have I misunderstood how Arduinos filtering functions work?

Here is my code:

    // Include SPI library
    #include <SPI.h>
    #include <Filters.h>

    // List of addresses: 7-bit adresses, 8th bit is R/W bit, and is set in the functions readRegister and writeRegister.
    char X_data_low = 0x28;
    char X_data_high = 0x29;
    char Y_data_low = 0x2A;
    char Y_data_high = 0x2B;
    char Z_data_low = 0x2C;
    char Z_data_high = 0x2D;

    char CTRL_REG1 = 0x20; // Controls data rate selection, low power mode, and X-, Y- and Z-axis enable
    char CTRL_REG1_value = 0b00101111; // 0001 1111 = 1 Hz, LP mode, XYZ enable.

    char CTRL_REG5 = 0x24; // Enables FIFO mode, among others.
    char CTRL_REG5_value = 0b01000000; // 0100 0000, FIFO enabled, all else is zero.

    char STATUS_REG = 0x27; // Flags for new XYZ values.

    char FIFO_CTRL_REG = 0x2E; // Controls FIFO mode (Bypass, FIFO, Stream, Stream-To-FIFO)
    char FIFO_CTRL_REG_value = 0b01000000; // Selects FIFO mode

    char FIFO_SRC_REG = 0x2F; // Watermark level, FIFO Overrun, FIFO empty, FSS. Can read FSS to know how many unread samples FIFO buffer contains currently.

    //int smpls = 20; // Number of samples

    char values[240]; // buffer for storing read values.

    int x_val[40]; // Arrays for storing values before filtering
    int y_val[40];
    int z_val[40];

    float filtered_x_val[40]; // Arrays for storing values after filtering
    float filtered_y_val[40];
    float filtered_z_val[40];

    int CS = 5; // Chip select pin

    int concat_val = 0b00011111; // For concatenation with values[0] to find number of samples in FIFO buffer
    int number_of_FIFO_values; // Number of FIFO samples

    // Testing Arduinos own filtering

    // filters out changes slower that 10 Hz.
    float filterFrequency = 10.0;

    // create a one pole (RC) lowpass filter
    FilterOnePole highpassFilter_x( HIGHPASS, filterFrequency );
    FilterOnePole highpassFilter_y( HIGHPASS, filterFrequency );
    FilterOnePole highpassFilter_z( HIGHPASS, filterFrequency );

    void setup() {
      // put your setup code here, to run once:
      // Opening pins
      pinMode(22, INPUT_PULLUP); // MISO
      pinMode(24, OUTPUT); // SCK
      pinMode(23, OUTPUT); // MOSI
      pinMode(CS, OUTPUT);  // CS
      pinMode(14, OUTPUT);  // VDD_IO, for use when no breadboard is available to connect both VDD and VDD_IO to 3.3V output
      digitalWrite(CS, HIGH);
      digitalWrite(14, HIGH);
      delay(50);

      // Communication with computer
      Serial.begin(9600);

      // SPI
      SPI.begin();
      SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
      // Loading settings
      delay(10);
      writeRegister(CTRL_REG1,CTRL_REG1_value);
      delay(10);
      writeRegister(CTRL_REG5,CTRL_REG5_value);
      delay(10);
      writeRegister(FIFO_CTRL_REG,FIFO_CTRL_REG_value);
      delay(10);

    }

    void loop() {
      readRegister(0x2F,1,values);
      number_of_FIFO_values = values[0] & concat_val;

      if (number_of_FIFO_values >= 20){ // It is enough to read high values since LP mode is only 8 bits
        readRegister(0x28,120,values);
        int x_count = 0; // Counters to keep track of which value in x_val, y_val, z_val to be assigned
        int y_count = 0;
        int z_count = 0;
        for(int i=0; i<120; i++){
          if (i % 6 == 1) {
            x_val[x_count] = int(values[i]);
            if(x_val[x_count] > 127)
              x_val[x_count] -= 256;
            x_count += 1;
            }
          if (i % 6 == 3) {
            y_val[y_count] = int(values[i]);
            if(y_val[y_count] > 127)
              y_val[y_count] -= 256;
            y_count += 1;
            }
          if (i % 6 == 5) {
            z_val[z_count] = int(values[i]);
            if(z_val[z_count] > 127)
              z_val[z_count] -= 256;
            z_count += 1;
            }
          }
        Serial.print('\n');
        filtering(x_val,y_val,z_val);
        writeRegister(FIFO_CTRL_REG,0b00000000);
        delay(10);
        writeRegister(FIFO_CTRL_REG,FIFO_CTRL_REG_value);
        delay(10);
      }
    }

    void filtering(int x_arr[], int y_arr[], int z_arr[]){
        for(int i=0; i<20; i++) {
          highpassFilter_x.input(x_arr[i]);
          highpassFilter_y.input(y_arr[i]);
          highpassFilter_z.input(z_arr[i]);
          filtered_x_val[i] = highpassFilter_x.output();
          filtered_y_val[i] = highpassFilter_y.output();
          filtered_z_val[i] = highpassFilter_z.output();
          Serial.print(filtered_x_val[i]);
          Serial.print(",");
          Serial.print(filtered_y_val[i]);
          Serial.print(",");
          Serial.print(filtered_z_val[i]);
          Serial.print('\n');
        }
      }

    //This function will write a value to a register on the sensor.
    // Parameters:
    //  char registerAddress - The register to write a value to
    //  char value - The value to be written to the specified register.
    // The bits to specify write or read operation on slave device, and single
    // or multiple register reading in reading operation, are included in the
    // registeraddress.
    // As defined by protocol, the MSB of the address indicates write/read, and the following bit indicate single/multiple reading. Cause ADXL345 support Byte operation,
    // The MSB is the 8th bit, the following bit is the 7th bit. (note: if indicating multiple bits reading, ADXL345 will increasing the register address automatically to the
    // next successive register like a pointer.
    void writeRegister(char registerAddress, char value){
      //Set Chip Select pin low to signal the beginning of an SPI packet.
      digitalWrite(CS, LOW);
      //Transfer the register address over SPI.
      // All ADXL345 register address are smaller than 0100 0000, all are like 00** ****, so that any register address of ADXL345 can be used directly for register write operation
      // without any change on the MSB and its following bit, but the case for reading operation is the opposite.
      // Might need a delay here between CS going low and data transfer.
      SPI.transfer(registerAddress);
      //Transfer the desired register value over SPI.
      // ignored the reture of SPI.transfer in writer operation
      SPI.transfer(value);
      //Set the Chip Select pin high to signal the end of an SPI packet.
      digitalWrite(CS, HIGH);
    }

    //This function will read a certain number of registers starting from a specified address and store their values in a buffer.
    //Parameters:
    //  char registerAddress - The register addresse to start the read sequence from.
    //  int numBytes - The number of registers that should be read.
    //  char * values - A pointer to a buffer where the results of the operation should be stored.
    void readRegister(char registerAddress, int numBytes, char * values){
      //Since we're performing a read operation, the most significant bit (bit 7(counting starts from bit 0)) of the register address should be set high.
      char address = 0x80 | registerAddress;
      //If we're doing a multi-byte read, bit 6 (counting starts from bit 0)needs to be set high as well.
      if(numBytes > 1)address = address | 0x40;

      //Set the Chip select pin low to start an SPI packet.
      digitalWrite(CS, LOW);
      //Transfer the starting register address that needs to be read.
      SPI.transfer(address);
      //Continue to read registers until we've read the number specified, storing the results to the input buffer.
      //SPI is full duplex transsmission. Every signle time SPI.transfer can and can only transmit 8 bits. the input parameter will be delived to slave, and it's return will be
      // the data that master device and get from the slave device. The data returned during master device's write operation makes no sense, hence always been ignored by not
      // doing any assignment operation.
      for(int i=0; i<numBytes; i++){
        values[i] = SPI.transfer(0x00);
      }
      //Set the Chips Select pin high to end the SPI packet.
      digitalWrite(CS, HIGH);
    }

title: High pass filtering accelerometer data on Arduino

Answers: 1

body:
This filter library is sensitive to the timing of you calling
`FilterOnePole::input()`. It assumes that the delays between consecutive
calls are the same as the delays between the samples being measured.
C.f. the first statement in the method, which is [a call to
`micros()`][micros]. The pauses between your 20-sample buffers are then
interpreted like long times during which the input only changed very
little.

If you are sampling at a constant data rate, I recommend you reimplement
the filter yourself: it is simple enough and it will be way more
efficient than the one you found on Playground.

------------------------------------------------------------------------

**Edit**: Here is a simple implementation of a first-order high-pass
filter like the one in the library, but using a constant sampling rate:

    class HigPassFilter
    {
    public:
        HigPassFilter(float reduced_frequency)
        : alpha(1-exp(-2*M_PI*reduced_frequency)), y(0) {}
        float operator()(float x) {
            y += alpha*(x-y);
            return x-y;
        }
    private:
        float alpha, y;
    };

You would use it like this:

    // Create the filters.
    HigPassFilter highpassFilter_x(cutoffFrequency/samplingFerquency);
    HigPassFilter highpassFilter_y(cutoffFrequency/samplingFerquency);
    HigPassFilter highpassFilter_z(cutoffFrequency/samplingFerquency);

    // Apply them.
    filtered_x_val[i] = highpassFilter_x(x_arr[i]);
    filtered_y_val[i] = highpassFilter_y(y_arr[i]);
    filtered_z_val[i] = highpassFilter_z(z_arr[i]);

[micros]: https://github.com/JonHub/Filters/blob/aeb294b4a66cf5dc30d5998cc221115dec95eb80/FilterOnePole.cpp#L20


body:
I am working on a music shield, I want to play a sound when a sensor triggers (it is very noob I know) well The music shield manufacturer provides a simple class named MusicPlayer here you can find its source

    #include <SD.h>
    #include <MusicPlayer.h>
    #include  <avr/pgmspace.h>

    // change this to match your SD shield or module;
    // Arduino Ethernet shield: pin 4
    // Adafruit SD shields and modules: pin 10
    // Sparkfun SD shield: pin 8

    static unsigned char fileBuf[32];
    songtype list[15];            //song list
    int ledcount;
    key keys[5];

    VS10XX VS1053;
    Sd2Card     card;
    SdVolume    volume;
    SdFile root;
    SdFile file;
    playingstatetype playingState;
    ctrlStatetype ctrlState;

    /* PCM file Header */
    unsigned char pcmHeader[44] = {
      'R', 'I', 'F', 'F',
      0xFF, 0xFF, 0xFF, 0xFF,
      'W', 'A', 'V', 'E',
      'f', 'm', 't', ' ',
      0x10, 0, 0, 0,          /* 16 */
      0x1, 0,                 /* PCM */
      0x1, 0,                 /* chan */
      0x40, 0x1F, 0x0, 0x0,   /* sampleRate */
      0x80, 0x3E, 0x0, 0x0,   /* byteRate */
      2, 0,                   /* blockAlign */
      0x10, 0,                /* bitsPerSample */
      'd', 'a', 't', 'a',
      0xFF, 0xFF, 0xFF, 0xFF
    };

    /**************************************************************/
    ISR(TIMER1_OVF_vect)          //Timer1 Service
    {
     for(int i=0;i<5;i++)
     {
      keys[i].scanKey();
     }

     if (playingState == PS_PAUSE) digitalWrite(LED, HIGH);
     else if (playingState == PS_IDLE) digitalWrite(LED,LOW);
     else
     if (ledcount-- == 0)
     {
      digitalWrite(LED,!digitalRead(LED));
      ledcount = 500;
     }
    }

    /**************************************************************/
    #define RESOLUTION 65536    // Timer1 is 16 bit
    void MusicPlayer::initTimer1(void)        //initialize Timer1 to 100us overflow
    {
      TCCR1A = 0;                 // clear control register A
      TCCR1B = _BV(WGM13);        // set mode as phase and frequency correct pwm, stop the timer

      long cycles;
      long microseconds = 500;   //setup microseconds here
      unsigned char clockSelectBits;
      cycles = (F_CPU / 2000000) * microseconds;                                // the counter runs backwards after TOP, interrupt is at BOTTOM so divide microseconds by 2
      if (cycles < RESOLUTION)              clockSelectBits = _BV(CS10);              // no prescale, full xtal
      else if ((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11);              // prescale by /8
      else if ((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10);  // prescale by /64
      else if ((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12);              // prescale by /256
      else if ((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10);  // prescale by /1024
      else        cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10);  // request was out of bounds, set as maximum

      ICR1 = cycles;
      TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
      TCCR1B |= clockSelectBits;                                          // reset clock select register, and starts the clock

      TIMSK1 = _BV(TOIE1);
      TCNT1 = 0;
      sei();                      //enable global interrupt
    }

    /**************************************************************/
    void MusicPlayer::initIO(void)
    {
      pinMode(SD_CS_PIN, OUTPUT);
      digitalWrite(SD_CS_PIN, HIGH);

      pinMode(VS_XCS, OUTPUT);
      digitalWrite(VS_XCS, HIGH);

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

      //keys input
      pinMode(KEY_VD, INPUT);
      pinMode(KEY_BK, INPUT);
      pinMode(KEY_PS, INPUT);
      pinMode(KEY_NT, INPUT);
      pinMode(KEY_VU, INPUT);
      //internal pull-up
      digitalWrite(KEY_VD, HIGH);
      digitalWrite(KEY_BK, HIGH);
      digitalWrite(KEY_PS, HIGH);
      digitalWrite(KEY_NT, HIGH);
      digitalWrite(KEY_VU, HIGH);
    }

    /**************************************************************/
    void MusicPlayer::initSD(void)
    {

      char i = 0;
      dir_t p;
      char name[13];

      /* init sd card */
      if(!card.init(SPI_FULL_SPEED, SD_CS_PIN))   //SPI_FULL_SPEED
      {
        Serial.println("SD initialization failed.");
     while(1);
      }
      if (!volume.init(card))
      {
        Serial.println("Could not find FAT16/FAT32 partition.");
        while(1);
      }
      root.openRoot(volume);
      Serial.println("---- songs in TF card (root dir) ----");
      while(root.readDir(&p) != 0)
      {
        SdFile::dirName(p, name);
     char *s = name;
     s = strupr(s);
     if(strstr(s,".MP3")||strstr(s,".WAV")||strstr(s,".WMA")||strstr(s,".OGG")
                 ||strstr(s,".AAC"))
        {
      uint32_t curPos = root.curPosition();
      uint16_t index = (curPos - 32) >> 5;
      if (file.open(&root,index, O_READ))
      {
       file.close();
       strncpy(list[i].name, name, 13);
       list[i].index = index;
       Serial.println(list[i++].name);
      }
        }
      }
      Serial.println();
      MaxSong = (i-1);
    }

    /**************************************************************/
    void MusicPlayer::begin(void)
    {
     keys[0].setKey(KEY_PS,CS_PLAYPAUSE);
       keys[1].setKey(KEY_VD,CS_DOWN);
     keys[2].setKey(KEY_VU,CS_UP);
       keys[3].setKey(KEY_BK,CS_PREV);
       keys[4].setKey(KEY_NT,CS_NEXT);

       initIO();
       initSD();
       VS1053.init();
       initTimer1();  // init timer1
    }

    /**************************************************************/
    void key::setKey(unsigned char io,unsigned char return_value)
    {
      _io = io;
      _return_value = return_value;
      _key_st = KS_IDLE;
      _keycnt = 0;
    }

    /**************************************************************/
    void key::scanKey(void)
    {
      switch (_key_st)
      {
      case KS_IDLE:
        if (digitalRead(_io) == LOW) _key_st = KS_PRESS;
        _keycnt = 0;
        break;
      case KS_PRESS:
        if (digitalRead(_io) == LOW)
        {
           _keycnt++;
        } else
        {
      if (_keycnt > 20)   //10ms, short press
           {
             ctrlState = (ctrlStatetype)_return_value;
           }
           if (_keycnt > 1000) //50 ms,long press
           {
             if((ctrlStatetype)_return_value == CS_PLAYPAUSE)ctrlState = CS_RECORDING;
           }
          _keycnt = 0;
           _key_st = KS_IDLE;

      if(ctrlState == CS_PLAYPAUSE)
      {
       if(playingState == PS_PAUSE)playingState = PS_PLAY;
       else playingState =PS_PAUSE;
       ctrlState = CS_EMPTY;
      }
      if(ctrlState == CS_RECORDING)
      {
       playingState = PS_RECORDING;
       ctrlState = CS_EMPTY;
      }
        }
        break;
      default:
        break;
      }
    }

    /**************************************************************/
    void MusicPlayer::play()
    {

     unsigned char bytes;        // How many bytes in buffer left
     unsigned char n;

     SPI.setClockDivider(SPI_CLOCK_DIV2);
     if(file.open(&root,list[songIndex].index,O_READ))
       {
      Serial.print("Playing ");
      Serial.println(list[songIndex].name);
       }
     else
     {
      Serial.print("Could not open: ");
      Serial.println(list[songIndex].name);
      songIndex ++;
      while(1);
     }

     playingState = PS_PLAY;
     while(bytes = file.read(fileBuf,sizeof(fileBuf)))
     {
            // actual audio data gets sent to VS10xx.
            VS1053.writeData(fileBuf,bytes);

      switch (playingState)
      {
       case PS_PLAY:
        switch(ctrlState)
        {
         case CS_UP:
          Vol += 10;
          if (Vol > MaxVol)Vol = MaxVol;
          VS1053.writeRegister(SPI_VOL, Vol*0x101);     //Set volume level
          ctrlState = CS_EMPTY;
          break;
         case CS_DOWN:
          Vol -= 10;
          if (Vol < 0)Vol = 0;
          VS1053.writeRegister(SPI_VOL,Vol*0x101);      //Set volume level
          ctrlState = CS_EMPTY;
          break;
         case CS_NEXT:
          if (++songIndex > MaxSong)songIndex = 0;
          file.close();
          VS1053.softReset();
          ctrlState = CS_EMPTY;
          return;
         case CS_PREV:
          if (--songIndex < 0)songIndex = MaxSong;
          file.close();
          VS1053.softReset();
          ctrlState = CS_EMPTY;
          return;
         default:
          break;
        }
        break;
       case PS_PAUSE:
        while(playingState == PS_PAUSE);         //Pause
        break;
       case PS_RECORDING:
        file.close();
        VS1053.softReset();
           return;
      }

     }
     file.close();
     VS1053.softReset();
     Serial.println("[done!]");
     songIndex++;

    }

    /**************************************************************/
    void Set32(unsigned char *d, unsigned int n) {
      int i;
      for (i=0; i<4; i++) {
        *d++ = (unsigned char)n;
        n >>= 8;
      }
    }

    /**************************************************************/
    void MusicPlayer::recording(char *recfile) {
        unsigned long fileSize = 0;
        unsigned int n;

        VS1053.writeRegister(SPI_BASS, 0x0055);    //set accent
        VS1053.writeRegister(SPI_AICTRL0,8000);    //samplerate 8k
        VS1053.writeRegister(SPI_AICTRL1,0);       //record gain
        VS1053.writeRegister(SPI_AICTRL2,0);       //Set the gain maximum,65536=64X
        VS1053.writeRegister(SPI_AICTRL3,6);       //PCM Mode ,left channel
        VS1053.writeRegister(SPI_CLOCKF,0x2000);   //set clock

        VS1053.writeRegister(SPI_MODE,0x1804);   //mic,Initialize recording
        delay(2);

        VS1053.loadPlugin(recPlugin,sizeof(recPlugin)/sizeof(recPlugin[0]));

     SPI.setClockDivider(SPI_CLOCK_DIV2);
     file.remove(&root,recfile);

     //if(file.open(&root,recfile,O_WRITE|O_CREAT) == NULL)
     if(!file.open(&root,recfile,O_WRITE|O_CREAT))
       {
      Serial.println("Rec open fail");
      return;
       }
     playingState == PS_RECORDING;
     Serial.println("Recording ...");

     while(playingState != PS_PAUSE)
     {
      if ((n = VS1053.readRegister(SPI_HDAT1)) > 0)
      {
                    //Make little-endian conversion for 16-bit PCM .WAV files
                   for (char i=0; i<n;i++) {
                       unsigned int w = VS1053.readRegister(SPI_HDAT0);
                       file.write((unsigned char)(w & 0xFF));
                       file.write((unsigned char)(w >> 8));
                    }
                   fileSize += 2*n;
      }
     }
       /* Update file sizes for an RIFF PCM .WAV file */
         file.seekSet(0);
            Set32(pcmHeader+4, fileSize-8);
            Set32(pcmHeader+40, fileSize-36);
            file.write(pcmHeader, sizeof(pcmHeader));
            file.close();

            /* Finally, reset the VS10xx software, including realoading the
                 patches package, to make sure everything is set up properly. */
            VS1053.softReset();
    }

    /**********************************Midi Player Part***************************/
    void MusicPlayer::beginMidi(void)
    {
      //Init VS105B in Midi Format
      Serial.print("Init vs10xx in MIDI format...");
      VS1053.initForMidi();
      Serial.print("done\r\n");
    }

    void MusicPlayer::midiWriteData(char cmd, char high, char low)
    {
      while(!digitalRead(VS_DREQ));
      digitalWrite(VS_XDCS, LOW);
      midiSendByte(cmd);
      if((cmd & 0xF0) <= 0xB0 || (cmd & 0xF0) >= 0xE0)
      {
        midiSendByte(high);
        midiSendByte(low);
      }
      else
      {
        midiSendByte(high);
      }
      digitalWrite(VS_XDCS, HIGH);
    }

    void MusicPlayer::midiNoteOn(char channel, char note, char rate)
    {
      midiWriteData((0x90 | channel), note, rate);
    }

    void MusicPlayer::midiNoteOff(char channel, char note, char rate)
    {
      midiWriteData((0x80 | channel), note, rate);
    }

    void MusicPlayer::midiSendByte(char data)
    {
      SPI.transfer(0x00);
      SPI.transfer(data);
    }

    void MusicPlayer::midiDemoPlayer(void)
    {
      delay(1000);
      midiWriteData(0xB0, 0x07, 170);   //channel volume

      //GM2 Mode
      Serial.print("Fancy Midi Sounds\r\n");
      midiWriteData(0xB0, 0, 0x78);     //Bank select drums
      for(int instrument = 30 ; instrument < 31 ; instrument++)
      {
        Serial.print(" Instrument: ");
        Serial.println(instrument, DEC);

        midiWriteData(0xC0, instrument, 0);    //Set instrument number. 0xC0 is a 1 data byte command

        //Play notes from F#-0 (30) to F#-5 (90):
        for (int note = 27 ; note < 87 ; note++)
        {
          Serial.print("N:");
          Serial.println(note, DEC);
          //Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
          midiNoteOn(0, note, 127);
          delay(50);

          //Turn off the note with a given off/release velocity
          midiNoteOff(0, note, 127);
          delay(50);
        }

        //delay 100ms between each instruments
        delay(100);
        }
    }

This class loops over sd card and plays all of the sounds. but I only want to have a function to play a single file. So I added this function

    void MusicPlayer::play(char * path)
    {

     unsigned char bytes;        // How many bytes in buffer left
     unsigned char n;

     SPI.setClockDivider(SPI_CLOCK_DIV2);
     if(file.open(&root,path,O_READ))
       {
      Serial.print("Playing ");
      //Serial.println(list[songIndex].name);
       }
     else
     {
      Serial.print("Could not open: ");
      //Serial.println(list[songIndex].name);
      //songIndex ++;
      return;
      //while(1);
     }

     playingState = PS_PLAY;
     while(bytes = file.read(fileBuf,sizeof(fileBuf)))
     {
            // actual audio data gets sent to VS10xx.
            VS1053.writeData(fileBuf,bytes);

      switch (playingState)
      {
       case PS_PLAY:
        switch(ctrlState)
        {
         case CS_UP:
          Vol += 10;
          if (Vol > MaxVol)Vol = MaxVol;
          VS1053.writeRegister(SPI_VOL, Vol*0x101);     //Set volume level
          ctrlState = CS_EMPTY;
          break;
         case CS_DOWN:
          Vol -= 10;
          if (Vol < 0)Vol = 0;
          VS1053.writeRegister(SPI_VOL,Vol*0x101);      //Set volume level
          ctrlState = CS_EMPTY;
          break;
         case CS_NEXT:
          //if (++songIndex > MaxSong)songIndex = 0;
          //file.close();
          //VS1053.softReset();
          ctrlState = CS_EMPTY;
          return;
         case CS_PREV:
          //if (--songIndex < 0)songIndex = MaxSong;
          //file.close();
          //VS1053.softReset();
          ctrlState = CS_EMPTY;
          return;
         default:
          break;
        }
        break;
       case PS_PAUSE:
        while(playingState == PS_PAUSE);         //Pause
        break;
       case PS_RECORDING:
        file.close();
        VS1053.softReset();
           return;
      }

     }
     file.close();
     VS1053.softReset();
     Serial.println("[done!]");
     //songIndex++;

    }

if I compile the above class with this addition function it will compile but I have no idea if I upload it on arduino it harms the device or not, Does this code works or no?
thanks

title: Play a single sound using music shield

Answers: 0


body:
Let's say I have an arduino Uno connected to a W5100 ethernet shield. The arduino communicates with the ethernet shield using the tx0 and rx0 pins. When I upload a new script to the arduino using USB, it uses the same tx0 and rx0. So that made me think.

What if I run a script on my arduino that fetches some data from a webpage using HTTP requests but someone manages to hack into my server. Is it possible for the hacker to upload some kind of code to my server, which will erase (when fetched by the arduino) the old script and upload a new arduino script, by making the arduino think it's uploading a new script while it's getting data from the ethernet shield (or other communication shields?)

EDIT: Let's expand the question a bit.. How can I add security to my code to prevent this situation from happening?

title: Is the arduino hackable when using communication shields?

Answers: 2

body:
You should be pretty safe, at least as long as your code handles the
incoming data properly.

When you upload a new sketch through USB, the USB-to-serial interface
uses the Arduino pins TX0, RX0 **and RESET**. Your Ethernet shield, on
the other hand, does not control the RESET pin. Pulling the RESET pin
LOW is needed to make the processor enter the bootloader, which in turn
is needed in order to upload a new program. For pulling this pin low,
the malicious code would need not only to break into the Ethernet
shield's firmware, it would also need a **hardware hack** to access the
pin.

Now, if your own code is not safe, it is conceivable that the malicious
payload tricks your program into jumping to the bootloader or, as
suggesting by Juraj, into triggering a watchdog reset (which ends up
being equivalent). Thus you should treat _anything_ coming from the
network as potentially malicious.

body:
No it's not possible. Assuming you mean [this shield](https://www.arduino.cc/en/Main/ArduinoEthernetShieldV1) (and if you don't, please clarify):

> Arduino communicates with both the W5100 and SD card using the SPI bus (through the ICSP header). This is on digital pins 10, 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega.

Further on it mentions:

> The shield contains a number of informational LEDs:
>
>    ...
>
>    RX: flashes when the shield receives data
>
>    TX: flashes when the shield sends data

That's Rx and Tx on the shield, not the Arduino. Since it does not connect to the Tx/Rx on the Arduino, and since it cannot reset the Arduino, it therefore cannot reprogram it.

If you are worried, disable the BOOTRST fuse on the Arduino so that the bootloader is not active after a reset.

If you are *really* worried, disable the SPIEN fuse so that you cannot even reprogram it using SPI. Of course, then you won't be able to reprogram it either.

Personally I would be more worried that a cockatoo would come and peck at the shield.


body:
I have simple example, where in loop is called webServer to handle clients and also text drawing on display.
The thing is that webServer is not responding, but when I remove second part of loop - drawing text to display then web server starts to work normally.

Server does not respond:
<!-- language-all: lang-cpp -->

     void loop() {
          server.handleClient();
          unsigned long timeNow = millis();
          if ((timeNow > screenChangeTime))  {
              display.clear();
              display.setFont(ArialMT_Plain_16);
              display.setTextAlignment(TEXT_ALIGN_CENTER);
               display.drawString(12, 20,"Loaded: "+String(particles));
               screenChangeTime= timeNow + delay;
               display.display();
          }
        }

Server responds:

    void loop() {
          server.handleClient();
    }

title: ESP8266 - Webserver not working in loop

Answers: 1

body:
My guess is, that you're wasting too much time within the drawing-part.

What is the value for `delay`? I guess you have a number too low chosen here. And you should really set this new time **after** you have updated the display by `display.display();`.

Your webserver doesn't respond because he's not called often enough inside this code.


body:
I have two simple NRF24l01+ (with range of 200m) and two NRF24l01+ with range of 1km.and two socket adapter.

[![what I have][1]][1] or [what I have][2]

and I have two good library with names **RF24** and **RF24-master** . problem is that I tried a lot of combinations and just one of them worked : two simple NRF24l01+ with their socket adapter and with **Getting started** example of **RF24-master** library and only when I touch the antenna of the NRF it can transmit the package and get response. whats the problem? thats with me or my modules have problem?
I've also readed the datasheet and wrote my own code for modules.but it just worked with 1km range NRF24l01+ and most of the packages have failed.

my own code for transmitter :

    #include <SPI.h>

    #define cePin 7
    #define csnPin 8

    //#define cePin D0
    //#define csnPin D1

    int data = 7;

    void IRQ() {
      Serial.println("STATUS register from IRQ ISR :  ");
      digitalWrite(csnPin, 0);
      SPI.transfer(0x07);
      delay(10);
      Serial.println(SPI.transfer(0xff), BIN);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x08);
      delay(10);
      Serial.println(SPI.transfer(0xff), BIN);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x07 + 0x20);
      delay(10);
      SPI.transfer(0xff);
      delay(10);
      digitalWrite(csnPin, 1);
    }

    void NRF_transmitterBegin() {

      //reading
      /*digitalWrite(csnPin, 0);
        SPI.transfer(0x00);
        delay(10);
        Serial.println(SPI.transfer(0xff), BIN);
        delay(10);
        digitalWrite(csnPin, 1);*/

      pinMode(cePin, OUTPUT);  //CE
      pinMode(csnPin, OUTPUT);  //CSN
      delay(100);
      digitalWrite(csnPin, 1);
      digitalWrite(cePin, 0);

      SPI.setBitOrder(MSBFIRST);
      SPI.setDataMode(SPI_MODE0);
      SPI.setClockDivider(SPI_CLOCK_DIV4);
      SPI.begin();
      delay(1000);

      digitalWrite(csnPin, 0);   //flush TX_FIFO
      SPI.transfer(0xe1);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);   //flush RX_FIFO
      SPI.transfer(0xe2);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x07 + 0x20);
      delay(10);
      SPI.transfer(0xf0);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x00 + 0x20);
      delay(10);
      SPI.transfer(0x0e);
      delay(10);
      digitalWrite(csnPin, 1);
      delay(10);

      /*digitalWrite(csnPin, 0);
        SPI.transfer(0x11 + 0x20);
        delay(10);
        SPI.transfer(0x3f);
        delay(10);
        digitalWrite(csnPin, 1);*/

      //Down for DYNPL
      digitalWrite(csnPin, 0);
      SPI.transfer(0x1c + 0x20);
      delay(10);
      SPI.transfer(0x01);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x1d + 0x20);
      delay(10);
      SPI.transfer(0x04);
      delay(10);
      digitalWrite(csnPin, 1);
      //Up for DYNPL

      digitalWrite(csnPin, 0);
      SPI.transfer(0x01 + 0x20);
      delay(10);
      SPI.transfer(0x3f);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x02 + 0x20);
      delay(10);
      SPI.transfer(0x03);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x03 + 0x20);
      delay(10);
      SPI.transfer(0x03);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x04 + 0x20);
      delay(10);
      SPI.transfer(0xff);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x05 + 0x20);
      delay(10);
      SPI.transfer(0x4c);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x06 + 0x20);
      delay(10);
      SPI.transfer(0x06);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x0a + 0x20);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x10 + 0x20);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      digitalWrite(csnPin, 1);

      attachInterrupt(digitalPinToInterrupt(2), IRQ, FALLING);
      delay(10);

    }

    void NRF_transmit(int whatIsData , float data , float hum) {    //hum is used just for temp&humidity
      /*
         byte 0 says what is our data:  1 -> data and humidity    2 -> movement   3 -> gas

         1(float) :   byte 1 -> integer part of temp  byte 2 -> fractional part of temp   byte 3 -> integer part of humidity    byte 4 -> fractional part of humidity    byte 5 -> �ttery
         2(binary) :  byte 1 -> �ttery
         3(float) :   byte 1 -> integer part of gas   byte 2 -> fractional part of gas    byte 3 -> �ttery

         �ttery feature is in progress ...
      */

      int byte0 = 0 , byte1 = 0 , byte2 = 0 , byte3 = 0 , byte4 = 0 , byte5 = 0;
      float buf = 0;

      byte0 = whatIsData;

      switch (whatIsData) {
        case 1: {

            byte1 = data;
            buf = data - byte1;
            byte2 = buf * 10;

            byte3 = hum;
            buf = hum - byte3;
            byte4 = buf * 10;

            break;
          }
        case 2: {

            break;
          }
        case 3: {

            byte1 = data;
            buf = data - byte1;
            byte2 = buf * 10;

            break;
          }
        default: {
            break;
          }
      }

      digitalWrite(csnPin, 0);
      SPI.transfer(0xe1);   //flush TX_FIFO empty
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0xa0);   //write on TX_FIFO
      delay(10);
      SPI.transfer(byte0);
      delay(10);
      SPI.transfer(byte1);
      delay(10);
      SPI.transfer(byte2);
      delay(10);
      SPI.transfer(byte3);
      delay(10);
      SPI.transfer(byte4);
      delay(10);
      SPI.transfer(byte5);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(cePin, 1);   //CE High
      delay(1);
      digitalWrite(cePin, 0);   //CE Low

    }

    void NRF_monitorRegisters() {

      for (int i = 0; i < 30; i++) {
        digitalWrite(csnPin, 0);
        SPI.transfer(i);
        delay(10);
        Serial.print(i , HEX);
        Serial.print(" -> ");
        Serial.println(SPI.transfer(0xff), BIN);
        delay(10);
        digitalWrite(csnPin, 1);
      }
      Serial.println("");

    }

    void setup() {

      Serial.begin(115200);

      NRF_transmitterBegin();
      NRF_monitorRegisters();

    }

    void loop() {

      NRF_transmit(3 , 15.1 , 0);

      delay(1000);
    }

and my code for receiver :

    #include <SPI.h>

    #define cePin 7
    #define csnPin 8

    //#define cePin D0
    //#define csnPin D1

    long int lastTime = 0;

    void IRQ() {

      int whatIsData = 0;
      int byte1 = 0 , byte2 = 0 , byte3 = 0 , byte4 = 0 , byte5 = 0;
      float data = 0 , hum = 0 , buf = 0;

      /*Serial.println("STATUS register from IRQ ISR :  ");
        digitalWrite(csnPin, 0);
        SPI.transfer(0x07);
        delay(10);
        Serial.println(SPI.transfer(0xff), BIN);
        delay(10);
        digitalWrite(csnPin, 1);*/

      digitalWrite(csnPin, 0);
      SPI.transfer(0x61);
      delay(10);
      whatIsData = SPI.transfer(0xff);
      delay(10);
      byte1 = SPI.transfer(0xff);
      delay(10);
      byte2 = SPI.transfer(0xff);
      delay(10);
      byte3 = SPI.transfer(0xff);
      delay(10);
      byte4 = SPI.transfer(0xff);
      delay(10);
      byte5 = SPI.transfer(0xff);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);   //flush RX_FIFO
      SPI.transfer(0xe2);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x07 + 0x20);
      delay(10);
      SPI.transfer(0xf0);
      delay(10);
      digitalWrite(csnPin, 1);
      delay(10);

      switch (whatIsData) {
        case 1: {

            buf = byte2;
            data = byte1 + buf / 10;
            buf = byte4;
            hum = byte3 + buf / 10;

            Serial.print("Received data from DHT22 -> temp:");
            Serial.print(data);
            Serial.print("  humidity:");
            Serial.println(hum);

            break;
          }
        case 2: {

            Serial.println("Received data from PIR -> Move detected");

            break;
          }
        case 3: {

            buf = byte2;
            data = byte1 + buf / 10;

            Serial.print("Received data from gas sensor -> %gas:");
            Serial.println(data);

            break;
          }
        default: {

            Serial.println("a problem accured");

            break;
          }
      }

    }

    void NRF_receiverBegin() {

      //reading
      /*digitalWrite(csnPin, 0);
        SPI.transfer(0x00);
        delay(10);
        Serial.println(SPI.transfer(0xff), BIN);
        delay(10);
        digitalWrite(csnPin, 1);*/

      pinMode(cePin, OUTPUT);  //CE
      pinMode(csnPin, OUTPUT);  //CSN
      delay(100);
      digitalWrite(csnPin, 1);
      digitalWrite(cePin, 0);

      SPI.setBitOrder(MSBFIRST);
      SPI.setDataMode(SPI_MODE0);
      SPI.setClockDivider(SPI_CLOCK_DIV4);
      SPI.begin();
      delay(100);

      digitalWrite(csnPin, 0);   //flush TX_FIFO
      SPI.transfer(0xe1);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);   //flush RX_FIFO
      SPI.transfer(0xe2);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x07 + 0x20);
      delay(10);
      SPI.transfer(0xf0);
      delay(10);
      digitalWrite(csnPin, 1);
      delay(10);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x00 + 0x20);
      delay(10);
      SPI.transfer(0x0f);
      delay(10);
      digitalWrite(csnPin, 1);
      delay(10);

      /*digitalWrite(csnPin, 0);
        SPI.transfer(0x11 + 0x20);
        delay(10);
        SPI.transfer(0x01);
        delay(10);
        digitalWrite(csnPin, 1);*/

      //Down for DYNPL
      digitalWrite(csnPin, 0);
      SPI.transfer(0x1c + 0x20);
      delay(10);
      SPI.transfer(0x01);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x1d + 0x20);
      delay(10);
      SPI.transfer(0x04);
      delay(10);
      digitalWrite(csnPin, 1);
      //Up for DYNPL

      digitalWrite(csnPin, 0);
      SPI.transfer(0x01 + 0x20);
      delay(10);
      SPI.transfer(0x3f);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x02 + 0x20);
      delay(10);
      SPI.transfer(0x03);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x03 + 0x20);
      delay(10);
      SPI.transfer(0x03);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x04 + 0x20);
      delay(10);
      SPI.transfer(0xff);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x05 + 0x20);
      delay(10);
      SPI.transfer(0x4c);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x06 + 0x20);
      delay(10);
      SPI.transfer(0x06);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x0a + 0x20);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      digitalWrite(csnPin, 1);

      digitalWrite(csnPin, 0);
      SPI.transfer(0x10 + 0x20);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      SPI.transfer(0xaa);
      delay(10);
      digitalWrite(csnPin, 1);

    }

    void NRF_startListening() {

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

      digitalWrite(cePin, 1);   //CE High
      Serial.println("Listening started");

    }

    void NRF_monitorRegisters() {

      for (int i = 0; i < 30; i++) {
        digitalWrite(csnPin, 0);
        SPI.transfer(i);
        delay(10);
        Serial.print(i , HEX);
        Serial.print(" -> ");
        Serial.println(SPI.transfer(0xff), BIN);
        delay(10);
        digitalWrite(csnPin, 1);
      }
      Serial.println("");

    }

    void setup() {

      Serial.begin(115200);

      NRF_receiverBegin();
      NRF_startListening();
      NRF_monitorRegisters();

    }

    void loop() {

      /*if (millis() - lastTime > 20000) {
        NRF_monitorRegisters();
        lastTime = millis();
      }*/

    }

  [1]: https://i.stack.imgur.com/XX5h2.jpg
  [2]: http://uupload.ir/files/b1w0_nrf.jpg

title: NRF24l01+ works only when touching its antenna

Answers: 0


body:
ok, I feel like this should be simple, but I am at a loss

Simple code mock up to send 4 bytes(mimicking a float)  over I2C from Arduino to rpi. I am trying to create a state machine so that I can request certain "registers" containing 4 bytes each. I send a byte from pi to arduino indicating what "register" I want, then read back 4 bytes.  I was attemping to reset the state back to NO_STATE after the end of the switch statement, but it effects the bytes received by the pi, and I dont see how.

    #include <Wire.h>
    #define SLAVE_ADDRESS 0x04

    //States
    #define NO_STATE 0x00
    #define GET_BAT_TEMP 0x03

    byte state = NO_STATE;
    void setup() {
      Serial.begin(9600);
      pinMode(13, OUTPUT);
      Wire.begin(SLAVE_ADDRESS);
      Wire.onReceive(receiveData);
      Wire.onRequest(sendData);
    }

    void loop() {
      delay(100);
    }

    // callback for received data
    void receiveData(int byteCount){

      while(Wire.available()) {
        state = Wire.read();
      }
      Serial.print("Got:");
      Serial.println(state);
    }

    // callback for sending data
    void sendData(){
      Serial.println("Sending...");
      byte b[4]={1,1,1,1};

      switch (state){
        case NO_STATE:
          //bad state   not sure if can return only byte, may need to return 4 zeros or somthing
          Wire.write(0);
          Wire.write(0);
          Wire.write(0);
          Wire.write(0);
          break;
        case GET_BAT_TEMP:
          //send battery temp
          Wire.write(3);
          Wire.write(3);
          Wire.write(3);
          Wire.write(3);
          break;
        default:
          Wire.write(9);
          Wire.write(9);
          Wire.write(9);
          Wire.write(9);
          //send back error code
      }
      //reset state to none
      state=NO_STATE;

    }

with this code I receive [3,0,0,0]

if I comment out the line

    //state=NO_STATE;

I then receive back [3,3,3,3]

which is what I would expect. But I do not see how reseting the state "after" all the bytes are sent would cause an issue

output from arduino shows entering that function only once, and sending the 4 bytes

    Got:3
    Sending...
    Sending...
    Sending...
    Sending...

title: Arduino --> RPI I2C issue

Answers: 1

body:
I'm not an expert, but I think I found why it is not working.

The main problem is that you are using always the same byte (0, 3 or 9) for debugging, so you are not noticing that it is not sending four bytes, but only one, and the function gets called four times. This is obvious however from the reply on the serial interface (+1 for adding it in the question, good work).

What you can do is to track how many bytes you sent, and send the successive one. After the bytes are all sent you can reset back the state. The code can be something like

    //States
    #define NO_STATE 0x00
    #define GET_BAT_TEMP 0x03

    byte sentData;
    byte batteryLevel[4]={3,4,5,6};

    byte state = NO_STATE;
    void setup() {
     Serial.begin(9600);
     pinMode(13, OUTPUT);
     Wire.begin(SLAVE_ADDRESS);
     Wire.onReceive(receiveData);
     Wire.onRequest(sendData);
    }

    void loop() {
      // delay(100); // Useless, let it cycle at its max speed
    }

    // callback for received data
    void receiveData(int byteCount){
     while(Wire.available()) {
      state = Wire.read();
      sentData = 0;
     }
     Serial.print("Got:");
     Serial.println(state);
    }

    // callback for sending data
    void sendData(){
     Serial.println("Sending...");

     switch (state){
      case NO_STATE:
       //bad state   not sure if can return only byte, may need to return 4 zeros or somthing
       Wire.write(0);
       break;
      case GET_BAT_TEMP:
       //send battery temp
       Wire.write(batteryLevel[sentData]);
       if (sentData < 3)
        sentData++;
       else
        //reset state to none
        state=NO_STATE;
       break;
      default:
       Wire.write(9);
       //send back error code
     }
    }

I haven't tested it, so forgive any bugs. But I'm sure  you understood the main point.

Just some remarks: the delay is useless (you are not saving energy or other with it, so just remove it); the serial is ok for debugging, but I think you should remove it from the code you will use (not ok to stop the interrupts for such a long time).

And most important: I hope you considered the 5V vs 3.3V voltage problem on the I2C ;)

In any case, I second Look Alterno: good way to ask a question, with all the information needed.

EDIT: as pointed out in the comments, there exist a function to send all the data together. I'm not sure how it behaves in different conditions (e.g. when less bytes are requested), but if you trust the communication the function can be simplified in

    // callback for sending data
    void sendData(){
     Serial.println("Sending...");

     switch (state){
      case NO_STATE:
       //bad state   not sure if can return only byte, may need to return 4 zeros or somthing
       Wire.write(0);
       break;
      case GET_BAT_TEMP:
       //send battery temp
       Wire.write(batteryLevel, 4);
       state=NO_STATE;
       break;
      default:
       Wire.write(9);
       //send back error code
     }
    }

(and the `sentData` variable becomes useless)


body:
I am want to receive a 5 character hexadecimal input from user over serial port of arduino Uno.

    int count = 0;                                    // count = 0
    char userInput[5];

    void setup()
    {
      delay(1000);
      Serial.begin(19200);                            // begin serial port with baud rate 9600bps

    }
    void loop()
    {
      if (Serial.available() > 5)
      {
        Serial.read();
      }

      else if (Serial.available() < 4)
      {
        Serial.read();
      }

      else if (Serial.available() == 5)
      {
        for (int i = 0; i < 5; i++)
        {
          userInput[i] = Serial.read();
        }

        Serial.print("User Input - ");
        Serial.println(userInput);
      }

      delayMicroseconds(10000);
    }

But I want to discard the input if user inters less than 5 characters or more than 5?

Since the Serial.flush() have a different meaning now, I can not clear the buffer if user enters less than or more than 5 characters and the characters gets added to next input.

e.g. If I upload above program and entered input in following sequence:

    abcde
    abcd
    abcd
    abcd
    abcd
    abcdef
    abcde

I got the following output:

    User Input - abcde
    User Input - dabcd
    User Input - dacbd
    User Input - bcdef
    User Input - abcde

Two invisible characters appear in output which are not visible but when I copied the output from serial monitor but these characters appear when I copy paste the output into Text Editor.

So How can I modify the program to receive only 5 hex character input from user (Which user will input from Hex Keypad)? And if user enters more or less character I want to clear the input buffer for next user input so that characters from previous input doesn't get added to next one.

title: How to Write a function or Loop or program to receive fixed number of Integers or characters over Serial?

Answers: 2

body:
As noted in the comments, since your prototype is receiving data from the serial port, you need some way for the user to indicate to the program that they are finished entry, since a 4-character entry is a necessary point along the way to a 5-character entry.

What you are doing now, by checking if `Serial.available()>5` is letting the serial buffer hold 6 characters before you read from it (note: 5 is not >5), but then your `else` statement:

    else if (Serial.available() < 4)
    {
      Serial.read();
    }

Clears out the buffer (`Serial.read()` removes one character from the buffer), so you will never get to 5 characters anyway, unless all 6 characters come in between runs of `loop()`, which is not likely at 19200 baud.

Not to mention that while data is sitting in the buffer, you don't know what it is and can't act on it. It is better to use the buffer as intended, which is to allow the Arduino to collect serial data, even while your program is working on other things, and then grab any pending data from the buffer as the program `loop()`s.

You have declared the `userInput[5]` array to hold user input, but note that if you only declare it at 5 `char`s long, it cannot hold the null-character terminator that is standard for C-style strings. It would be better to declare this as:

    char userInput[6];  // Holds 5 user characters, plus null terminator.

In your `loop()`, you should copy out the contents of the buffer into your `userInput`, check the length or for a termination character, such as a carriage return or newline (i.e., pressing 'Enter' on the serial terminal.) and act accordingly. Here is an example, showing just the relevant bits for the user input and hiding the rest in [...]:

    char userInput[6];  // Holds 5 user characters, plus null terminator.

    void setup() {
      userInput[0] = '\0';  // Initialize string to empty
      Serial.begin(9600);
    }

    void loop() {
      uint8_t processInput = 0;   // Set to 1 if we have complete entry
      while (Serial.available()>0) {
        char input = Serial.read();
        if (input=='\r' || input=='\n') {
          // Have received a terminating character,
          // Flush the rest of the buffer
          while (Serial.available()) {
            Serial.read();
          }

          processInput = 1;

        } else {
          int s_len = strnlen(userInput, 5); // Get current length of userInput
          if (s_len<5) {
            userInput[s_len++] = input;      // Append character
            userInput[s_len] = '\0';         // Null-terminate string
          } else {
            // User has entered more than 5 characters and no terminating
            // character; here is where you can decide to clear the userInput
            // and start over, or just drop the first character and care
            // about the most recent 5, etc. Here, we will clear the input
            // and start over; The 6th character is dropped/ignored and
            // user input starts again. It is as though the 6th character
            // entered is like pressing Enter, but it does not process
            // the incoming data, beacuse 6 characters is an invalid input.
            userInput[0] = '\0';
            s_len = 0;
            processInput = 0;
            // Invalid input
            Serial.println("Error: invalid data");
          }
        }
      }

      if (processInput) {
        Serial.print("User input - ");
        Serial.println(userInput);

        if (strnlen(userInput, 5)==5) {
          // Do something **here** with the input string!!

          // Reset input string
          userInput[0] = '\0';
        } else {
          // Invalid input
          userInput[0] = '\0';
          Serial.println("Error: invalid data");
        }
        processInput = 0;
      }
    }

Note, this code is not fully tested and may contain bugs. In particular, I did not intensely check if the `while (Serial.available()) {}` properly handles a lot of extra data.

One final note, you don't need the `delay()` with this code.

**EDIT:**

I tried the sample code above and it had a couple of bugs, one of which was that after a successful 5-digit entry, the input string was not reset to empty. I have now updated the code and it's a valid, working program to receive and process a 5-character input on the serial port and to toss an error if fewer than 5 or more than 5 characters are entered. Entry is terminated with a carriage return or newline (enter key).

body:
I wrote following program, it receives 5 character input from user and if user enters input more than 5 characters then program store only 1st 5 characters and if user inputs less than 5 characters long the it rejects than input altogether..

    char userInput[5];
    void setup()
    {
    //delay(1000);
    Serial.begin(9600); // begin serial port with baud rate 9600bps
    }

    void loop()
    {
    if (Serial.available() < 5)
    {
       Serial.read();
    }
    else if (Serial.available() >= 5)
    {
          for (int i = 0; i < 5; i++)
          {
            userInput[i] = Serial.read();
          }
         while (Serial.available() > 0)
         {
           Serial.read();
         }
    Serial.print("User Input - ");
    Serial.println(userInput);
    }
    delay(100);
    }


body:
The Adafruit Motor Shield is connected to 2 steppers which are wired correctly and work when I just use the onestep function. I understand that I cannot drive both at once, so I am using a while loop with two if statements. The Motors were wired:

The left motor was wired:

Green -> m3+

White -> m3-

Red -> m4+

Blue -> m4-

The right motor was wired:

Red -> M2+

Blue -> M2-

Green -> M1+

Black -> M1-

Here is the code:

    #include <Wire.h>
    #include <Adafruit_MotorShield.h>
    #include "utility/Adafruit_MS_PWMServoDriver.h"

    Adafruit_MotorShield AFMS = Adafruit_MotorShield();
    Adafruit_StepperMotor *leftMotor = AFMS.getStepper(200, 2);
    Adafruit_StepperMotor *rightMotor = AFMS.getStepper(200, 1);
    //79 steps per half inch
    //half inch is a coordinate
    //declaring global variables for Hypotenuses (cord lengths)
    int leftHyp;
    int rightHyp;
    int prevX = 0;
    int prevY = 0;
    //space from shaft to shaft is 30"
    //calculating function
    void CordCalc(int xCord, int yCord)
    {
     Serial.begin(9600);
      //cords start at 0,0
     xCord = xCord - prevX;
     yCord = yCord - prevY;
     int xSquared = sq(xCord);
     int ySquared = sq(yCord);
     int addSquares = xSquared + ySquared;
     int leftHyp = sqrt(addSquares);
      //now for the right
     int rightX = 60 - xCord;
     int rightXsq = sq(rightX);
     int rightSquares = rightXsq + ySquared;
     int rightHyp = sqrt(rightSquares);
      //leftMotor->step(leftHyp * 79, FORWARD, MICROSTEP);
      //rightMotor->step(rightHyp * 79, FORWARD, MICROSTEP);
     int lStepsTaken = 0;
     int rStepsTaken = 0;
     leftHyp = leftHyp * 79;
     rightHyp = rightHyp * 79;
     bool stepsComplete = false;

      //This is the section for moving the Motors
     while(stepsComplete == false) {
      if(lStepsTaken <= leftHyp) {
       leftMotor->onestep(FORWARD,DOUBLE);
       lStepsTaken++;
       Serial.print("Left");
      }

      if(rStepsTaken < rightHyp) {
       rightMotor->onestep(FORWARD,DOUBLE);
       rStepsTaken++;
       Serial.print("Right!");
      }

      if(rStepsTaken >= leftHyp && lStepsTaken >= leftHyp) {
       stepsComplete = true;
      }
     }

     int prevY = yCord;
     int prevX = xCord;
     stepsComplete = false;
    }

    void setup()
    {
    // direction from project point of view
     int leftLength = 0;
     int rightLength = 0;
     leftMotor->setSpeed(122);
     rightMotor->setSpeed(122);
     Serial.begin(9600);

     CordCalc(15, 15);
    }

    void loop()
    {
    }

Loop is empty on purpose because only need to move to coordinates once.

title: Adafruit Motor Shield steppers not turning

Answers: 1

body: The missing line was afms.begin(); which starts communication with the adafruit motor shield.


body: Have been using UNO MEGA for small projects. Recently bought an UNO for other projects. Can I just go into the IDE an under Tools select UNO and a different port to do projects and rename sketches to keep track of sketches. Do not wish to use boards at the same time.

title: Two Arduino boards - one IDE

Answers: 1

body:
That's the way to do it.

You need to select the type of board first:

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

And then the port. You can have both devices connected at the time and select which one you want to program.

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

With Arduino you can do OTA (Over The Air uploads) to NodeMCU and other ESP8266 based systems.

If you want to run two instances of the IDE, to work with two different boards at the same time, use [UECIDE][3].

  [1]: https://i.stack.imgur.com/AgnSX.png
  [2]: https://i.stack.imgur.com/6ClKZ.png
  [3]: http://uecide.org


body:
I reinstalled a previously working sketch to my UNO and now the behaviour of the lcd has changed.

Previously this example worked perfectly:

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

    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

    void setup()
    {
      lcd.init();                      // initialize the lcd

      // Print a message to the LCD.
      lcd.backlight();
      lcd.print("Hello, world!");
    }

    void loop()
    {
    }

Now it only displays the very first character 'H'

This version does work though:

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

    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

    void setup()
    {
      lcd.init();                      // initialize the lcd

      // Print a message to the LCD.
      lcd.backlight();
      lcd.print("H");
      lcd.print("e");
      lcd.print("l");
      lcd.print("l");
      lcd.print("o");
      lcd.print(" ");
      lcd.print("W");
      lcd.print("o");
      lcd.print("r");
      lcd.print("l");
      lcd.print("d");
    }

    void loop()
    {
    }

Can anyone shed me any light what is the reason of this change in behaviour and how to solve it?

Running version 1.8.3 on a W7pro PC

title: changed behaviour in I2C LCD

Answers: 1

body:
There seems to be an incompatibility between recent versions of the IDE and the library I was using.

Installing the latest version of the library from GitHub and replacing the `lcd.init()` command with `lcd.begin()` in my sketches solved the problem.


body:
I recently bought a GPRS shield from Seeed Studio but was having issues running the programs described in their documentation.  Here is everything you need to know about my shield:

[Documentation for GPRS Shield V2.0][1]

[Website to purchase GPRS Shield V2.0][2]

I assumed that there was a connection problem. I used the following code to try to debug my SIM900 and its connections to the sim card and the cellular network:

    #include <SoftwareSerial.h>
    SoftwareSerial gprsSerial(7,8);

    void setup(){
      gprsSerial.begin(19200); // GPRS shield baud rate
      Serial.begin(19200);
      delay(500);
    }

    void loop(){
      if(Serial.available()) {
        switch(Serial.read()) {
          case '0': testSIM900(); break;
            // AT OK
          case '1': testSIMCARD(); break;
            // +CPIN: READY
            // +CREG: 0,1
          case '2': testNETWORK(); break;
            // +CGATT: 1
        }
      }

      if(gprsSerial.available()) Serial.write(gprsSerial.read());
    }

    void testSIM900() {
      gprsSerial.println("AT");
      // AT OK
      delay(100);

    }

    void testSIMCARD() {
      gprsSerial.println("AT+CPIN?");
      // +CPIN: READY
      delay(100);
      gprsSerial.println("AT+CREG?");
      // +CREG: 0,1
      delay(100);
    }

    void testNETWORK() {
      gprsSerial.println("AT+CGATT?");
      // +CGATT: 1
      delay(100);
    }

When I entered 0, 1, and 2 into the serial monitor, I got the following response:

    AT

    OK
    AT+CPIN?

    +CPIN: READY

    OK
    AT+CREG?

    +CREG: 1,2

    OK

    +CREG: 0

    +CGREG: 0
    AT+CGATT?

    +CGATT: 0

    OK

What does this tell me about the current state of my shield, sim card, and network connection? Is there anything else I can do to isolate issues?

 [1]:https://seeeddoc.github.io/GPRS_Shield_V2.0/
 [2]:https://www.seeedstudio.com/GPRS-Shield-V2.0-p-1379.html

title: Connection Problems with GPRS Shield

Answers: 1

body:
It seems it can't register on the network, GSM modems are power hungry, are you sure you're powering it up with the external power source (through Vin)? Pretty sure the Arduino isn't enough, but I could be wrong, that's a shield that has those issues in mind.

Also try to see the signal strength using AT+CSQ.