body:
I have designed a thermistor-based respiratory monitor which detects changes in temperature during respiration, but I am having problems with the coding part. Can someone help, my code given below is not working.

    void setup() {
      Serial.begin(9600);
    }
    unsigned long timer;
    void loop(void)
    {
        delay (500)
      int sensorValue = analogRead(A0);
    timer=millis ();
        if ( sensorValue<200) {
    unsigned long currentTime = millis();
    float period_respiration = currentTime-timer;
    float breathrate= 60000/period_respiration;
    Serial.println("Respirations per minute:");
    Serial.println(breathrate);
      }
    }

The sensor value is 600-800 during inspiration, and about 100 during expiration.

title: Arduino code for thermistor respiratory monitor

Answers: 3

body:
This code is missing 2 critical components.  First, with out some form of [hysteresis][1] it is unlikely the program will respond in a dependable manner. Second, it would be best if a [finite state machine][2] were utilized to assist in the collection of data and calculation of a reparation rate.  In this case, 4 states to track exhale, transition from exhale to inhale, inhale & transition from inhale to exhale.

  [1]: https://en.wikipedia.org/wiki/Hysteresis
  [2]: https://en.wikipedia.org/wiki/Finite-state_machine

body:
The *primary* reason your code doesn't work is very simple: every time you go around the loop you set

    timer = millis();

and if the reading is greater than 200 you set

    currentTime = millis();

but ***those two statements are executed just a few microseconds apart***, so the difference between them (in milliseconds) will almost always be zero (it might occasionally be one if you happened to cross a tick boundary, but it will never be more than that).

There are a few other problems with the logic of your code, which I think you'll understand when you look at some code that *will* work. Try something like this:

    enum respState {
     Inhaling,
     Exhaling
    };
    unsigned long prevRespTime = 0;
    unsigned long currRespTime = 0;
    respState currentRespState;
    int movingAvgRespRate = 0;

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

    void loop()
    {
     //delay(500);
     // don't need to delay because we'll only fire once per inhalation and once per exhalation
     int sensorValue = analogRead(A0);

     if ((sensorValue > 300) && (currentRespState == Exhaling))
     {
      currentRespState = Inhaling;
      prevRespTime = currRespTime;  // save time from last cycle
      currRespTime = millis();

      float period_respiration = currRespTime - prevRespTime;
      float breathrate = 60000 / period_respiration;
      Serial.print("Inhaling /tRespirations per minute: ");
      Serial.println(breathrate);
     }
     else if ((currentRespState == Inhaling) && (sensorValue < 200))
     {
      currentRespState = Exhaling;
      Serial.println("Exhaling");
     }
    }

The above code will give you the instantaneous respiratory rate, which probably will jump around a bit more than you would like. You probably want to add some dependency on prior history (hysteresis) to smooth it out a bit. One easy way is to put this through a low-pass filter algorithm to get a moving average value for the respiratory rate. That way the rate goes up when you breathe faster and down when you breathe slower but it doesn't instantaneously jump around on every breath.  Here's what that might look like:

    // Global variables
    enum respState {
     Inhaling,
     Exhaling
    };
    unsigned long prevRespTime = 0;
    unsigned long currRespTime = 0;
    respState currentRespState = Exhaling;
    float breathrate = 0;
    int movingAvgRespRate = 0;

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

    void loop()
    {
     //delay(500);
     // don't need to delay because we'll only fire once per inhalation and once per exhalation
     int sensorValue = analogRead(A0);

     if ((sensorValue > 300) && (currentRespState == Exhaling))
     {
      currentRespState = Inhaling;
      prevRespTime = currRespTime;  // save time from last cycle
      currRespTime = millis();

      float period_respiration = currRespTime - prevRespTime;

      if (period_respiration == 0)
       breathrate = 0;
      else
       breathrate = 60000 / period_respiration;

      Serial.print("Inhaling /tResp Rate: ");
      Serial.print(breathrate);

      if (movingAvgRespRate == 0)
       movingAvgRespRate = breathrate;
      else
       movingAvgRespRate = (int) ((0.2 * breathrate) + (0.8 * movingAvgRespRate));

      Serial.print("/tAvg Resp Rate: ");
      Serial.println(movingAvgRespRate);
     }
     else if ((currentRespState == Inhaling) && (sensorValue < 200))
     {
      currentRespState = Exhaling;
      Serial.println("Exhaling");
     }
    }

This code compiles, but I did not happen to be near an arduino with a sensor, so I didn't run it -- there could be issues, but this should be enough to put you on the right track. Good Luck!

body:
Aside from all the useful code provided, here is some additional input for a relatively accurate flow measurement using thermistors. Sage metering provides a [useful overview][1] of the most established modes of operation. You'd need an array of two or more thermistors; by heating the central element and measuring the temperature field displacement induced by the flow using the other thermistors you would get a really accurate reading. Google Scholar has a lot of papers on constant temperature and constant current flow meters.

Also, I suppose you are using some short of tubing where you inhale/exhale; there is a critical length for this tube, where you would want to place your sensors to measure a good, steady flow (this is called laminar flow). You can look up Reynolds number and laminar - turbulent flow in pipes; I can say from experience that after approx. 15cm you would measure well, but have a reading, this is really interesting information on setting up a proper measurement setup.

  [1]: https://sagemetering.com/knowledge-base/topics/thermal-mass-flow-meter/
  [2]: http://www-mdp.eng.cam.ac.uk/web/library/enginfo/aerothermal_dvd_only/aero/fprops/pipeflow/node8.html


body:
Ì am building speedometer with NEO-6M and have some problems with my code.
The scenario is that I send some data from our Arduino to another device via a TX pin with a delay of 50 ms. This delay of 50 ms needs to be maintained and should not exceed. The issue with GPS data, which arrives from the device, is that it is received every 1 second. This issue will cause the 50ms delay to be longer and exceed to 1050 ms. In my last code change delay is not maintained on 50 ms, it is all 1000 ms. Not sure what I did wrong.
My code is

# original

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

    #include <AD9850.h>
    #include <TinyGPS++.h>
    #include <SoftwareSerial.h>

    static const int RXPin = 0, TXPin = 1;
    static const uint32_t GPSBaud = 9600;

    const int W_CLK_PIN = 8;
    const int FQ_UD_PIN = 9;
    const int DATA_PIN = 10;
    const int RESET_PIN = 11;

    double freq = 1;
    double trimFreq = 124999500;

    int phase = 0;

    unsigned int speed = 0;

    TinyGPSPlus gps;
    SoftwareSerial ss(RXPin, TXPin);

    void setup()
    {
      Serial.begin(115200);
      ss.begin(GPSBaud);
      DDS.begin(W_CLK_PIN, FQ_UD_PIN, DATA_PIN, RESET_PIN);
      DDS.calibrate(trimFreq);
    }

    void loop()
    {
      // Dispatch incoming characters
      while (ss.available() > 0)
        gps.encode(ss.read());

      {
        digitalWrite(outPin, HIGH);   // sets the pin on
        delayMicroseconds(50);        // pauses for 50 microseconds
        digitalWrite(outPin, LOW);    // sets the pin off
        delayMicroseconds(50);        // pauses for 50 microseconds
      }

      if (gps.speed.isUpdated())
      {
        Serial.print(F("SPEED      Fix Age="));
        Serial.print(gps.speed.age());
        Serial.print(F("ms Raw="));
        Serial.print(gps.speed.value());
        Serial.print(F(" km/h="));
        Serial.println(gps.speed.kmph());
        speed = gps.speed.kmph();
        //calculate the frequency with map()
        freq = map(speed, 0, 100, 0, 160);
        DDS.setfreq(freq, phase);
      }
    }

# revised
(replying to https://arduino.stackexchange.com/a/45657)
Thank you for help. Is it possible to put GPS speed in this code? https://pastebin.com/LdT7UHBQ I used your code and it works but my boss demands that we modify his code and make it maintain delay with it.

    long prevTxTime = 0;
    const int delayTime = 51;

    void setup()
    {
      Serial1.begin(115200);
      Serial2.begin(115200);
    }

    void loop()
    {

      int b, chunk = 0;

      if (Serial2.available())
      {
        b = Serial2.read();
        chunk = b >> 6;
        if (chunk == syncc)
        {
          bytes[syncc] = b & 63;
          syncc++;
          if (syncc == 4)
          {
            syncc = 0;
            tach = bytes[0] + (bytes[1] << 6);
            velocityfreq = bytes[2] + (bytes[3] < delayTime)
            {
              //speed from gps would most likely need to be set here as "speedfromgps"

              SendData();
              prevTxTime = millis();
            }
          }

          void SendData()
          {
            sprintf(charToSend, "%d|%d|%d|%d|%d\n\r",
                    data1, data2, data3, data4, speedfromgps);

            Serial1.print(charToSend);
          }

title: Maintain delay with NEO-6M

Answers: 1

body:
*  What is `outPin`?

*  Don't start a `SoftwareSerial` object on the `Serial` port.  Just use `Serial`

*  The Serial Monitor window will have to use the GPS baud rate if the GPS is connected to pins 0 & 1.  This is a good choice, but you'll have to disconnect pin 0 to upload a new sketch over USB.

*  Don't use `delay`.  This prevents the sketch from reading GPS characters.  Eventually, the input buffer will overflow and characters will be lost.  Instead, save a timestamp and compare the current time with the timestamp.  When the difference is 50ms, simply toggle the pin and save another timestamp.

*  Try [NeoGPS](https://github.com/SlashDevin/NeoGPS).  It's smaller, faster, more reliable and more accurate than all other GPS libraries.  There are many tips on the Installation and Troubleshooting pages, and the examples are structured properly.  If you want to use pins other than 0 & 1, be sure the read the section about choosing a serial port.  `SoftwareSerial` is the worst choice.

Here is your sketch, modified to use `Serial` and `NeoGPS`:

    #include <AD9850.h>
    #include <NMEAGPS.h>
    NMEAGPS gps;

    #define gpsPort Serial  // GPS on pins 0 & 1
    static const uint32_t GPSBaud = 9600;

    const int OUT_PIN   = 4; ???
    const int W_CLK_PIN = 8;
    const int FQ_UD_PIN = 9;
    const int DATA_PIN  = 10;
    const int RESET_PIN = 11;

    const double trimFreq = 124999500.0;

    int phase = 0;

    unsigned long lastToggle;

    void setup()
    {
      //Serial.begin(115200);  // NOT needed if gpsPort *is* Serial (pins 0 & 1)
      gpsPort.begin( GPSBaud );

      DDS.begin(W_CLK_PIN, FQ_UD_PIN, DATA_PIN, RESET_PIN);
      DDS.calibrate(trimFreq);

      pinMode( OUT_PIN, OUTPUT ); // must be set to output mode
      lastToggle = millis();
    }

    void loop()
    {
      // Toggle the OUT_PIN every 50ms
      if (millis() - lastToggle > 50) {
        digitalWrite( OUT_PIN, !digitalRead(OUT_PIN) );   // toggle the pin
        lastToggle += 50; // step to the next toggle time
      }

      // Dispatch incoming characters
      if (gps.available( gpsPort )) {
        gps_fix fix = gps.read(); // get a fix structure with all GPS fields

        Serial.print(F("SPEED km/h="));

        // for testing, use some random values (comment this out later)
        fix.valid.speed = true;
        fix.spd.whole   = random( 0, 35 );

        if (fix.valid.speed) {
          float speed=fix.speed_kph();
          Serial.print( speed );

          double freq = map(speed, 0, 100, 0, 160);
          DDS.setfreq(freq, phase);

          Serial.print( ' ' ); // for debugging, show the DDS frequency
          Serial.print( freq );
        }
        Serial.println();
      }

    }

Notice that it checks to see if there is a valid speed.  The GPS device may not know the speed, depending on satellite reception.

If you want to try it, NeoGPS is available from the Arduino IDE Library Manager, under the menu **Sketch -> Include Library -> Manage Libraries**.
<hr>
### UPDATE

For the code you posted (which is not a complete program) in an Answer (instead of editing your question :-/), you could do something like this:

    #include <NMEAGPS.h>
    NMEAGPS gps;
    gps_fix fix;

    #define gpsPort Serial  // GPS on pins 0 & 1 or whatever
    static const uint32_t GPSBaud = 9600;

    void setup()
    {
      Serial1.begin(115200);
      Serial2.begin(115200);

      gpsPort.begin( 9600 );

        ...other things?
    }

    void loop()
    {
      // Constantly read GPS characters
      if (gps.available( gpsPort )) {

        // Update the global fix structure with the latest GPS info.
        //   The speed will be used later by SendData.
        fix = gps.read();
      }

      // Constantly read Serial2 characters (a sensor?)
      if (Serial2.available())
      {
        int b     = Serial2.read();
        int chunk = b >> 6;
        if (chunk == syncc)
        {
          bytes[syncc] = b & 63;
          syncc++;

          if (syncc == 4)
          {
            syncc = 0;
            tach = bytes[0] + (bytes[1]<<6);
            velocityfreq = bytes[2] + (bytes[3]< delayTime)  ??? "<" ???

            SendData();
            prevTxTime = millis();
          }
        }
      }
    }

    void SendData()
    {
      // No need to use sprintf, just print the pieces.

      Serial1.print( data1 );
      Serial1.print( '|' );
      Serial1.print( data2 );
      Serial1.print( '|' );
      Serial1.print( data3 );
      Serial1.print( '|' );
      Serial1.print( data4 );
      Serial1.print( '|' );

      // use the current GPS speed, as set in loop
      Serial1.print( fix.speed_kph() );
      Serial1.print( F("\r\n") ); // F macro saves RAM for doubled-quoted string constants
    }

I had to guess at the nesting of curly braces because IT IS NOT INDENTED, nor do the CURLY BRACES MATCH.  sad.


body:
Arduino Pro Mini ATmega 328P 3.3V 8MHz, connected to USB port via USB to Serial breakout board built around the FT232RL FTDI chip. JTAGenum project code uploaded to the Arduino. I opened terminal and tried to run test command (without connecting wires between target and Arduino), but terminal output show [garbage] [1] values. The baud rate of the serial console has been set **115200**, as specified in JTAGenum code. Not sure whether this issue can be related to `CPU_PRESCALE` defintions in code.

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

title: Arduino Pro Mini ATmega 328P: garbage output on serial console

Answers: 0


body:
My Arduino MKR Fox 1200 doesn't upload any sketches. First it worked, but now it doesn't.
It compiles the bare minimum sketch (empty loop and empty setup) but then uploads forever and after a long while it says port busy or Board not Found on Port

title: MKR FOx 1200 doesn't upload Sketch

Answers: 1

body:
I think that your Operating System has not found the board.  This could be for any number of reasons, not least a Windows update, if you have Windows :).

 1. Close the IDE and unplug the board.
 2. Wait 10 seconds.
 3. Plug the board in, did the OS detect the board?
 4. If NO, Unplug board and restart computer.
 5. IF NO, When booted plug in board, did it detect the board -> No Stop.
 6. If yes, start the IDE.
 8. Check you have the write COM port selected.
 9. Try loading a sketch again, did it work?

Other things to try:

 - New USB cable
 - Different USB port.
 - Remove other USB devices, my Xbox controller sometimes prevents Arduinos attaching, not idea why.
 - Different board.
 - Different computer.


body:
I seem to be going round in circles trying to find the answer to this question, so thought I'd ask the good folk here.

I have an Arduino pro mini 3.3v based project, using lowpower libraries. It wakes up every h hours and takes a reading.  I would now like it to still wake up every h hours but in the meantime know whether the item (the board, or its container) has actually physically been moved - like binary, did it move or not at all?

I don't need constant monitoring of position. Once triggered I'd turn off the interrupt until the next wake up event.

In my mind I see the solution as being an interrupt attached to low power device which when moved slightly triggers the event to be recorded.

pseudo code would be:

    if ((hour == h_hour) && movementDetectedSinceLastWakeup){
      doStuff();
    } else {
      goBackToSleep(2hrs);
    }

My question is, what kind of sensor should I consider for this job?

 - 3.3v
 - lowpower
 - can trigger interrupt

EDIT "move" as in it vibrated past some set level.

title: What device do I add in order to detect if my project is moved?

Answers: 2

body:
I would say, that a gyroscope would be perfect for physical movement. In case there is change in X, Y or Z axis, it should turn on a flag as an indicator.

The model MPU-6050 would be ok for this project.

body:
There's two basic ways of detecting vibration - one which is quantifiable and one which isn't (much).

The simplest way is a sprint (possibly weighted) inside a metal tube. Vibration causes the spring to move and touch the tube - the resultant circuit is just the same as using a button. Sensitivity can't be controlled (other than maybe "how many times in a given period does the spring touch the tube"), but it's very very simple to use. They are often used in simple movement alarms (for things like bikes, etc).

The second method is to use an accelerometer. These are harder to work with but they do give you the actual amount of vibration at any given time. They are far more sensitive than a simple spring+tube, but since they are an active component they need to be constantly queried (often through I2C or an analog input). That makes them harder to use in a low-power scenario.

Some accelerometers are more intelligent and can be programmed to trigger an interrupt when vibration above a certain level is detected, though again that increases the complexity of working with them.

So in short: the lowest power option is the simple spring+tube sensor - it uses zero quiescent current. The best option is a programmable accelerometer that can trigger an interrupt to wake the main MCU. Which you choose depends on how sensitive you need the device to be...


body:
I'm trying to connect multiple sensors to an arduino and write the retrieved data in to a SD. When I test each module separately it works properly, but when I put everything together the SD card module doesn't work, can anybody help me?

This is the code that I'm using:

    #include <Arduino.h>
 #include <SPI.h>
 #include <SD.h>
 #include <Wire.h>
 #include <TinyGPS++.h>
 #include <SoftwareSerial.h>
 #include <MS5611.h>

 // SD
 #define GPS_STORED_DATA_FILE_NAME "gps.txt"
 #define SDCARD_PIN 10
 bool _sdError = false;

 // GPS
 #define GPS_RX_PIN 9
 #define GPS_TX_PIN 8
 #define GPS_BAUD 9600
 TinyGPSPlus _gps;
 SoftwareSerial _ss (GPS_RX_PIN, GPS_TX_PIN);
 unsigned long _timeLastMeasurementGps;

 // MS5611
 MS5611 _ms5611;

 void sdTest(double latitude, double longitude, float elevation, double time) {
   if (_sdError) {
     //Serial.print("SD ERROR. Stopping writing");
     return;
   }
   String fileName = GPS_STORED_DATA_FILE_NAME;
   File myFile = SD.open(fileName, FILE_WRITE);

   if (myFile) {
     Serial.print("Writing to ");
     Serial.print(fileName);
     Serial.print("...");
     //myFile.println("testing 1, 2, 3.");
     myFile.print(latitude);
     myFile.print(" | ");
     myFile.print(longitude);
     myFile.print(" | ");
     myFile.print(elevation);
     myFile.print(" | ");
     myFile.println(time);
     myFile.flush();
  // close the file:
     myFile.close();
     Serial.println("done.");
   } else {
     // if the file didn't open, print an error:
     Serial.println("error opening");
     Serial.print(fileName);
     _sdError = true;
   }

   // re-open the file for reading:
   myFile = SD.open(fileName);
   if (myFile) {
     Serial.print(fileName);
     Serial.println(":");

     // read from the file until there's nothing else in it:
     while (myFile.available()) {
      // Serial.write(myFile.read());
       myFile.read();
     }
     // close the file:
     myFile.close();
   } else {
    // if the file didn't open, print an error:
     Serial.print("error opening ");
     Serial.println(fileName);
   }
 }

 void smartDelay(unsigned long ms)
 {
   unsigned long start = millis();
   do
   {
     while (_ss.available())
       _gps.encode(_ss.read());
   } while (millis() - start < ms);
 }

 void setupSd() {
   Serial.print("Initializing SD...");
   pinMode(SS, OUTPUT);

   if (!SD.begin(SDCARD_PIN))
     Serial.println(" ERROR");
   else
     Serial.println(" DONE");
 }

 void setupGps() {
   Serial.print("Initializing GPS...");
   _ss.begin(GPS_BAUD);
   smartDelay(1000);
   _timeLastMeasurementGps = millis();
   Serial.println(" DONE");
 }

 void setupMs5611()
 {
    Serial.print("Initializing vario...");
    while(!_ms5611.begin(MS5611_ULTRA_HIGH_RES))
   {
     Serial.println("Could not find a valid MS5611 sensor, check wiring!");
     delay(500);
   }
   // Serial.print("ms5611 Oversampling: ");
   // Serial.println(_ms5611.getOversampling());
   Serial.println(" DONE");
 }

 void setup()
 {
   Serial.begin(115200);
   setupMs5611();
   setupSd();
   setupGps();
 }

 void loop()
 {
   delay (100);
    sdTest(1, 2, 3, 4);
 }

Thanks in advance!

title: Unable to access SD Card when using GPS and MS5611 sensors

Answers: 3

body:
If you are using an SPI SD breakout board (like 50 cents on AliExpress), than it does work only when not connected to other SPI devices.

However, when connected to other SPI devices it cannot communicate. The only way I could overcome this problem was to use an SD recorder/logger, which is a shield that fits on an Arduino (and contains a small proto space and sometimes a RTC. Or use a device that has multiple SPI ports.

Type (SD reader) that do not work together with other SPI devices:

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

Type (SD Data recorder/logger) that do work together with other SPI devices:

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

  [1]: https://i.stack.imgur.com/KmmVX.jpg
  [2]: https://i.stack.imgur.com/2Vir4.jpg

body:
I suspect that your problem lies with how your SD card is connecting via the SPI bus.

The problem is that a lot of Serial Peripheral Interface (SPI) devices, particularly the cheaper ones, don't properly put the MISO pin into high-impedance when SS is pulled high.

I had almost exactly this situation with one of my projects. I eventually resolved it by placing a tri-state buffer in the MISO line for each of the SPI devices.

I used a [74HC125][1] (4-channel tri-state buffer).

This is the page on [Better SPI Bus Design in 3 steps][2] that finally got me on the right track. I think the explanations are reasonably clear (at least compared with many other sites I found!).

  [1]: https://assets.nexperia.com/documents/data-sheet/74HC_HCT125.pdf
  [2]: https://www.dorkbotpdx.org/blog/paul/better_spi_bus_design_in_3_steps

body:
The SD I have is the following:

https://www.banggood.com/Micro-SD-TF-Card-Memory-Shield-Module-SPI-Mciro-SD-Adapter-For-Arduino-p-919914.html

Using the [SdFat library][1] I managed to make it work a "little": if I draw something in the external screen (PCD8544) during the setUp process the SD card will not work, otherwise it will work. I'll end up buying a new SD card reader.

  [1]: https://github.com/greiman/SdFat


body:
Just starting with my first Arduino project.
In order to measure voltage in a circuit I connected my multimeter to two points in the circuit (for example before and after a resistor).

I am interested to know how an input pin can measure its voltage (for example 5v or 0v).

title: How does Arduino digital input pin measure its input voltage?

Answers: 2

body:
Assuming you are asking about digital input pins on an Arduino:

Digital logic operates at the saturation and cut off regions of the transistor logic used.  Most modern day processors use CMOS transistors.  The logic levels are Low: 0 V to 1/3 VDD and High:2/3 VDD where VDD is the supply voltage.  This information can be found [here][1].

So, if your processor is designed to operate at 5 volts and is likely made of CMOS logic gates, the low level voltage is from 0 to 1.67 volts and the high level voltage is from 3.33 to 5 volts.

But to address your question specifically:  Digital input pins do not measure the voltage.  Not like an ADC input.  Instead, it is agreed that nothing operating normally that is to interface with a digital pin will produce (linger at) a voltage other than those designed to force the transistors into cut-off or saturation.

So do be careful not to do this.  It could result in unexpected behavior.

Now, if you can not avoid voltage between the designated upper limit of the low logic signal and the lower limit of the high logic signal you man need to buffer your signal with a device called a [Schmitt Trigger][2].  This device adds hysteresis to your signal and converts it into either a low or high logic state.  Examples of hysteresis include the thermostat control for your furnace.

A final word, do not exceed the voltage at a digital input to that which is supplied at the power pin of that digital circuit. This can cause all kinds of problems.  Usually this is not a problem as most devices / projects are powered off of one power source.  But in case multiple power supplies are used, keep this in mind.

  [1]: https://en.wikipedia.org/wiki/Logic_level
  [2]: http://htthttps://en.wikipedia.org/wiki/Schmitt_triggerp://

body:
The implementation of the digital inputs may depend on what kind of
microcontroller you are using. On AVR microcontrollers (most common
Arduinos are AVR-based), the inputs go through [Schmitt triggers][].
This means that the voltage seen by the logic downstream is always a
valid logic level. You should then not worry about an invalid input
causing “unexpected behavior”.

It should be noted, though, that the characteristics of the Schmitt
trigger are very loosely specified. If I take the ATmega328P at Vcc =
5 V as an example (the MCU powering the Arduino Uno), the thresholds are
expected to be “typically” around 2.1 V (for the HIGH → LOW transition)
and 2.6 V (LOW → HIGH). But these are only typical values. The only
thing that is really specified is that the input reads LOW when the pin
voltage is below 0.3 Vcc and it reads HIGH above 0.6 Vcc. At 5 V this
means that the thresholds could be anywhere between 1.5 V and 3 V).

[Schmitt triggers]: https://en.wikipedia.org/wiki/Schmitt_trigger


body:
I recently started a project with HC-SR04 sensors and RTC DS1302 clock. The idea is when a sensor detects an object, call and keep a timestamp (hh:mm:ss) all over the loop until Else If{} appears,  but I don't know how to.

    #include <DS1302.h>
    #include <Time.h>
    #include <TimeLib.h>
    #define echoPin 12 // Echo Pin
    #define trigPin 13 // Trigger Pin

    time_t t = now();
    DS1302 rtc(6,20,21);
    String inTime;

    void setup()
    {
      Serial.begin(9600);
      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
    }

    void loop(){
        long duration, distance;
        digitalWrite(trigPin, LOW);
        delayMicroseconds(2);
        digitalWrite(trigPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(trigPin, LOW);
        duration = pulseIn(echoPin, HIGH);
        distance = (duration/2) / 29.1;

       if (distance <= 4) {
     inTime= rtc.getTimeStr();
     Serial.println(inTime);

        }

        else if (distance >= 5 || distance <= 0){
     Serial.println("Out of range");

        }

      delay(500);
    }

Appreciate any help, thanks.

title: Keep RTC time in a loop

Answers: 1

body:
Check '{' and '}' pairs in your code.

    void loop(){
        long duration, distance;
        digitalWrite(trigPin, LOW);
        delayMicroseconds(2);
        digitalWrite(trigPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(trigPin, LOW);
        duration = pulseIn(echoPin, HIGH);
        distance = (duration/2) / 29.1;
        if (distance <= 4) {
            inTime= rtc.getTimeStr();
            Serial.println(inTime);

       }
    } //<--- what is this little fella doing here?
        else if (distance >= 5 || distance <= 0){
        Serial.println("Out of range");
        }

    delay(500);
    }


body:
I have two Arduino unos, and I am using I2C to have them communicate with each other. The A4, A5, and GND of each Arduino is connected to the other. These are my functions:

On the sending Arduino:

    void playNote(int pitch, int len, int location){
      Serial.println(String(String(location) + ":" + String(pitch) + "," + String(len) + "\n"));
      Wire.beginTransmission(location);
      Wire.write(pitch);
      Wire.write(len);
      Wire.endTransmission();
    }

On the receiving Arduino:

    void receiveEvent(int howMany){
      int pitch = Wire.read();
      int len = Wire.read();
      Serial.println("Pitch: " + String(pitch) + ", Length: " + String(len));
      playNote(pitch,len);
    }

`pitch` always sends fine. When I send `len` as 150, it works and is received as 150. However, when `len` is sent as 300, it is received as 44. I cannot figure out why this is. Any help is appreciated.

title: Arduinos using I2C reading integers wrong

Answers: 1

body:
wire.write(n) sends a single byte of value n

150 decimal = 96 Hex
300 decimal = 012C Hex ...so is 2 bytes, and is truncated to one byte of value 2C Hex.

2C Hex = 44 decimal

Send a single byte! Maximum value of a byte is 255 decimal

If you need to send multiple Len bytes, then you need to ascertain the number of bytes and send them individually.
In your code you send multiple bytes concatenated one after the other already ...you send Pitch followed by Len.
All you need to do is split Len into L1, L2 bytes first.

L1 = Len and xFF
Shift Len left or do other logical math to derive high byte, L2
Then send L1 and L2


body:
I'm doing some security research on FreeRTOS embedded systems and I don't have much information about Arduino. Is there any way to leak function or variable addresses on serial console? I can use `avr-nm` and `avr-objdump` but, I may need it for dynamically allocated memory.

It gives:

    call of overloaded 'println(void (*)(void*))' is ambiguous

When I try to pass function pointers to serial console.

UPDATE:
With using (unsigned char) I can leak something and it is 68 in serial console my code below. I have

    000004d0 l     F .text  000000e0 _Z9TaskBlinkPv

from symbols if it is related with TaskBlink.

    #include <Arduino_FreeRTOS.h>

    // define two tasks for Blink & AnalogRead
    void TaskBlink( void *pvParameters );
    void TaskAnalogRead( void *pvParameters );

    // the setup function runs once when you press reset or power the board
    void setup() {
      // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);

      // Now set up two tasks to run independently.
      xTaskCreate(
        TaskBlink
        ,  (const portCHAR *)"Blink"   // A name just for humans
        ,  128  // Stack size
        ,  NULL
        ,  2  // priority
        ,  NULL );

      xTaskCreate(
        TaskAnalogRead
        ,  (const portCHAR *) "AnalogRead"
        ,  128 // This stack size can be checked & adjusted by reading Highwater
        ,  NULL
        ,  1  // priority
        ,  NULL );

      // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
    }

    void loop()
    {
      // Empty. Things are done in Tasks.
    }

    /*--------------------------------------------------*/
    /*---------------------- Tasks ---------------------*/
    /*--------------------------------------------------*/

    void TaskBlink(void *pvParameters)  // This is a task.
    {
      (void) pvParameters;
      // initialize digital pin 13 as an output.
      pinMode(13, OUTPUT);
      Serial.println((unsigned char) &TaskBlink,HEX);
      for (;;) // A Task shall never return or exit.
      {
        digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
        vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
        digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
        vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
      }
    }

    void TaskAnalogRead(void *pvParameters)  // This is a task.
    {
      (void) pvParameters;

      for (;;)
      {
        // read the input on analog pin 0:
        int sensorValue = analogRead(A0);
        // print out the value you read:
        //Serial.println(sensorValue);
        vTaskDelay(1);  // one tick delay (15ms) in between reads for stability
      }
    }

UPDATE 2: When I'm using (unsigned int) it is giving 268 and dissassembling 268 gives:

         262:       9b 8d           ldd     r25, Y+27       ; 0x1b
         264:       8c 8d           ldd     r24, Y+28       ; 0x1c
         266:       98 13           cpse    r25, r24
         268:       05 c0           rjmp    .+10            ; 0x274 <_ZN14HardwareSerial5writeEh+0x24>
         26a:       e8 89           ldd     r30, Y+16       ; 0x10
         26c:       f9 89           ldd     r31, Y+17       ; 0x11
         26e:       80 81           ld      r24, Z
         270:       85 fd           sbrc    r24, 5
         272:       24 c0           rjmp    .+72            ; 0x2bc <_ZN14HardwareSerial5writeEh+0x6c>
         274:       f6 2e           mov     r15, r22

It is not my function nor a tramboline. It is at:

    000004d0 <_Z9TaskBlinkPv>:
    /*--------------------------------------------------*/
    /*---------------------- Tasks ---------------------*/
    /*--------------------------------------------------*/

    void TaskBlink(void *pvParameters)  // This is a task.
    {
         4d0:       cf 93           push    r28
         4d2:       df 93           push    r29
         4d4:       cd b7           in      r28, 0x3d       ; 61
         4d6:       de b7           in      r29, 0x3e       ; 62
         4d8:       a1 97           sbiw    r28, 0x21       ; 33
         4da:       0f b6           in      r0, 0x3f        ; 63
         4dc:       f8 94           cli
         4de:       de bf           out     0x3e, r29       ; 62
         4e0:       0f be           out     0x3f, r0        ; 63
         4e2:       cd bf           out     0x3d, r28       ; 61

What am I doing wrong?

title: How to leak function addresses?

Answers: 2

body:
What you need is

      Serial.println((unsigned int) &TaskBlink, HEX);

The operator "&" gives you an address. In Arduino (ATMega MCU), that is a 16 bit value, that fits inside an unsigned int.

The cast operator "`(unsigned int)`" means "I will use that value as an `unsigned int`".

Serial knows how to print numerical values (but not funtion addresses).

body:
The error you have is exactly a factor 2: Your `Serial.print()` gave
0x0268, whereas `TaskBlink(void *)` is at address 0x04d0, which is twice
0x0268. Both addresses are correct: it all depends on what you mean by
“address”.

Functions live in the microcontroller's flash. At the hardware level,
and for the purpose of fetching instructions, the flash is addresses by
16-bit words. This means that address 1 is one word (two bytes) past
address 0. Note that for fetching constant “PROGMEM” data, the `lpm`
instruction addresses the flash byte-wise. This may seem inconsistent,
but it's the way the hardware is designed. Function pointers are
addresses intended to be put into the program counter by means of the
`icall` (indirect call) instruction. This instruction expects a
word-wise address, thus function pointers are word-wise addresses.

For some reason – presumably for consistency with other platforms – the
authors of the GNU binutils package chose to always use byte-wise
addresses. When `avr-nm` and `avr-objdump` tell you that
`TaskBlink(void *)` is at address 0x04d0, they mean it starts 0x04d0
_bytes_ after the start of the flash. When `Serial.print()` tells you
it's at 0x0268, it means the address used at the hardware level is
0x0268, and that's because the function starts 0x0268 _words_ after the
start of the flash.


body:
I am trying to read a LM35 temperature sensor with Arduino UNO which I got as a gift.
The issue is the fact, that my readings of sensor are, well, suspicious at least - they jump with each reading some 5 °C up or down.

I had used several posts how to wire  the thing to Arduino board and for and program the reading ([1], [2], [3]) and produced the code posted below. The sensor reading fluctuates really a lot - it jumps by some 3 to 7 °C after  each reading regardless of reading frequency (tested with reading each 0.5 s, 1.0 s or 2.5 s). (Unfortunately I do not own a multi-meter to check actual values.) To mitigate the issue I implemented an averager, but underlying problem stays. Expected values are something like 23 or 24 °C as measured by digital weather station and bimetallic thermometer respectively.

Have you met this before ? Do you have any ideas what might be source of this ? I am beginner to electronics as well as to Arduino, trying to learn and mainly understand it.

The complete code:

    #include <WString.h>

    //Stores read analog values
    int readLM35;
    const int sensorAnalogPin = 0;
    const float voltsToTemperature = 1.1 / 1023 * 100; // (1.1V supply / 10bit resolution) * (10 mV/°C = 1 V / 100 °C)
    //Stores the temperature in °C
    float temp;
 //Averager
    float temps[8];
    byte position = 0;
    float averageTemp;

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

        //For setting internal analog reference voltage to 1.1V
        analogReference(INTERNAL);
    }

    void loop() {
        digitalWrite(LED_BUILTIN, HIGH);
        delay(50);
        digitalWrite(LED_BUILTIN, LOW);

        //Measure temperature
        readLM35 = analogRead(sensorAnalogPin);
        temp = readLM35  * voltsToTemperature;

        //Save it
        temps[position] = temp;
        if (position == 7) {
            position = 0;
        } else {
            position++;
        }

        //Get average
        averageTemp = 0;
        for (byte i = 0; i < 8; i++) {
            averageTemp += temps[i] / 8;
        }

        //Write
        Serial.println(String(readLM35) + " => " + String(temp, 1) + " deg. C, avg. " + String(averageTemp, 1));
        delay(2500);
    }

Example of output (note the first numbers - actual reading):

    211 => 22.7 deg. C, avg. 22.5
    186 => 20.0 deg. C, avg. 21.9
    234 => 25.2 deg. C, avg. 22.7
    173 => 18.6 deg. C, avg. 21.9
    237 => 25.5 deg. C, avg. 22.6
    185 => 19.9 deg. C, avg. 21.9
    231 => 24.8 deg. C, avg. 22.4
    193 => 20.8 deg. C, avg. 22.2
    223 => 24.0 deg. C, avg. 22.3
    206 => 22.2 deg. C, avg. 22.6
    197 => 21.2 deg. C, avg. 22.1
    225 => 24.2 deg. C, avg. 22.8
    183 => 19.7 deg. C, avg. 22.1
    240 => 25.8 deg. C, avg. 22.8

[![Experimental setup][4]][4]

  [1]: https://playground.arduino.cc/Main/LM35HigherResolution
  [2]: https://www.timdejong.nl/blog/get-accurate-temperature-lm35-arduino-correctly
  [3]: https://electronics.stackexchange.com/questions/131326/excessively-high-temperature-reading-with-lm35
  [4]: https://i.stack.imgur.com/6uzYO.jpg

title: Fluctuating readings of LM35 temperature sensor (+- 5°C) with Arduino UNO

Answers: 7

body:
Try :-

    const int temperaturePin = A0;

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

            Serial.begin(9600);
        }

    double getVoltage(int pin)
    {

      return (analogRead(pin) * 0.004882814);

        }

    void loop() {

          double degree,voltage;
          degree = analogRead(temperaturePin)*0.48875855;
          voltage = getVoltage(temperaturePin);
          Serial.print(voltage);
          Serial.print(degree);
          delay(1000);

        }

body:
I guess when 0 = 0 and 5V = 1023, then you should divide by 1023.
Looking at the question, I notice that you use AnalogPin = 0. Myself, I would stick to AnalogPin = A0.
A0 is defined as:
## define PIN_A0   (14)
so it is not equivalent to 0.
Are you sure you're reading the right pin? Also try another pin like A3.

body:
this is a known issue for all Arduino sensors (fluctuations and drift), I also had this problem with humidity sensor and water level sensor with LM393 comparator, what I tried to do to make the fluctuations less was trying to calculate average readings instead of single reading:

    for (int i = 0; i < 100; i++)
    {
    levelSensorValue = levelSensorValue + analogRead(levelSensorPin);
    moistureSensorValue = moistureSensorValue + analogRead(moistureSensorPin);
    }
    levelSensorValue = levelSensorValue / 100;
    moistureSensorValue = moistureSensorValue / 100;

generally speaking, all sensors have a linear range witch cannot be reliable beyond it, and also calibration for them is necessary.

body:
Why have you done 1.1/1023. Your saying that the supply is 1.1v but your supplying it 5v. I use (readLM35/1024)*500 to get temperature value in °C and it is on par with a thermometer I have bought. If this doesn't work try with another lm35. You might just have a faulty one.

Also the LM35 is factory calibrated for voltage. So you have to calibrate it according to the Arduino you use.
I would recommend the ds18b20 as it's calibrated for temperature. Using the Dallas temperature library makes it easier to use as well

![I found this on the Arduino forum some time back](https://i.stack.imgur.com/mrdek.jpg)

body:
many answers, stick to the code or the LM35 itself rather than the main part, the ADC.
when you are reading a [approximately] right temperature, well, then the code, vRef and pin config is right.
I had problem with ADCs as I had to measure many voice signals for my thesis. here are some problems which may occur :

 - double check if the board itself, has proper AVCC/AREF decoupling caps. many clone boards doesn't pay attention to production failures. decoupling caps usually connect between ground (GND) and a positive supply line(like VCC) to filter out noise.
 - if you have access to the AVCC/AREF pin, connect 2 or 3 paralleled 100nf caps between them and ground. the values are not critical. anything in the 10nF up to 10uF range is fine. you can use different values for each cap.
 - check your input power supply noise. computer USB port is the most trusted power supply. other power supplies (wall adapters, cheap power banks etc.) have some unimaginable noise.
 - use caps (decoupling caps. the caps which are connected between + and - pins) on every single component or sensor. like LCDs, LM35 sensor... .
 - try to use the exact code and sensor on other analog pins and if you got any, another Arduino. if the problem insists, then you can check for another LM35, or the code like the others said. but if the problem didn't exist, then the board has a problem. any faulty component in supply line can cause this. from regulators to a bad joint or PCB via.

body:
The cause is the low sinking capabilities of LM35 output. This makes the output sensitive to EMI. Yes, the output output impedance is stated as 0.5 ohms but only for sourcing current. The sinking current is limited to 1uA which is easily achieved by the environment noise.
[![enter image description here][1]][1]

You need to add a low impedance load between LM35 output and ground, can be 200 ohm as the data sheet recommends for heavy capacitive loads but I wouldn't go that far, might be 1k or 2k to avoid self heating errors.

No software only solution can solve this error.

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

body:
If issue with readings persist, put an RC circuit for measuring the voltage as it is similar to averaging done in software. Another thing that you can try is replacing the LM35 with a new one as sometimes it could be faulty or you might have damaged it(has happened with me). However u can easily check this by measuring the voltage at the sensing pin whether it corresponds to what you are getting. If you are working with electronics please invest in a multi-meter as it will help you in all your projects

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

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


body:
I think it will become readily apparent that i have absolutely zilch programming experience as I am currently going out my mind with a problem i am having trying to get my first arduino uno project off the ground. I am simply attempting to acquire the necessary libraries including a TimeLib.h library file, but however i seemingly cant even figure out how exactly to complete that very simple first step. I am giving it a serious go trying to break into this interesting field and would greatly appreciate any advice anyone could generously provide.
With regards,

Newcomer

title: Newcomer at Arduino

Answers: 1

body:
If you are using the Arduino IDE then you first need to include the library then you can put `#include <TimeLib.h>` at the top of your sketches.

There is plenty of documentation online about how to use Arduino. To solve your immediate problem I would go here: https://www.arduino.cc/en/Guide/Libraries


body:
Most of my Arduino work has been on a PC, but now I am on a Mac. I need to modify Print.h to give me printf facilities, as detailed [here][1].

I can find Print.h buried within my application files, but changing it has no effect. A search across my disk reveals no further Print.h files.

Where on a Mac should I find and edit the Print.h file?

Can someone tell me what I am missing please?

Thanks,

Martin

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

title: Modifying Print.h on a Mac

Answers: 2

body:
There must be a print.h in the Arduino IDE. Try to reinstall. In [this webpage][1], there is no specification about the platforms where it is neither where it's not.

And, of course, you don't need to edit anything: use a medium/big sized string with `sprintf`and you could use the printf capabilities.

  [1]: https://www.arduino.cc/en/Serial/Print

body:
Each hardware package has its own version of Print.h in the cores folder. The Arduino IDE installation includes a copy of the Arduino AVR Boards hardware package but that package will not be used if you installed a different version via Boards Manager (**Tools > Board > Boards Manager**) or if you have a board selected from the **Tools > Board** menu that is not part of the Arduino AVR Boards package. Operating systems seem to like to hide the folder that Boards Manager installs the hardware packages to by default, which makes things more confusing.

The easiest way to find the location of the active hardware package, and thus the Print.h you want to edit is this:

1. Select a board of the hardware package you want to locate from the **Tools > Board** menu.
1. **File > Examples > SPI > BarometricPressureSensor** (or any other example sketch of the SPI library)
1. **Sketch > Show sketch folder** - this will open the BarometricPressureSensor example sketch folder.
1. Navigate up 4 folder levels to the architecture folder.
1. Open the `cores` subfolder of the architecture folder.
1. If there are multiple folders inside the `cores` folder you will need to open boards.txt (which is located in the architecture folder) and find which core library your board is using, which is specified by the `build.core` property. Most hardware packages only have a single core library so this should not be necessary.
1. Open the core folder. There you will find Print.h.

The reason I selected the SPI library example is because this is a hardware specific library that is bundled with all hardware packages I've encountered. If you encounter a hardware package that does not bundle an SPI library you would want to open the example for another hardware specific library such as Wire, SoftwareSerial, or EEPROM.


body: I am developing a 247 monitoring system with **Arduino**. The values need to be sent to server periodically as well as upon interrupt (**Watchdog**). To access the internet, I am using the **SIM800** module. Now, **Is it possible to HTTP inside an ISR**? As far as I know, **Serial** communication should not be used in ISR. Then how can I communicate with SIM800? Any suggestion will be valuable.

title: Is it possible to HTTP inside an ISR

Answers: 1

body:
No, you cannot do HTTP in an interrupt, and you certainly can't use SoftwareSerial in an interrupt.

To trigger a heavy task in an interrupt you just set a flag (variable) which means "this task is due to be performed". Your main loop then checks that variable, runs the task, and resets the variable ready for the next time the interrupt triggers.

In multithreading environments these flags are called *semaphores* (yes, from the old signalling system using flags on ships). One thread (the interrupt) signals to the other thread (`loop()`) that it can do something.


body:
Is it possible to publish and subscribe using MQTT, when the mqtt broker is connected to a network which is created by a NodeMCU?

Can a NodeMCU connect to its own created network?

title: NodeMCU access point for MQTT broker

Answers: 1

body:
The devices conected via an NodeMCU acting as an WiFi Access Point can communicate between with the NodeMCU and between themselves.

So, if all devices involved are connected to the same NodeMCU, then they can communicate as you asked.

NodeMCU also works as an Access Point + Station. Beside being an AP, then NodeMCU can simultaneously be a client in another WiFi network.

I doubt NodeMCU can route between his client and the external WiFi network.


body:
I have noticed that some atmel chips can do "self programming" and I'm doing a hobbyist project where I need to change the "setting" of my arduino without code-reuploading through Arduino IDE.

Is it possible to do that ?
If it's possible. Please give me some basic though about how to do it.

Thanks in advance !

title: Arduino self programming

Answers: 6

body:
You can write to the non-volatile memory of the microcontroller and then read it again during setup.

Another (perhaps simpler) option is to have an external eeprom chip in a socket to hold the settings so you can program that separately from the module. That way you don't need to have a menu in your project.

body:
Self programming is used by `Arduino` bootloader. If you want something special, you have to change bootloader, because you can't call `SPM` instruction outside of `BOOT` sector (the only exception are `AVRs` with a small program memory).

I'd recommend to use internal `EEPROM` storage instead.

body:
You have multiple options to change *settings* without code-reuploading. By settings I mean values, not code.

First, you can add a physical UI to your project. It can be a push button and a LED, a key pad with a LCD display or a touch sensitive screen.

Second, your sketch can use `Serial` as way to receive comands and display information. You will need a tablet, smartphone or PC.

Third, you can also use Bluetooth instead of Serial.

Fourth, you can add WiFi to your project. With WiFi any solution is posible (web page, Android App ...).

You can also mix technologies: have a minimal physical UI for emergencies and a full interface via WiFi.

With NodeMCU you also have a file system where you can store you app data. It may be simpler to use than EEPROM.

body:
There are two areas of non-volatile storage in an Arduino: Flash and EEPROM.

Flash is where your program and constant values are stored. Variables with default values also have their default values stored in Flash.

EEPROM is a much smaller area with no real fixed purpose - you can store whatever values you want in there.

Flash can *only be written to by code that is in the bootloader area of flash*. This is important. A program *cannot* modify itself. Only the bootloader can modify a program - and then only in chunks ("pages"). It has to erase a whole page before it can write data to it.

The reason why you can't modify Flash from your main program is simple: Flash is the only place code can be executed from. If you erase the page of flash that contains the code that is programming the Flash then everything dies. Horribly. So it's stopped in its tracks by not allowing it to happen in the first place.

EEPROM, conversely, can be written to by anything - the bootloader *or* the main program. And on top of that individual values can be modified at will - no need to erase pages.1

So to answer the question behind your question ("How can I store and modify settings?"): it's quite simple - store them in EEPROM.

The IDE has examples of how to use the bundled EEPROM library, and there are more details [in the Arduino reference manual](https://www.arduino.cc/en/Reference/EEPROM).

----
1: Some systems don't have EEPROM, so they emulate it using Flash. These systems still have to erase the Flash in pages, but they try to do it transparently. Some (such as the ESP8266) use a `commit()` method to update a batch of values. Others, such as chipKIT boards, use wear levelling and separately indexed writing to reduce the need to erase pages.

body: Yes, you can self-program these.  There are several different bootloaders you can use to do this - here's one: https://bitbucket.org/talk2/talk2boot

body:
You can do something simple - say have 2 pins to select 1 of 4 sets of values for the code to use.  Read the pins in setup(), and change values to use in loop() accordingly.

    void setup(){
    change = PIND & 0b1100000; // say D7/D6 used on a Uno.
    switch (change){
      case 0b00000000:
      // set values for D7/D6 = 00
      break;
      case 0b01000000:
      // set values 01
      break;
      case 0b10000000:
      // set values 10
      break;
      case 0b11000000:
      // set values 11
      break;
      }
    }

Or wait in setup() for the choice to come in a Serial message.
Maybe store the sets of values in EEPROM for selection via whatever source, and then let the code change the values if needed.
Or think of other ways to select the values without having to change the existing bootloader.


body:
Arduino Due has 54 pins. It says that it has 12 PWM pins. I know it uses a more powerful chip than other Arduinos.

Can the number of PWM be increased?

Can any of its pin be used for PWM?

title: Can any Arduino Due pin be used for PWM?

Answers: 2

body:
You could do software pwm but the frequency will be several orders of magnitude less than the clock frequency.

The hardware pwm pins have a counter a register and a comparator where every tick it increments the counter, compares the value of the counter to the value in the register and setting the pin to the corresponding value.

If you need more analogue outputs then it's easier to use an external DAC module.

body:
According to the manual:

"The Arduino Due supports analogWrite() on pins 2 through 13, plus pins DAC0 and DAC1. Unlike the PWM pins, DAC0 and DAC1 are Digital to Analog converters, and act as true analog outputs."

https://www.arduino.cc/en/Reference/AnalogWrite


body:
I want to burn the bootloader of esp8266. Assume I have esp8266 on esp12 in hand and an USB ISP programmer (or any other programmer like USBTinyISP).
I (think I) know how to use the Arduino IDE to burn the bootloader (mainly it's by selecting board and the programmer), but how to wire the esp8266? Precisely I mean, "do I use the pins 12, 13, 14, and 15 as these are for SPI connection"?

Edit: I have seen Arduino microcontroller board of which the bootloader was burned, so I was wondering why not do the same for esp8266.

title: Wiring when burning the bootloader of esp8266

Answers: 1

body:
The ESP8266 already has a bootloader to upload new firmware over UART. You don't need to burn anything, and you don't use SPI to program it.

AVR microcontrollers are programmed (aka flashed, or uploaded) using ISP (in-system programming) over SPI. They don't support programming over UART out of the box. To receive new firmware over the serial port, a bootloader is used. It is a piece of software that receives data from the UART and writes it to flash, overwriting the previous firmware.

Before you can do this, you need to write (aka burn) the bootloader firmware to the microcontroller. This can only be done using ISP, because

1. if the chip is blank, there is no bootloader to receive the bootloader over UART
2. if there is a previous bootloader that you want to replace, you can't rely on the bootloader for programming over UART either, because the bootloader would be overwriting itself.

The situation on an ESP8266 is completely different. Whereas on an AVR, ISP is the default method to flash new firmware, on the ESP8266, it is UART flashing.
The ESP8266 already has a system built-in for UART flashing (just like an AVR has a system for ISP flashing), so you don't need to flash a software UART bootloader.

There is no ISP system inside of the ESP8266, so trying to do ISP on the HSPI port won't flash anything.

Read this: [A Beginner's Guide to the ESP8266](https://tttapa.github.io/ESP8266/Chap01 - ESP8266.html)


body:
What is recommended color recognition sensor in the following two cases:

- To determine the color of the floor while the robot is moving (multi-color line follower).

- To determine the color of an object in distance 10cm at least.

For both cases above, I am looking for a sensor so that I can get values like (R: 252 , G: 217 , B: 0) not only red, green or blue as an result, and no problem with small errors.

title: What is recommended color recognition sensor RGB for different cases?

Answers: 1

body:
You have a conceptual error. You don't need *n* wires to transmite *n* bits of information. If you use a *serial protocol*, one wire or two is enough to transmit information of any size: you just send one bit after another.

Just think: you are downloading sketchs in your Arduino thru a cable with only 4 wires ...

Most sensors (and modules) for Arduino use I2C or SPI to transmit commands/information in digital format. You can learn a lot in this [tutorial][2] that covers I2C, SPI and USB.

A quick search on Aliexpress show me this APDS-9960 sensor

[![APDS-9960 sensor][1]][1]

The sensor provide ambient light and color measurement, proximity detection and non-contact gesture detection. The APDS-9960 has built in UV and IR blocking filters, four separate diodes sensitive to different directions, and an I2C compatible interface.

Pins: VL (optional power to IR LED), GND (Ground), VCC (power to APDS-9960 sensor), SDA (I2C data), SCL (I2C clock), and INT (interrupt). Each APDS-9960 also has a detection range of 4 to 8 inches (10 to 20 cm).

It works with 3.3V.

  [1]: https://i.stack.imgur.com/KYM8i.png
  [2]: http://www.deviceplus.com/how-tos/arduino-guide/arduino-communication-protocols-tutorial/


body:
I am simply trying to send a simple HTTP request from an Arduino Uno with w5500 Ethernet Shield to a local server running on my PC.

The two are connected via a crossover ethernet cable and I am able to host a server on the Arduino that is accessible from my PC browser. Now I am trying to use the PC as a server and the Arduino as the client.

Using the simple WebClient example, I can send a successful GET request to google.com from the Arduino.

Here is what I am trying that is failing:

1 - Start a local server via running http-server in my command prompt. That successfully starts a server at 192.168.56.1:8080 that I can access via my browser

2 - Change the Web Client example to use

    IPAddress server(192,168,56,1);

and change the port to

    if (client.connect(server, 8080))

3 - Run this Arduino sketch. The connection fails and I don't know why. I have allowed port 8080 full input access through the Windows firewall.

Any ideas?

title: Send HTTP request from Arduino Ethernet to server on PC

Answers: 1

body: The answer was simple. Instead of trying to connect to the IP address of the local server (192.168.56.1) I had to use the IP address of the ethernet connection between the Arduino and the PC (found using the ipconfig command on the command prompt).


body:
I'm working on an agriculture system and one of my partners (who was taking care of the automation side of things) has gone MIA and we are left with arduino code running our systems that we have a basic understanding of. We're in a bit of a pickle until we can get another person on board who has this kind of expertise and would greatly appreciate any help from anyone who can assist us in modifying a few parameters of the program.

The arduino is controlling one of the generic 8 relay boards hooked up to mains voltage and 8 outlets. The outlets control lights, cO2, water pumps, and fans (which are programmed to activate when temp/humidity reaches certain levels).

We presently understand how to alter how long the relays are activated for, but what we are trying to understand is how to modify the interval at which these relays are activated (cO2/water is every 150 minutes, we would like to alter this). So for example, how would I alter the code to release cO2 every 90 minutes and activate the water pump every 5 minutes?

Any help on this matter would be greatly appreciated! Thank you so much!

    #include <dht.h>
    #include <dht.h>

    dht DHT;
    #define dataPin 7
    //#define DHT11_PIN 7

    #define CH1 1   // Connect Digital Pin 8 on Arduino to CH1 on Relay Module
    #define CH2 2   // Connect Digital Pin 7 on Arduino to CH3 on Relay Module
    #define CH3 3   // Connect Digital Pin 8 on Arduino to CH1 on Relay Module
    #define CH4 4   // Connect Digital Pin 7 on Arduino to CH3 on Relay Module
    #define CH5 5   // Connect Digital Pin 8 on Arduino to CH1 on Relay Module
    #define CH6 6   // Connect Digital Pin 7 on Arduino to CH3 on Relay Module
    #define CH7 9   // Connect Digital Pin 8 on Arduino to CH1 on Relay Module
    #define CH8 8   // Connect Digital Pin 7 on Arduino to CH3 on Relay Module
    int seconds = 0;
    int minutes = 1;
    int hours = 0;
    int days = 0;
    int temp = 28; // not used
    int tempset = 25; // turn on fan temp
    int minmil = 1000; //clock 60000
    int watertime = 8000; //water for 8 seconds =8000
    int co2time = 8000; //water for 8 seconds =8000

    void setup() {
      //Setup all the Arduino Pins
      pinMode(CH1, OUTPUT);//Lights
      pinMode(CH2, OUTPUT);//Water
      pinMode(CH3, OUTPUT);// CO2
      pinMode(CH4, OUTPUT);//FAN
      pinMode(CH5, OUTPUT);//FAN
      pinMode(CH6, OUTPUT);//FAN
      pinMode(CH7, OUTPUT);//FAN
      pinMode(CH8, OUTPUT);
    }

    void loop() {
      int readData = DHT.read11(dataPin); // Reads the data from the sensor
      float t = DHT.temperature; // Gets the values of the temperature
      float h = DHT.humidity; // Gets the values of the humidity
       Serial.print(minutes,2);
     Serial.print(" minutes  ");
     Serial.print(hours,2);
     Serial.print(" hours ");
     Serial.print(days,2);
     Serial.print(" days ");
     Serial.println();

    //int chk = DHT.read11(DHT11_PIN);
     seconds=seconds+1;
       if (seconds >= 59) {
     minutes = minutes + 1;//adds to count
        seconds = 0;
      }
      if (minutes >= 59) {
        hours = hours + 1;
        minutes = 0;
      }
      if (hours >= 23) {
        days = days + 1;
        hours = 1;
      }
      if (days >= 31) {
        days = 1;
      }
      if ((days <= 3) && (hours < 19)) {

        digitalWrite(CH1, LOW);//Lights on for first 3 days 12 hours per Day

      }
      if ((days <= 3) && (hours >= 19)) {

        digitalWrite(CH1, HIGH);//Lights on for first 3 days 12 hours per Day

      }

      if ((days > 3) && (hours < 16)) {

        digitalWrite(CH1, LOW);//Lights on for first 3 days 12 hours per Day

      }
      if ((days > 3) && (hours >= 16)) {

        digitalWrite(CH1, HIGH);//Lights on for first 3 days 12 hours per Day

      }

      if (tempset < t) { // TURN ON FANS IF ABOVE TEMP SET POINT
        digitalWrite(CH4, LOW);//Lights on for first 3 days 12 hours per Day
        digitalWrite(CH5, LOW);//Lights on for first 3 days 12 hours per Day
        digitalWrite(CH6, LOW);//Lights on for first 3 days 12 hours per Day
        digitalWrite(CH7, LOW);//Lights on for first 3 days 12 hours per Day
      }
      if (tempset >= t) { // TURN ON FANS IF ABOVE TEMP SET POINT
        digitalWrite(CH4, HIGH);//Lights on for first 3 days 12 hours per Day
        digitalWrite(CH5, HIGH);//Lights on for first 3 days 12 hours per Day
        digitalWrite(CH6, HIGH);//Lights on for first 3 days 12 hours per Day
        digitalWrite(CH7, HIGH);//Lights on for first 3 days 12 hours per Day
      }

     // if (( (hours % 2) == 0) && (minutes == 30)) { //Water every 2 hours @ 30 minute Mark
    if (minutes == 3) { //Water every 2 hours @ 30 minute Mark
        digitalWrite(CH2, LOW);//
        delay(watertime); //how long water pump is engaged
        minutes = minutes + 1;
      }
      else {
        digitalWrite(CH2, HIGH);//
      }
     // if (( (hours % 2) == 0) && (minutes == 45)) { //CO2 Released every 2 hours @ 45 minute Mark
     if  (minutes == 5) { //CO2 Released every 2 hours @ 45 minute Mark
        digitalWrite(CH3, LOW);//CO2
        delay(co2time); //how long CO2 is released
        minutes = minutes + 1;
      }
      else {
        digitalWrite(CH3, HIGH);// no CO2
      }
      delay(minmil);  // (60000) - 1 minute Delay
    }

Question:  how could we alter the code in order to release co2 every 90 minutes?

title: Need assistance decyphering agriculture systems control code created by absent team member

Answers: 4

body:
There is nothing that happens every 150 minutes!

The `(hours % 2) == 0` would be true every 2 hours.

NOTE this is terrible code! I hope nothing is to dependent on things happening at a definite time, because the internal clock will drift and no allowance is made for the time other code takes to execute.

body:
**Straight answer to the question as asked:**

To make it do this every 90 minutes would be

    if ((hours / 60 + minutes) % 90) == 0) {

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

If you want something to happen every 5 minutes you would write it like this:

    if ((minute % 5) == 0) {

---

I hope you can find someone who can make some improvements on this.  There are much better ways to do it, beginning with a DS3231 Real-Time Clock module.

Good luck with this.

body:
The sketch has so many issues that it's better to start afresh. Dump it. It's worthless. Anyone can rewrite it in 30 minutes while under the influence.

See: you are controlling a grow room with what seems to be 1 KW or more in HID. You can't simply switch ON an HID; you have to be sure that the HID is cold (a waiting period of 5-15 minutes).

The sketch doesn't get time from anywhere. Every time you reset the board, time goes back to zero. Kiss your light schedule goodbye.

You need to control room temperature. If the grow room goes over 30°C, you are in trouble. The minimum you can do is switch OFF the HID to cool things. And if the temp is lower than 20°, better switch OFF the extractor for a while to heat up the room. *Girls* don't like cold.

The sketch has no user interface, no way to set the light schedule, temp limits (among other things).

Replace it with a wall timer:

[![Timer][1]][1]

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

body:
Just about all the comments are lying, mostly from copy paste-code-edit where the comment wasn't edited. It's a great example of why comments should not be used to explain code.

The timing code is full of off-by-one errors. The seconds go from 0 to 58, minutes also goes from 0 to 58, hours goes from 1 to 22, and days goes from 1 to 30.

The comments say that it runs the `loop()` once every minute but instead it's once a second.

There is no hysteresis on the fan control. Which means that in the worst case the fans can cycle on and off every time it runs through `loop()`.

The `CH1`, `CH2`, etc. can be named much better like `RELAY_LIGHT`, `RELAY_WATER`, `RELAY_CO2`, etc. After you do that you won't need the comment on each `digitalWrite`.

Turning off the water and CO2 after they have been activated can be done by setting a timestamp of when to turn it off in the globals and then checking that:

    if (((hours % 3 == 0 && minutes == 0)  ||
        (hours % 3 == 1 && minutes == 30)) && seconds == 0) {
        digitalWrite(RELAY_CO2, LOW);
        CO2RelayOffDays = days;
        CO2RelayOffHours = hours;
        CO2RelayOffMinutes = minutes
        CO2RelayOffSeconds= seconds + CO2_ON_TIME;
        if(CO2RelayOffSeconds >= 60){
            CO2RelayOffSeconds -= 60;
            CO2RelayOffMinutes++;
        }
        if(CO2RelayOffMinutes >= 60){
            CO2RelayOffMinutes -= 60;
            CO2RelayOffHours++;
        }
        if(CO2RelayOffHours >= 24){
            CO2RelayOffHours -= 24;
            CO2RelayOffDays++;
        }
        if(CO2RelayOffDays >=30){
            CO2RelayOffDays -= 30;
        }
    }

    if(days == CO2RelayOffDays && hours == CO2RelayOffHours && minutes == CO2RelayOffMinutes && seconds == CO2RelayOffSeconds){
        digitalWrite(RELAY_CO2, HIGH);
    }

Every 90 minutes means when `hours:minutes` (modulo 3 hours) is equal to `0:00` or `1:30`. But another option is keeping a timestamp of when to turn it on next by adding 1 hour and 30 seconds each time to it you turn it on.

Every 5 minutes is when `minutes%5 == 0`.

You can collect the various timestamps I suggest into a struct each and then provide a function that will wrap everything appropriately.

    void wrapTimestamp(TimeStamp *timestamp){
        if(timestamp->seconds >= 60){
            timestamp->seconds = timestamp->seconds`;
            timestamp->minutes += timestamp->seconds/60;
        }
        if(timestamp->minutes >= 60){
            timestamp->minutes = timestamp->minutes`;
            timestamp->hours +=timestamp->minutes/60;
        }
        if(timestamp->hours >= 24){
            timestamp->hours = timestamp->hours$;
            timestamp->days +=timestamp->hours/24;
        }
        if(timestamp->days >=30){
            timestamp->days = timestamp->days0;
        }
    }

You should consider adding a real-time-clock module that will have much less drift than delay.


body:
I am trying to update values to Firebase. According to Firebase:

<!-- language: lang-sh -->

    curl -X PUT -d '{ "first": "Jack", "last": "Sparrow" }' \
      'https://[PROJECT_ID].firebaseio.com/users/jack/name.json'

We can update using put command. Using curl works fine, but when I look at the header of `ESP8266HTTPClient`, I don't see any `put` or `patch` method there.

I can only see the following:

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

    int GET();
    int POST(uint8_t * payload, size_t size);
    int POST(String payload);

Whereas in NodeMCU documentation, it is clearly stated it supports the `put` method too.

<!-- language: lang-lua -->

    http.put(url, headers, body, callback)

[`http.put()` documentation][1]

I cannot find any example.

How can I implement the `put` method in NodeMCU?

  [1]: https://nodemcu.readthedocs.io/en/master/en/modules/http/#httpput

title: HTTP PUT method on NodeMCU

Answers: 1

body:
pardon me if i asked too soon. I found the answer.
all verb are supported. but `post` and `get` got their own names.

     int httpCode = http.sendRequest("PUT", String(data));

enven post method implement the sendRequest.


body: Is there an similar function in AVR-libc/Arduino C++ to mmap()? I'm looking for a way to place machine code in memory at runtime and make it executable.

title: Equivalent to POSIX mmap() in AVR-libc

Answers: 1

body:
No.

First, mmap() makes almost no sense on an AVR, as there's no memory management unit or concept of process memory to configure.  Some related concepts like sbrk() are occasionally implemented in a minimalist fashion to let library functions designed for larger computers work, but they typically only update a tracking variable or fail.  For things that are physically realizable you can write your own mmap() if you really want, either allowing (assigning) or disallowing a region, and even if you really want automatically copying part of a file off an SD card or whatever...

But more importantly, your actual goal is entirely unachievable, as the AVR is a strict Harvard Architecture which **can only execute instructions from flash**, never from RAM.

If you want to execute from RAM, try one of the various small ARM Cortex M0/M4/M3 platforms (many of which have Arduino ports), or even consider a larger Embedded Linux system, which will not necessarily be any more expensive than an Arduino.


body:
I have a Wemos D1 mini that's connected to a pc with usb, I want to be able to sleep the pc and wake it up programmatically.

Is there a way to do this? Like sending a simulated sleep keyboard button press?

Maybe I can send a wake up on lan command from the Wemos since they both are connected to the same router, but I'm still more interested in sending a sleep command.

I found [this][1] but it's old and it looks like they don't really have a way to do it.

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

title: Arduino/ESP8266 to put PC to sleep and wake it up

Answers: 2

body:
**Sleep**

If this is a Windows PC and you can write a WIN32 C++ program then you can look at the `WH_KEYBOARD_LL()` function and use that to inject the "sleep key", but I'm not sure the "sleep key" isn't an OEM key which might make things difficult.

You could also look at sending a remote command (shutdown) over the network, but you'd have some hefty protocols to implement.  Unless you had a service on your PC that listened to the serial connection and waited for the device to send a sleep command to it over that and converted it into a system call.  The same will work with a Linux Daemon.

**Wake Up**

You can get Windows (don't know about Linux) to let a USB device wake it up, but I don't know if you could get a Arduino/ESP to send the correct signals.

Like The great Majenko says WoLAN is an option, but difficult to achieve.

My preferred option would be to splice a wire into the power button of the PC in parallel (so you can still use the button) and control that with a relay.  That should give you a Wifi enabled power switch, but you need to check how the switch works and mimic it properly.  I would try it with an old, almost dead, worthless PC first if I was you.

body:
The hardware interface would be the easiest like others were saying.
Here is a project someone else shared that does that.

https://www.hackster.io/zvonko-bockaj/wemos-esp8266-remote-pc-switch-062c7a

The wake-on-lan part is easy and here is some code for that.

https://github.com/koen-github/WakeOnLan-ESP8266

I'm also interested in sending some kind of RPC call to a system (linux/windows/mac) via wifi to initiate a shutdown.  If I find a solution I will post it here.

UPDATE: I found a Sleep-On-Lan project that should work.  You can use the same code above for the ESP8266 but just reverse the MAC Address of the system you want to shutdown.

https://github.com/SR-G/sleep-on-lan

You will need to run this as a service on the system you intend to put to sleep.  There is a windows and linux version.  They didn't mention mac but I bet it will compile and run on a mac too.  :)

I hope this helps.  I will probably use this myself in the future.


body:
Please examine the following code.

    volatile uint8_t myVar;

    void setup() {
      attachInterrupt(digitalPinToInterrupt(2), isr, FALLING);
      Serial.begin(115200);
    }

    void loop() {
      myVar = 0;
      while (myVar != 5) {
      }
      Serial.println("ISR called");
    }

    void isr() {
      myVar = 5;
    }

From this code, I expect that every time the pin 2 is falling, I get one single print statement `ISR called`.

However, when dropping the voltage on pin 2 ONCE, the serial monitor shows `ISR called` TWICE.

Why is this? This is a simplified, stripped-down example of the problem I am facing with my current project.

Edit:
After reading the comments, here is a bit more info. I am using a 64-button shield that is triggering the interrupt. The process is time critical since I am measuring the time it takes for the button to be pressed (I am testing people's reflexes). I will add a print statement in the interrupt to see how many times it gets called. However, I believe the interrupt is only getting called once per buttonPressed.

Thank you for your help!

title: Interrupt volatile variable doesn't work as expected

Answers: 1

body:
Turns out, the 64 button shield calls the interrupt TWICE. Once when the button is pressed and once when it is released.

Thank you for everyone's help!


body:
Recently I bought an Arduino M0 board and I'm using it in one of my projects, which logs GPS data into an SD card.

Can an Arduino M0 be programmed as a USB SD Card reader? So that I don't have to remove the SD card from the system and use the same USB port from M0 to see the contents of the SD card directly on my computer.

title: View Arduino M0 SD card content on a computer

Answers: 1

body:
Yes, in at least some way, but what is realizable and best depends on a few things.

- A traditional "card reader" is a USB Mass Storage device which basically exports the logical blocks of the card to the USB host computer.  While this is active, nothing on the embedded system may interact with the card.  The embedded system will need a USB device port which can operate in this mode, suitable software, and whatever data is recorded on the card will need to be a in a filesystem (FAT or whatever) that the host PC can read, and a data format in the files that existing or custom software for that PC can make sense of.

- A different option would be to still store data on the card in a way that would be PC-compatible if the card were removed and placed in a PC, but not to be a USB Mass Storage device.  Instead, you might use the existing quasi-serial interface that is the typical role of an Arduino-type board's USB port, to send or summarize the data, either directly or by interpreting it first.  This could either flow into a simple terminal program, or into something custom.  Typically this means less work on the Arduino side, more but more work on the PC side.  Additionally, since there is never a direct export of the card's block, the embedded system continues to have access to the card the whole time, rather than having to surrender control of the card to the PC operating system as USB Mass Storage requires.

- A variation of the above could leverage the fact that if only the Arduino ever reads the card for its own purposes or to report the data to a PC, it doesn't necessarily need to store things in a PC compatible file system, or even in a file system at all.


body:
#Firmware version
    AT+GMR

    AT version:0.21.0.0
    SDK version:0.9.5

    OK

#Connection

    ESP8266(ESP-01) <> Arduino Uno
    GND  <> GND
    3V3 <> 3.3V
    EN(CH_PD) <> 3.3V
    TX  <> D2
    RX <>  D3

ps) I know I must not connect `RX` directly to `Arduino's D3`.
When I `level down` `ESP8266's RX` `5V` to `3.3V`, `ESP8266` didn't work.
But when `directly`, It works well.
I supply power to `Arduino Uno` and `ESP8266` by `usb` from `PC`.

#Arduino Code

        #include <SoftwareSerial.h>
        #include <ESP8266.h>        //다운 후 libraries폴더에 저장한 라이브러리

        SoftwareSerial esp8266Serial = SoftwareSerial(2, 3);
        ESP8266 wifi = ESP8266(esp8266Serial);

        #define SSID "MYSSID"
        #define PWD "MYPWD"

        void setup() {
          Serial.begin(9600);
          esp8266Serial.begin(9600);  // ESP8266

          wifi.begin();
          wifi.setTimeout(1000);

          // test
          Serial.print("test: ");
          Serial.println(getStatus(wifi.test()));

          // restart
          Serial.print("restart: ");
          Serial.println(getStatus(wifi.restart()));
          Serial.print("quitAP: ");
          Serial.println(getStatus(wifi.quitAP()));

          // joinAP
          Serial.print("joinAP: ");
          Serial.println(getStatus(wifi.joinAP(SSID, PWD)));

          // getAP
          Serial.print("getAP: ");
          Serial.println(getStatus(wifi.getAP(SSID)));

          // getIP
          Serial.print("getIP: ");
          IPAddress ip;
          Serial.println(getStatus(wifi.getIP(ESP8266_WIFI_STATION, ip)));
          Serial.print("IP: ");
          Serial.println(ip);

          // connect with webserver

          Serial.print("connect: ");
          Serial.println(getStatus(wifi.connect(ESP8266_PROTOCOL_TCP, IPAddress(192, 168, 0, 52), 3000)));
          getConnectionStatue(wifi);

          // send to webserver
          Serial.print("send: ");

          Serial.println(getStatus(wifi.send("GET /?id=arduino HTTP/1.0\r\nHost: http://192.168.0.52:3000\r\n\r\n")));
        }

        void loop()
        {
          // read data
          unsigned int id;
          int length;
          int totalRead;
          char buffer[11] = {};
          if ((length = wifi.available()) > 0) {
            id = wifi.getId();
            totalRead = wifi.read(buffer, 1000);
            if (length > 0) {
              Serial.println((char*)buffer);
            }
          }
        }

        void getConnectionStatue(ESP8266 wifi) {
          // getConnectionStatus
          ESP8266ConnectionStatus connectionStatus;
          ESP8266Connection connections[5];
          unsigned int connectionCount;
          Serial.print("getConnectionStatus: ");
          Serial.print(getStatus(wifi.getConnectionStatus(connectionStatus,                                         connections, connectionCount)));
          Serial.print(" : ");
          Serial.println(connectionCount);
          for (int i = 0; i < connectionCount; i++) {
            Serial.print(" - Connection: ");
            Serial.print(connections[i].id);
            Serial.print(" - ");
            Serial.print(getProtocol(connections[i].protocol));
            Serial.print(" - ");
            Serial.print(connections[i].ip);
            Serial.print(":");
            Serial.print(connections[i].port);
            Serial.print(" - ");
            Serial.println(getRole(connections[i].role));
          }
        }

        String getStatus(bool status)
        {
          if (status)
            return "OK";

          return "KO";
        }

        String getStatus(ESP8266CommandStatus status)
        {
          switch (status) {
            case ESP8266_COMMAND_INVALID:
              return "INVALID";
              break;

            case ESP8266_COMMAND_TIMEOUT:
              return "TIMEOUT";
              break;

            case ESP8266_COMMAND_OK:
              return "OK";
              break;

            case ESP8266_COMMAND_NO_CHANGE:
              return "NO CHANGE";
              break;

            case ESP8266_COMMAND_ERROR:
              return "ERROR";
              break;

            case ESP8266_COMMAND_NO_LINK:
              return "NO LINK";
              break;

            case ESP8266_COMMAND_TOO_LONG:
              return "TOO LONG";
              break;

            case ESP8266_COMMAND_FAIL:
              return "FAIL";
              break;

            default:
              return "UNKNOWN COMMAND STATUS";
              break;
          }
        }

        String getRole(ESP8266Role role)
        {
          switch (role) {
            case ESP8266_ROLE_CLIENT:
              return "CLIENT";
              break;

            case ESP8266_ROLE_SERVER:
              return "SERVER";
              break;

            default:
              return "UNKNOWN ROLE";
              break;
          }
        }

        String getProtocol(ESP8266Protocol protocol)
        {
          switch (protocol) {
            case ESP8266_PROTOCOL_TCP:
              return "TCP";
              break;

            case ESP8266_PROTOCOL_UDP:
              return "UDP";
              break;

            default:
              return "UNKNOWN PROTOCOL";
              break;
          }
        }

#Response
        test: OK
        restart: OK
        quitAP: OK
        joinAP: TIMEOUT
        getAP: OK
        getIP: OK
        IP: 192.168.0.55
        connect: OK
        getConnectionStatus: OK : 1
         - Connection: 0 - TCP - 192.168.0.52:3000 - CLIENT
        send: OK

There is no response
On server, the request ESP8266 sent didn't come.
I have no Idea...........

#Addition
I send AT commands directly to ESP8266 by Arduino IDE
##connection
    ESP8266(ESP-01) <> Arduino Uno
    GND  <> GND
    3V3 <> 3.3V
    EN(CH_PD) <> 3.3V
    TX  <> TX
    RX <>  TX

##response
    AT

    OK
    AT+CIPSTART="TCP","192.168.0.52",3000

    CONNECT

    OK
    AT+CIPSEND=74

    OK
    > GET /?id=arduino HTTP/1.0\r\nHost:http://192.168.0.52:3000\r\n\r\n

    busy s...

    SEND OK
    CLOSED

---
    AT+CIPSTART="TCP","192.168.0.52",3000

    CONNECT

    OK
    AT+CIPSEND=39

    OK
    > GET http://192.168.0.52/id?=arduino\r\n\r\nbusy s...

    SEND OK
    CLOSED

---
    AT+CIPSTART="TCP","192.168.0.52",3000

    CONNECT

    OK
    AT+CIPSEND=39

    OK
    > GET http://192.168.0.52/id?=arduino\r\n\r\n
    busy s...

    SEND OK

Sometime connection `CLOSED` after sending the request, sometime connection alive.

title: Arduino Uno, ESP8266 HTTP request have no response

Answers: 0


body:
Edit: I have found out that it was something wrong with the cables. I have solved the problem. Thanks for everyone who tried to help.

I am working a project that should basically do:

 1. Read the RFID card UID.
 2. Get the selection from user using pushbuttons.
 3. Restart the code for new cards.

**The problem is, It reads the card and gets the input from pushbuttons. But after the first loop, It doesn't detect other cards (or the same card again).** Here is my code: (I am using miguelbalboa's MFRC522 library and Arduino UNO)

    #include <MFRC522Hack.h>
    #include <MFRC522Extended.h>
    #include <deprecated.h>
    #include <MFRC522Debug.h>
    #include <require_cpp11.h>
    #include <MFRC522.h>

    // protype 1 copy
    #include <SPI.h>

    // Define pin numbers for mfrc522
    #define SS_PIN 10
    #define RST_PIN 9
    #define BLUE_BUT A0
    #define RED_BUT A1

    // Define pin numbers for lcd
    const int RS = A0 , EN = A1 , D4 = A5 , D5 = A4 , D6 = A3 , D7 = A2;
    int uids[] = {14805 ,25673};
    int votedArray[] = {};
    String uidNames[] = {"WHITE" , "BLUE"};
    // Create LCD and MFRC522 instances
    MFRC522 mfrc522(SS_PIN , RST_PIN);

    unsigned long getCardID(int showCardData = 0){
      /* this function gets the uid of the rfid card
       and returns the uid in unsigned long format */
      /* this fn. should be called with argument 1
      if printing the card data to the serial monitor
      is needed. */

      unsigned long UID_unsigned;
       UID_unsigned =  mfrc522.uid.uidByte[0] << 24;
       UID_unsigned += mfrc522.uid.uidByte[1] << 16;
       UID_unsigned += mfrc522.uid.uidByte[2] <<  8;
       UID_unsigned += mfrc522.uid.uidByte[3];

      if(showCardData==1){
      Serial.println("UID Unsigned int");
      Serial.println(UID_unsigned);

      String UID_string =  (String)UID_unsigned;
      long UID_LONG=(long)UID_unsigned;

      Serial.println("UID Long :");
      Serial.println(UID_LONG);

      Serial.println("UID String :");
      Serial.println(UID_string); } // print card data to the serial monitor
    int UID_int = (int) UID_unsigned;
     return UID_int;

     }

    void showCardData(){
      /* this fn. calls getCardID function
      with argument 1 to print the data to
      the serial monitor (kind of shortcut)*/
      getCardID(1);
    }

    int findInList(int uid , int uidArray[]){
      /* this fn. returns the index of the uid in the array if found,
      returns -1 if not found*/
      int numOfElements = sizeof(uidArray)/sizeof(uidArray[0]); // calculate the num.of elem. in array
      for (int i = 0 ; i <= numOfElements ; i++) {
        if(uid == uidArray[i]){
          return i; // if element is found in the array, return true
        }
      }
      return -1;
    }

    String getCardName(int cardUID){
      int UIDIndex = findInList(cardUID , uids);

      if(UIDIndex == -1){
        return "ERROR";
        }

      else {
        String cardName = uidNames[UIDIndex];
        return cardName;
        }

    }

    void printCardName(int cardUID){
      String cardName = getCardName(cardUID);
      if(cardName == "ERROR"){
        Serial.print("ERROR! CARD UID: ");
        Serial.println(cardUID);
        }

      else {
        Serial.print("CARD NAME: ");
        Serial.println(cardName);
        }
    }

    void setup() {
      Serial.begin(9600); // Init. serial comm. with the PC
      SPI.begin(); // Init. SPI bus for MFRC522
      mfrc522.PCD_Init(); // Init. MFRC522 card
      pinMode(BLUE_BUT , INPUT);
      pinMode(RED_BUT , INPUT);
    }

    void loop() {

        // Look for new cards
      if ( ! mfrc522.PICC_IsNewCardPresent()){
      Serial.println("CARD NOT PRESENT");
        return;
     }

      // Verify if the NUID has been readed
      if ( ! mfrc522.PICC_ReadCardSerial()) {

        Serial.println("CARD NOT read");
        return;  }

      int cardUID = getCardID();

      Serial.println("CARD UID READ");
      printCardName(cardUID);

      Serial.println("SELECT WITH BUTTONS");

    //getVote(cardUID);
      int blueState = LOW , redState = LOW ;
      while(1) {
       blueState = digitalRead(BLUE_BUT);
       redState = digitalRead(RED_BUT);

      if(blueState == HIGH){
        Serial.println("BLUE");

        break;
        }

      if(redState == HIGH){
        Serial.println("RED");
        mfrc522.PICC_HaltA();
    mfrc522.PCD_StopCrypto1();
        break;
        }

      }

    Serial.println("PROGRAM COMPLETE");

    }

I have already tried adding

        mfrc522.PICC_HaltA();
        mfrc522.PCD_StopCrypto1();
but didn't help.

And here is the screenshot of the Serial Monitor after reading the first card and getting the button input.
[![Serial Monitor][1]][1]

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

I have checked the similar problems, but the solutions didn't help me.

title: MFRC522 won't detect cards after the first loop

Answers: 1

body: I assume, `Buttons` and `RFID reader` both connected to the 3.3v pin on arduino. Move buttons to the 5v, leave RFID on 3.3v alone.


body:
I'm try to connect my Arduino Mega 2560 to PC, but I think it's not easy as I imagine. I spent a lot's of time to install USB driver. Here is a screenshot:

[![Device manager][1]][1]

When I try to upload blink example, Arduino IDE throw this error:

    Sketch uses 656 bytes (0%) of program storage space. Maximum is 253952 bytes.
    Global variables use 9 bytes (0%) of dynamic memory, leaving 8183 bytes for local variables. Maximum is 8192 bytes.
    avrdude: ser_open(): can't set com-state for "\\.\COM10"
    avrdude: ser_drain(): read error: The handle is invalid."

[![Screenshot of error][2]][2]

Please help to run one simple example.

I think this screen may help to understand my problem:

[![COM port selection][3]][3]

  [1]: https://i.stack.imgur.com/tCFGp.jpg "Device manager"
  [2]: https://i.stack.imgur.com/HZcOH.jpg "Screenshot of error"
  [3]: https://i.stack.imgur.com/N9AKX.jpg "COM port selection"

title: Why Arduino Mega 2560 throw error when i try to upload example

Answers: 3

body:
What you can try is:

- Use another USB port
- Reopen IDE
- Reinsert the USB cable
- Use a different USB cable
- Prevent using a USB 'box' in between
- Try a different 2560 (if you have)
- Restart computer
- Check if it can be found in the system drivers
- Reinstall IDE (after deinstall it).

However, as the author already mentioned the real solution is needed for some non-genuine Arduinos:

- Install the CH driver e.g. at wch.cn/download/CH341SER_EXE.html

body:
I install driver for this site and everything is working well.
driver download:  wch.cn/download/CH341SER_EXE.html

I'm recommend to unplug arduino first and install driver, after that plug and enjoy.

Here is a video:
https://www.youtube.com/watch?v=FhmG5J-AHrg

body: I also got the same error. Then I un-plugged my connections and pressed the reset button. Then I uploaded the default blink example to my board. Then it's working fine. Then again I made a connection to the board and it shows the same error again. Now, I un-plugged the GND pin; it's working again. So, in my case there was some thing wrong with my connections.


body:
I am trying to connect a CDC communication device to the Leonardo USB port and have communication with it via the TTL com port. Basically I want to echo to the TTL port whatever is transmitted over USB and vice-versa.

ASCII data is transmitted out the USB from the CDC device into the USB port of the Leonardo Aurduino. The Arduino needs to *xtransfer* this info over to the UART pins D0 (RX) and D1 (TX) that are connected to the UART of another micro-controller. I should be able to test it by connecting an FTDI TTL-RS232 cable and see results and have comms in my terminal program.

I came across this sketch that appears to be basically what I want, but I think the "hosting" portion is not being set up:

    void setup() {
      Serial.begin(9600);  // rx/tx pins
      Serial1.begin(9600); // USB port
      Serial1.write("2nd Version");
    }

    void loop() {
      // copy from virtual serial line to UART and vice-versa
      if (Serial.available()) {
        char c = (char)Serial.read();
        Serial1.write(c);
      }
      if (Serial1.available()) {
        char c = (char)Serial1.read();
        Serial.write(c);
      }
    }

What am I missing? Note I am NOT trying to do HID but CDC. Basically I want to eliminate using a PC as a Host device and use the "bridge" between my CDC device and another micro-controller.

title: Can the Leonardo Arduino be used as a USB HOST for CDC Com devices?

Answers: 1

body:
No, the Leonardo cannot be a USB Host. You may be able to use a USB Host Shield in conjunction with the Leonardo, though I have never tried it and cannot vouch for compatibility with the Leonardo.

USB is a host->device protocol, not a peer-to-peer protocol. You cannot just connect two devices together. Only a USB Host can communicate with a USB device.


body:
I am trying to send some messages from nodeMCU to Arduino using Serial communication (aka UART). Following is the code on nodeMCU side:

    #include <ESP8266WiFi.h>

    const char* ssid = "my-ssid"; // SSID i.e. Service Set Identifier is the name of your WIFI
    const char* password = "my-pasword"; // Your Wifi password, in case you have open network comment the whole statement.

    int ledPin = 13; // GPIO13 or for NodeMCU you can directly write D7
    WiFiServer server(80); // Creates a server that listens for incoming connections on the specified port, here in this case port is 80.

         void setup() {
              Serial.begin(115200);
              delay(10);

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

              // Connect to WiFi network
              WiFi.begin(ssid, password);
              //Trying to connect to wifi
              while (WiFi.status() != WL_CONNECTED) {
                delay(500);
              }
              Serial.println("$Wifi Connected#");
              server.begin();
            }

            void loop() {
              // Check if a client has connected
              WiFiClient client = server.available();
              if (!client) {
                return;
              }

              // Wait until the client sends some data
              while(!client.available()){
                delay(1);
              }
              // Read the first line of the request
              String request = client.readStringUntil('\r');
              client.flush();

              int value = LOW;
              if (request.indexOf("/LED=ON") != -1)  {
                digitalWrite(ledPin, HIGH);
                Serial.println("$Led High#");
                value = HIGH;
              }
              if (request.indexOf("/LED=OFF") != -1)  {
                digitalWrite(ledPin, LOW);
                Serial.println("$Led Low#");
                value = LOW;
              }

              // Return the response
              client.println("HTTP/1.1 200 OK");
              client.println("Content-Type: text/html");
              client.println(""); //  do not forget this one
              client.println("<!DOCTYPE HTML>");
              client.println("");

              client.print("Led pin is now: ");

              if(value == HIGH) {
                client.print("On");
              } else {
                client.print("Off");
              }
              client.println("

");
              client.println("<button>Turn On </button>");
              client.println("<button>Turn Off </button>
");
              client.println("");
              delay(1);
            }

Following is the code on Arduino side:

    String msgFromNodeMCU;
    void setup() {
      pinMode(13,OUTPUT);
      Serial.begin(115200);
    }

    void loop() {
      msgFromNodeMCU=Serial.readString();
      Serial.println(msgFromNodeMCU);
    }
which was working fine until I modified that code to:

    String msgFromNodeMCU;

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

    void loop() {
      msgFromNodeMCU=Serial.readString();
      delay(10);
      String wifi_connected="$Wifi Connected#";
      String led_High="$Led High#";
      String led_Low="$Led Low#";
        if (msgFromNodeMCU.equalsIgnoreCase(wifi_connected)) {
          Serial.println("Wifi Connected");
          delay(10);
        }
        if (msgFromNodeMCU.equalsIgnoreCase(led_High)) {
          digitalWrite(13,HIGH);
        }
        if (msgFromNodeMCU.equalsIgnoreCase(led_Low)) {
          digitalWrite(13,LOW);
        }
    }

With this code, I see no "Wifi Connected" message on my Serial monitor and there is no response on pin 13. This implies msgFromNodeMCU is not heard. What can I do for msgFromNodeMCU to be heard? Any sort of help is highly appreciated. :D

title: Problem in Serial Communication between nodeMCU and arduino

Answers: 0