body:
I am working on a project with LED strips that would consume 12V and 20A. The problem is that the household wall outlet limitation is 15A, and 20A current draw would potentially start a fire. I have been searching for tutorials of large current LED project, and none of them really addresses the current draw problem.

I found an adequate power supply. It is Meanwell RSP-320-12. [http://www.mouser.com/ProductDetail/Mean-Well/RSP-320-12/?qs=Uzd/wh%2bZzhBChmc2p7rgKQ==][1].

How can I make it work with a 15A wall outlet limitation?

Thanks in advance!

  [1]: http://www.mouser.com/ProductDetail/Mean-Well/RSP-320-12/?qs=Uzd/wh%2bZzhBChmc2p7rgKQ==

title: Current Draw for LED Projects

Answers: 2

body:
Drawing 20A on 12V means 240W which on 110V is 1A and a bit (a bit more once you consider efficiency of the conversion).

The [spec sheet][1] of the power supply you linked says that it will draw 2.7A max on a 115V input.

The power supply will convert the high voltage low amps into low voltage high amps.

  [1]: http://meanwellusa.com/productPdf.aspx?i=455#1

body:
The power outlet is either 110V AC or 230/240V AC. Ignoring modern Switch-mode power supplies, to convert the power outlet voltage down to 12V, you first need to step down the voltage (using a transformer) and then rectify the AC voltage to DC voltage.

Working backwards, to get 12V DC you need: `12 x square_root(2) = 16.97 V AC`.

A transformer can step down AC voltage. For example it can step down 110V AC down to 16.97 V AC.

The formula for an ideal transformer is:

    V x i (primary side) = V x i (secondary side)

And using this to find the current draw on the primary side:

    110 x i (primary side) = 16.97 x 20 (secondary side)

    i (primary side) = 16.97 x 20 / 110

    i (primary side) = 3.08 A

So if you have an outlet that provides 110 V AC then an ideal AC-DC converter would draw 3.08 A.


body:
I am trying to use a on-off switch with the ESP8266 to change whether GPI02 is HIGH or LOW. I am using GPIO3 as input. My circuit looks like this:

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

The red area to the right is a relay, I wasn't sure how to make it work in fritzing but I am sure that it is wired correctly, it just has a signal, +, and -, pin. The more important stuff is happening with the ESP8266. First, here is the code:

    /*
      This a simple example of the aREST Library for the ESP8266 WiFi chip.
      This example illustrate the cloud part of aREST that makes the board accessible from anywhere
      See the README file for more details.

      Written in 2015 by Marco Schwartz under a GPL license.
    */

    // Import required libraries
    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    #include <aREST.h>

    // Clients
    WiFiClient espClient;
    PubSubClient client(espClient);

    // Create aREST instance
    aREST rest = aREST(client);

    // Unique ID to identify the device for cloud.arest.io
    char* device_id = "ew1zard";

    // WiFi parameters
    const char* ssid = "MaisonBlanche";
    const char* password = "7932gLBw";

    // Functions
    void callback(char* topic, byte* payload, unsigned int length);

    void setup(void)
    {
      // Set input / output pin
      pinMode(3, INPUT);
      pinMode(2, OUTPUT);
      //pinMode(2, OUTPUT);
      //digitalWrite(3, 0);

      // Start Serial
      Serial.begin(115200);

      // Set callback
      client.setCallback(callback);

      // Give name & ID to the device (ID should be 6 characters long)
      rest.set_id(device_id);
      rest.set_name("esp8266");

      // Connect to WiFi
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected");

      // Set output topic
      char* out_topic = rest.get_topic();
    }

    void loop() {

      // Connect to the cloud
      rest.handle(client);

      int read3 = digitalRead(3);
      Serial.println(read3 + " input");
      digitalWrite(2, read3);

    }

    // Handles message arrived on subscribed topic(s)
    void callback(char* topic, byte* payload, unsigned int length) {

      Serial.println("request from interwebs");
      rest.handle_callback(client, topic, payload, length);

    }

The output of the `Serial.println` is always `input` (there is no HIGH or LOW or 1 or 0, or whatever it should be, before the input. I have verified that the switch is working. In the `on` position it is sending `3.3v` to GPIO3 (I have measured it with my multimeter) and still the input never changes. In the `off` position it sends 0v and the ESP8266 just acts as if there is nothing to read it seems. Since I am using this with `aREST` and you can set the mode of pins through that, I thought maybe I had to set the `pinMode` with the `aREST` request `cloud.arest.io/xxxxx/mode/3/i` and it verifies with a JSON response that the pin is being set to input, but still no reading. Do I not have the ESP8266 wired correctly for this? Maybe I need some pull-ups/pull downs or I can't use the pins in the configuration I am using them? One other thing, when I set the input pin with aREST, it turns on the relay (sending something through GPIO2 for some reason). If I don't set the input with `aREST` the relay stays off.

**UPDATE**
I tried with this code to rule out that it might be `aREST`:

    void setup() {
      // put your setup code here, to run once:
      pinMode(3, INPUT);
      pinMode(2, OUTPUT);

      // Start Serial
      Serial.begin(115200);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      int read3 = digitalRead(3);
      Serial.print(read3);
      Serial.println(" input");
      digitalWrite(2, read3);
    }

It always outputs `0 input`, the ESP8266 seems to be ignoring that input pin.

**UPDATE**
I am now trying with GPIO0 as input. I have the switch wired to ground, and it leads to GPIO0. When I turn it on, GPIO0 reads `1` (on), then I use the switch and it turns the relay off correctly, then I try and turn it on again, and nothing happens, GPIO0 continues to be read at `0`. So I can't use the switch past the initial `off`.

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

title: digitalRead not reading input pin of ESP8266-01

Answers: 3

body:
The expression `read3 + " input"` performs pointer arithmetic, i.e. you either add 0 or 1 to the start adress of `" input"`, so you get either `" input"` or `"input"`. Does the leading space disappear when pressing the button?

To correct your code you can print the number separately:

    Serial.print(read3);
    Serial.println(" input");

You should get rid of the rest and pub-sub code. You can add this later after having solved the problem with the button.

Also note that GPIO03 uses the same pin as RX. The docs state the following:

    Serial uses UART0, which is mapped to pins GPIO1 (TX) and GPIO3 (RX).

So it should work after disabling Serial and after providing a pull down resistor. The resistor is needed to prevent having a floating input.

body:
There are certain pins that output a 3.3V signal when the ESP8266 boots. This may be problematic if you have relays or other peripherals connected to those GPIOs. The following GPIOs output a HIGH
signal on boot: GPIO1, GPIO3, GPIO9, GPIO10. GPIO3:  pin must high at BOOT and is pulled up to that position. I have no idea what will happen if low at that point.  Since I2C I/O modules are cheep I use them and do not worry about the rest of the pins. Not the cheapest but keeps me out of trouble. It makes my life a bit easier as well as I pull up the I2C lines to the 3.3V and connect the PCF8574 to 5 Volts. No problem as the SCL and SCI are by definition Open Drain or Open Collector (Bipolar parts). This made my first try with a LCSD work first shot. I tried the 3.3V and it would not work.

body: The issue occurs when you try to use the RX port (3) and you also define Serial.begin. This is double dipping. You can only use the RX/TX as a single unit of digital or serial communication.


body:
I'm using an Arduino uno with a SIM900 GSM shield.  I'm trying to connect the Arduino to my (ASP MVC) website.  I've written an API which i've successfully tested with postman, and whilst the GET Command works fine, I've had no success with POSTING data as yet.  Using the arduino to echo serial monitor input, I've done the following...

So, some setup commands

        AT+CGATT?
        AT+SAPBR=3,1,"CONTYPE","GPRS"
        AT+SAPBR=3,1,"APN","internet"    (vodafone UK parameters
        AT+SAPBR=3,1,"USER","web"
        AT+SAPBR=3,1,"PWD","web"
        AT+SAPBR=1,1
        AT+SAPBR=2,1     (confirms i have an IP address)

i then do the following...

        AT+HTTPINIT
        AT+HTTPPARA="CID",1
        AT+HTTPPARA="PROIP","212.183.137.12"   (vodafone uk proxy settings)
        AT+HTTPPARA="PROPORT","8799"
        AT+HTTPPARA="CONTENT","application/json"
        AT+HTTPPARA="URL","http://mywebsite.co.uk/api/obs"
        AT+HTTPDATA=83, 10000    (gives the download command).
        {"SensorName": "TestSensor", "ObsValue": 31, "ObsDateTime": "2017-10-01T03:30:00"}
        AT+HTTPACTION=1
and I just get an "OK" back, no httpaction response, and no data stored on the database.

Is there anything I'm doing that is obviously wrong?  Does HTTPACTION come before the data?

Are there commands I can use to check the status of my http session on the GSM board? to confirm that my settings are correct?

Finally, I keep getting messages like

        +CREG: 1,"002A","0F48"
Always the 1 (presumably the CID i'm using), and always the 002A, but the final part varies.

Any help would be hugely welcome.  Thanks.

title: Posting data to ASP web service from GSM using AT commands - where am I going wrong

Answers: 1

body:
>     +CREG: 1,"002A","0F48"

That's the registration status. "1" is "Registered on your 'home' network", "002A" is your LAC (Location Area Code) and "0F48" is the Cell ID (CI).


body:
I am new to arduino and I am trying to build an interface for my flight simulator. I am using a plugin for the simulator software which returns a float variable to my arduino, which I then want to display on a series of 7-segment displays. I have connected three max7219 modules, each with 8 digits.

I found the LedControl library which I managed to get to display on my modules like this:

    #include <LedControl.h>

    // inputs: DIN pin, CLK pin, LOAD pin. number of chips
    LedControl mydisplay = LedControl(48, 44, 46, 3);

    void setup() {
      mydisplay.shutdown(0, false);  // turns on display
      mydisplay.shutdown(1, false);  // turns on display
      mydisplay.setIntensity(0, 7); // 15 = brightest
      mydisplay.setDigit(0, 0, 9, false);
      mydisplay.setDigit(0, 1, 8, false);
      mydisplay.setDigit(0, 2, 7, false);
      mydisplay.setDigit(0, 3, 6, false);
      mydisplay.setDigit(0, 4, 5, true);
      mydisplay.setDigit(0, 5, 4, false);
      mydisplay.setDigit(0, 6, 3, false);
      mydisplay.setDigit(0, 7, 2, false);

      mydisplay.setDigit(1, 0, 9, false);
      mydisplay.setDigit(1, 1, 8, false);
      mydisplay.setDigit(1, 2, 7, false);
      mydisplay.setDigit(1, 3, 6, false);
      mydisplay.setDigit(1, 4, 5, true);
      mydisplay.setDigit(1, 5, 4, false);
      mydisplay.setDigit(1, 6, 3, false);
      mydisplay.setDigit(1, 7, 2, false);

    }

    void loop() {
    }

The arduino code however for the plugin I am using has this function:

    void ProgOut(byte id, float val) {

      if (id == 1)
      {
           // print this to display
      }
    }

So my question is, right now based on the LedControl test sketch, I have to display each individual character one by one, but I receive a float variable.. so how can I just do something like "mydisplay.set(floatvariable)" ?

title: Writing a value to 7-segment max7219 displays

Answers: 1

body:
> how can I just do something like "mydisplay.set(floatvariable)" ?

write your own code.

let's say that you want to display up to two decimal points. Multiply the float vary by 100, save it into an int variable, and utilize the existing code to display that integer variable + decimal point at the right digit.


body: I'm trying to use an Arduino to switch a monitor's power on and off. I'm going to wire the Arduino to the monitor's power switch. I've tested the power switch with a multimeter, and when pressed, there is a 3.3V current running through it that triggers the power on and off. The monitor itself is takes 12VDC to power. I know that a relay is used when switching larger power sources from a low voltage source so as not to damage the lower voltage source, but since the switch in question only runs at 3.3V would it be safe to use the Arduino without a relay?

title: Do I need a relay to control a monitor's power with an Arduino?

Answers: 1

body:
It's always better to use MOSFET as a switch (or relay) like this:

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

It can handle loads up to 24V, 5A. The load is powered from an external supply. It is based on a IRF520 Mosfet and cost 0.55 a piece in Aliexpress. Search "Arduino IRF520 module"

You need one Arduino pin to switch on/off the load.

It's very handy and provide posts for power input/output.

*I understand that you will still power the monitor from the wall, replacing only the original switch with Arduino. Otherwise, you will need a bigger relay*

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


body:
I have a bunch of thermometers (between 1 and 128). The thermometers have an internal OneWire ID such as "28edce1e500e5" and it is not readable by humans.

Normally I would make an associative array like this:

    map["28edce1e500e5"] = "Temp1";
    map["28ffd33b9116420"] = "Temp2";

    Serial.print(map[printAddress(allDevices[i])]);
    Serial.print(" : ");
    Serial.print(sensors.getTempC(allDevices[i]));

But it looks like the only hashmap library for Arduino is no longer supported and appears to be quite expensive.

The solution does not have to involve associative array.

The values are populated from a JSON file, loaded from an SD card.

I'm looking for a solutiuon to the problem, not a way to implement an associative array. (Unless that's the best way to solve the problem)

title: Mapping string values

Answers: 2

body:
Make a struct containing the name and id.

    struct device{char[MAX_ID_LENGTH] id; char[MAX_NAME_LENGTH] name; }

Then store the those pairs in an array which you can have sorted by one field or the other. That way you can binary search on that field.

body:
Taking the device structure from rachet freak's post you could implement a map of your own using something like this:

    template  <class K, class V> class MyMap
    {
    public:
     MyMap()
     {
     }

     void Add(K key, V value)
     {
     }

     void Remove(K key)
     {
     }

     V operator[](const& K)
     {
     }

    private:
    }

But I think templates are expensive under Arduino so you might want to manually instantiate it to drop the template.


body:
I am programming an ESP8266-01.

I have this code which I am using to operate an on-off switch, which is being used as an override switch for when the relay is turned on and off over the internet:

    void loop() {

      // Connect to the cloud
      rest.handle(client);

      // put your main code here, to run repeatedly:
      int read3 = digitalRead(0);

      Serial.print(read3);
      Serial.println(" input (1 is off)");

      if(read3 == 0) {
        if(pressed2) {
          Serial.println("in on");
          digitalWrite(2, 1);
          pressed = true;
          pressed2 = false;
        }
      }
      else {
        Serial.println("in off");
        if(pressed) {
          Serial.println("in off once");
          digitalWrite(2, 0);
          pressed = false;
          pressed2 = true;
        }
      }
    }

The above code never starts to run (nothing gets output on the serial) and the relay turns on. The thing is, this code works:

    void loop() {

      // Connect to the cloud
      rest.handle(client);

      // put your main code here, to run repeatedly:
      int read3 = digitalRead(0);

      Serial.print(read3);
      Serial.println(" input (1 is off)");

      if(read3 == 0) {
        Serial.println("in on");
        digitalWrite(2, 1);
        pressed = true;
      }
      else {
        Serial.println("in off");
        if(pressed) {
          Serial.println("in off once");
          digitalWrite(2, 0);
          pressed = false;
        }
      }
    }

Basically the way the code is set up, it is handling things so that the pin doesn't get read after the instance first instance that it is read (this is what the `bool` `pressed` is helping to do).

Why doesn't the first version work?

**UPDATE**

Whole working sketch:

    /*
      This a simple example of the aREST Library for the ESP8266 WiFi chip.
      This example illustrate the cloud part of aREST that makes the board accessible from anywhere
      See the README file for more details.

      Written in 2015 by Marco Schwartz under a GPL license.
    */

    // Import required libraries
    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    #include <aREST.h>

    // Clients
    WiFiClient espClient;
    PubSubClient client(espClient);

    // Create aREST instance
    aREST rest = aREST(client);

    // Unique ID to identify the device for cloud.arest.io
    char* device_id = "ew1zard";

    // WiFi parameters
    const char* ssid = "MaisonBlanche";
    const char* password = "7932gLBw";

    bool pressed = true;

    // Functions
    void callback(char* topic, byte* payload, unsigned int length);

    void setup(void)
    {
      // Set input / output pin
      pinMode(0, INPUT);
      pinMode(2, OUTPUT);

      // Start Serial
      Serial.begin(115200);

      // Set callback
      client.setCallback(callback);

      // Give name & ID to the device (ID should be 6 characters long)
      rest.set_id(device_id);
      rest.set_name("esp8266");

      // Connect to WiFi
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected");

      // Set output topic
      char* out_topic = rest.get_topic();
    }

    void loop() {

      // Connect to the cloud
      rest.handle(client);

      // put your main code here, to run repeatedly:
      int read3 = digitalRead(0);

      Serial.print(read3);
      Serial.println(" input (1 is off)");

      if(read3 == 0) {
        Serial.println("in on");
        digitalWrite(2, 1);
        pressed = true;
      }
      else {
        Serial.println("in off");
        if(pressed) {
          Serial.println("in off once");
          digitalWrite(2, 0);
          pressed = false;
        }
      }
    }

    // Handles message arrived on subscribed topic(s)
    void callback(char* topic, byte* payload, unsigned int length) {

      Serial.print("request from interwebs: ");
      Serial.println(topic);
      rest.handle_callback(client, topic, payload, length);

    }

title: Code runs, then doesn't run after I add some routine code

Answers: 1

body:
I used this - it does the same thing basically, just moved where the bool variables were.

    if(read3 == 0) {
        if(pressed2) {
          Serial.println("in on");
          digitalWrite(2, 1);
          pressed2 = false;
        }
        pressed = true;
      }
      else {
        Serial.println("in off");
        if(pressed) {
          Serial.println("in off once");
          digitalWrite(2, 0);
          pressed = false;
        }
        pressed2 = true;
      }


body:
I'm a beginner to Arduino and circuits. I've spent the last couple hours hung up on the concept of how current flows through switches and pull-down resistors, having read every thread and watched every YouTube video I could find on the subject.

I understand that pull-down (and pull-up) resistors are necessary in order to prevent pins from floating. What confuses me is that, if the input pins effectively have a built-in 100 megohm resistance (according to [this page][1]), then how is it that a 10k ohm pull-down resistor is enough to dissuade current from flowing directly into ground even when the switch is closed?

Here is a diagram of my circuit:

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

Am I conflating the high-impedance state of input pins with resistance more generally?

Would really appreciate any clarification on this. Thanks!

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

title: In a circuit with a switch and a pull-down resistor, why does the high impedance of the input not discourage current from flowing into pin?

Answers: 1

body: Yes, all of the current that flows goes through that resistor to ground.  That way almost all the voltage drops across that one resistor and you are able to read the voltage with the pin on the high side of it.  Only a very very small amount of current flows into the pin when you read a voltage.  It just needs to charge up a very small capacitor.


body:
I'm having what I believe to be a power issue with an Arduino project. I've tried 3 different power supplies (all separately):

1. My computer via USB B
2. A 5V USB "outlet" via USB B
3. A 5V USB "outlet", through a 5V->9V boost converter, to the arduino's barrel jack

I can run the sketch without an issue when connected to my computer (supply 1), even if the computer is sleeping and the Arduino program is closed. **However, when using supply 2 or 3, everything works EXCEPT reading the pilot light thermocouple through the MAX6675 module. It runs without throwing errors, but always reads 32.0 degrees F from the pilot light thermocouple.** The other thermocouples run and update as expected.

Details:

- Arduino Uno (bought ~November 2016)
- Running Arduino 3 for programming (downloaded October 2017)
- Code and Wiring Schematic below

![Wiring Schematic Here](https://i.stack.imgur.com/dTg8S.jpg)

Thanks for your help!

**EDIT 1**

I can run the Arduino with no problems off a small battery bank (like the kind you use to charge a phone with on the go). This isn't a permanent solution because the battery banks will only last 1-2 days powering the arduino. Anyway, I think this indicates that there's something to do with isolation/noise issues from the USB outlet, or something to do with not having a common ground.

Also, to clarify, the 5V USB outlet is powered by a 12V deep cycle battery, hooked up to a solar system with charge controller, other circuits, etc. I don't know if this is relevant, just trying to provide as much information as possible.

    //-------------------------------------------------------------------------------------------
    //--------------Inputs-----------------------------------------------------------------------

    // DS18B20 Thermocouples
    #include <Wire.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>

    // High temp thermocouple
    #include <max6675.h>

    // LCD Libraries
    #include <Adafruit_RGBLCDShield.h>
    #include <utility/Adafruit_MCP23017.h>
    // The shield uses the I2C SCL and SDA pins. On classic Arduinos
    // this is Analog 4 and 5 so you can't use those for analogRead() anymore
    // However, you can connect other I2C sensors to the I2C bus and share
    // the I2C bus.
    Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

    // Set temperature
    int heatSetTemp = 60; // deg F
    int bandwidth = 2; // if temp is within "bandwidth" of set point, it's acceptable

    float freshWaterTemp; // deg F, current fresh water temp
    float insideTemp; // deg F, current indoor temp
    float outsideTemp; // deg F, current outside temp
    float pilotTemp; // deg F, pilot light temperature

    boolean pilotIsOn = false;
    char pilotIsOnText = 'n';
    boolean gasIsOn = false;
    char gasIsOnText = 'n';

    // Set up high temp thermocouple
    int pilotThermo_sck_pin = 10;
    int pilotThermo_cs_pin = 9;
    int pilotThermo_so_pin = 8;
    MAX6675 pilotThermo(pilotThermo_sck_pin, pilotThermo_cs_pin, pilotThermo_so_pin);

    // Set up pilot light solenoid relay
    // pin 3 is saved for A/C control - to be implemented
    int ac_relay_pin = 3;
    int gasSolenoid_pin = 2;

    // Pin 4 has a wire jammed in it - not used

    // Set up ambient thermocouples
    int freshWaterThermo_pin = 5;
    int insideThermo_pin = 6;
    int outsideThermo_pin = 7;

    OneWire freshWaterThermo(freshWaterThermo_pin);
    DallasTemperature freshWaterThermoSensor(&freshWaterThermo);
    OneWire insideThermo(insideThermo_pin);
    DallasTemperature insideThermoSensor(&insideThermo);
    OneWire outsideThermo(outsideThermo_pin);
    DallasTemperature outsideThermoSensor(&outsideThermo);

    // Set up LCD for user interface
    int firstLCDLine = 0;
    boolean backlightIsOn = true;

    //-------------------------------------------------------------------------------------------
    //--------------Functions--------------------------------------------------------------------
    void turnGasOn() {
      digitalWrite(gasSolenoid_pin, LOW);
      gasIsOn = true;
      gasIsOnText = 'y';
    }

    void turnGasOff() {
      digitalWrite(gasSolenoid_pin, HIGH);
      gasIsOn = false;
      gasIsOnText = 'n';
    }

    void blinkLED() {
      digitalWrite(LED_BUILTIN, HIGH);
      delay(100);
      digitalWrite(LED_BUILTIN, LOW);
      delay(100);
      digitalWrite(LED_BUILTIN, HIGH);
      delay(100);
      digitalWrite(LED_BUILTIN, LOW);
    }

    void writeTempsLine() {
      lcd.print("In:"); lcd.print(insideTemp, 1);
      lcd.print(" Out:"); lcd.print(outsideTemp, 1);
    }

    void writeSetLine() {
      lcd.print("Set:"); lcd.print(heatSetTemp);
      lcd.print(" Wt:"); lcd.print(freshWaterTemp, 1);
    }

    void writeGasLine() {
      lcd.print("P:"); lcd.print(pilotTemp, 1);
      lcd.print(" P:"); lcd.print(pilotIsOnText);
      lcd.print(" G:"); lcd.print(gasIsOnText);
    }

    void toggleBacklight() {
      if (backlightIsOn) {
        lcd.setBacklight(0x0);
        backlightIsOn = false;
      }
      else {
        lcd.setBacklight(0x1);
        backlightIsOn = true;
      }
    }

    //-------------------------------------------------------------------------------------------
    //--------------Setup------------------------------------------------------------------------
    void setup() {
      Serial.begin(9600);

      // Set up relay to gas solenoid
      pinMode(gasSolenoid_pin, OUTPUT);
      turnGasOff(); // Set solenoid to closed by default

      // Start DallasTemperature Library
      freshWaterThermoSensor.begin();
      insideThermoSensor.begin();
      outsideThermoSensor.begin();

      // set up the LCD's number of columns and rows:
      lcd.begin(16, 2);

      // Indicator LED
      pinMode(LED_BUILTIN, OUTPUT);
    }
    //-------------------------------------------------------------------------------------------
    //--------------Main Program-----------------------------------------------------------------
    void loop() {

      // Read Temperatures
      pilotTemp = pilotThermo.readFahrenheit();

      freshWaterThermoSensor.requestTemperatures();
      insideThermoSensor.requestTemperatures();
      outsideThermoSensor.requestTemperatures();
      freshWaterTemp = freshWaterThermoSensor.getTempFByIndex(0);
      insideTemp = insideThermoSensor.getTempFByIndex(0);
      outsideTemp = outsideThermoSensor.getTempFByIndex(0);

      // Check Pilot Light
      pilotIsOn = (pilotTemp > 300); // flame temp goes here in degF
      if (pilotIsOn) { pilotIsOnText = 'y'; }
      else { pilotIsOnText = 'n'; }

      // Actuate Relay
      if (insideTemp < (heatSetTemp - bandwidth)) // Temp too cold, gas not on yet
      {
        if(pilotIsOn) { turnGasOn(); }
        else { turnGasOff(); } // because pilot is off
      }
      else if (gasIsOn && insideTemp < heatSetTemp) // Temp still too cold, but gas already on
      {
        if(pilotIsOn) { //leave gas on
        }
        else { turnGasOff(); } // because pilot is off
      }
      else // Temp is hot enough
      {
        turnGasOff();
      }

      //Check for button presses
      uint8_t buttons = lcd.readButtons();
      if (buttons) {
        if (buttons & BUTTON_UP) {
          Serial.println("button up pressed");
          firstLCDLine++;
        }
        if (buttons & BUTTON_DOWN) {
          Serial.println("button down pressed");
          firstLCDLine--;
        }
        if (buttons & BUTTON_RIGHT) {
          Serial.println("button right pressed");
          heatSetTemp++;
        }
        if (buttons & BUTTON_LEFT) {
          Serial.println("button left pressed");
          heatSetTemp--;
        }
        if (buttons & BUTTON_SELECT) {
           Serial.println("button select pressed!!!");
           toggleBacklight();
        }
      }

      // Output to Serial Monitor
      Serial.println(String("Fresh Water: ") + freshWaterTemp);
      Serial.println(String("Inside: ") + insideTemp);
      Serial.println(String("Outside: ") + outsideTemp);
      Serial.println(String("Pilot: ") + pilotTemp);
      Serial.println(String("Pilot Is On: ") + pilotIsOn);
      Serial.println(String("Gas Is On: ") + gasIsOn);
      Serial.println(String("Heat Set Temp: ") + heatSetTemp);
      Serial.println(String("firstLCDLine: ") + firstLCDLine);
      Serial.println();

      // Output to LCD
      lcd.clear();
      if(firstLCDLine % 3 == 0) {
        lcd.setCursor(0, 0); writeTempsLine();
        lcd.setCursor(0, 1); writeGasLine();
      }
      else if (firstLCDLine % 3 == 1) {
        lcd.setCursor(0, 0); writeGasLine();
        lcd.setCursor(0, 1); writeSetLine();
      }
      else {
        lcd.setCursor(0, 0); writeSetLine();
        lcd.setCursor(0, 1); writeTempsLine();
      }

      // Automatic scrolling
      firstLCDLine++;

      // Indicate "heartbeat" of sketch
      //blinkLED();
    }

title: Arduino Fails to Read Thermocouple on External Power

Answers: 0


body:
The code given below is an example code I found on the internet. This is to use my nodeMCU as a server. For my application, I believe that these lines of code...:

    if (request.indexOf("/LED=ON") != -1)  {
                digitalWrite(ledPin, HIGH);
                value = HIGH;
              }
              if (request.indexOf("/LED=OFF") != -1)  {
                digitalWrite(ledPin, LOW);
                value = LOW;
              }
... from the below program should run thereby interrupting every processes.

     #include <ESP8266WiFi.h>

        const char* ssid = "Linux"; // SSID i.e. Service Set Identifier is the name of your WIFI
        const char* password = "0123456789"; // 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
          Serial.println();
          Serial.println();
          Serial.print("Connecting to ");
          Serial.println(ssid);

          WiFi.begin(ssid, password);

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

          // Start the server
          server.begin();
          Serial.println("Server started");

          // Print the IP address
          Serial.print("Use this URL to connect: ");
          Serial.print("http://");
          Serial.print(WiFi.localIP()); //Gets the WiFi shield's IP address and Print the IP address of serial monitor
          Serial.println("/");

        }

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

          // Wait until the client sends some data
          Serial.println("new client");
          while(!client.available()){
            delay(1);
          }

          // Read the first line of the request
          String request = client.readStringUntil('\r');
          Serial.println(request);
          client.flush();

          // Match the request

          int value = LOW;
          if (request.indexOf("/LED=ON") != -1)  {
            digitalWrite(ledPin, HIGH);
            value = HIGH;
          }
          if (request.indexOf("/LED=OFF") != -1)  {
            digitalWrite(ledPin, LOW);
            value = LOW;
          }

        // Set ledPin according to the request
        //digitalWrite(ledPin, value);

          // 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);
          Serial.println("Client disconnected");
          Serial.println("");

        }

 How can we achieve this kind of software Interrupt(s)?
PS: Timer Interrupt won't work -- I believe.

title: Software Interrupts in Arduino or nodeMCU

Answers: 1

body: That doesn't need an interrupt.  Think about it, just check it right after you read it from the client.  So the response will be immediate.  It's not like it can suddenly become true at some other point without being read from the client.  You're already using a blocking read so if the first part of the message has arrived you'll stop right there and wait for it.  The loop should turn over really fast, keep it fast and non-blocking anywhere else and you can count on even if the message starts coming in immediately after your read the loop will make it back around to read again before the end of the message gets there.


body:
I have an issue with my application.

**Hardware used:**

- ESP8266 Serial Wi-Fi Wireless Transceiver Module for IOT
- Robodyn Micro USB Compatible for Arduino Nano V3.0 ATmega168 CH340G
- SENSOR: BMP180

**Connections:**

- Arduino Nano to ESP8266
- CH-PD to Vcc
- GPIO0 to GND
- Rx to Rx
- Tx to Tx
- 3.3v to 3.3v
- Reset to GND
- GND to GND

**Arduino Nano to BMP180**

- 3.3v to VIN
- GND to GND
- A5 to SCL
- A4 to SDA

Sketch used (uploaded in Generic ESP8266 Board):

    #include <DHT.h> //  DHT.h library
    #include <ESP8266WiFi.h> // ESP8266WiFi.h library
    #include <SFE_BMP180.h>
    #include <Wire.h>

    SFE_BMP180 pressure;

    const char* ssid     = "GOPI-LAPTOP";
    const char* password = "kcejava123";
    const char* host = "api.thingspeak.com";
    const char* writeAPIKey = "CQSHDFP4EZFCDWKO";

    void setup() {
      // Initialize sensor
      Serial.begin(9600);
      delay(1000);
      if (pressure.begin())
        Serial.println("BMP180 init success");
      else {
        Serial.println("BMP180 init fail\n\n");
      }
      //  Connect to WiFi network
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
      }
    }

    void loop() {
      char status;
      double T, P, p0, a;
      status = pressure.startTemperature();
      if (status != 0) {
        // Wait for the measurement to complete:
        delay(status);
        status = pressure.getTemperature(T);
        if (status != 0) {
          // Print out the measurement:
          Serial.print("temperature: ");
          Serial.print(T,2);
          Serial.print(" deg C, ");
          Serial.print((9.0/5.0)*T+32.0,2);
          Serial.println(" deg F");
        } else
          Serial.println("error retrieving pressure measurement\n");
      }
      status = pressure.startPressure(3);
      if (status != 0) {
        delay(status);
        status = pressure.getPressure(P, T);
        if (status != 0) {
          // Print out the measurement:
          Serial.print("absolute pressure: ");
          Serial.print(P, 2);
          Serial.print(" mb, ");
          Serial.print(P*0.0295333727, 2);
          Serial.println(" inHg");
          p0 = 1013.25; // we're at 1655 meters (Boulder, CO)
          Serial.print("relative (sea-level) pressure: ");
          Serial.print(p0, 2);
          Serial.print(" mb, ");
          Serial.print(p0*0.0295333727, 2);
          Serial.println(" inHg");
          a = pressure.altitude(P, p0);
          Serial.print("computed altitude: ");
          Serial.print(a, 0);
          Serial.print(" meters, ");
          Serial.print(a*3.28084, 0);
          Serial.println(" feet");
        }
      }
      // make TCP connections
      WiFiClient client;
      const int httpPort = 80;
      if (!client.connect(host, httpPort)) {
        return;
      }
      String url = "/update?key=";
      url+=writeAPIKey;
      url+="&field1=";
      url+=String(T);
      url+="&field2=";
      url+=String(P);
      url+="\r\n";
      // Request to the server
      client.print(String("GET ") + url + " HTTP/1.1\r\n" +
        "Host: " + host + "\r\n" +
        "Connection: close\r\n\r\n");
      Serial.print(String("GET ") + url + " HTTP/1.1\r\n" +
        "Host: " + host + "\r\n" +
        "Connection: close\r\n\r\n");
      delay(30000);
    }

**Serial Output:**

    BMP180 init fail

    GET /update?key=CQSHDFP4EZFCDWKO&field1=8.04&field2=8.08
     HTTP/1.1
    Host: api.thingspeak.com
    Connection: close

    GET /update?key=CQSHDFP4EZFCDWKO&field1=8.04&field2=8.08
     HTTP/1.1
    Host: api.thingspeak.com
    Connection: close

**Queries:**

• How to enable BMP180 to sense? When I configure BMP180 with Arduino (without ESP8266), I get the output in the serial terminal.

• How to send data to Thingspeak.com from BMP180 using the specified hardware?

title: How to connect Arduino Nano with ESP8266 and BMP180?

Answers: 2

body:
**Connections:**

[...]

- `Rx to Rx`
- `Tx to Tx`

That's not gonna fix your problem with initializing the BMP180, but you have to cross the lines, Rx to Tx and Tx to Rx, if you want to get anything on the serial terminal... Besides, your Nano is 5V, your ESP 3.3V. Connecting directly the Nano's Rx/Tx lines at 5V to the ESP's Rx/Tx 3.3V lines might not be very safe.

As for the BMP180, is it rated for 3.3V, or only 5V? If it is 5V only, it might not work on the ESP. Hence the init fail.

body:
For I2C to work you must have pull up resistors.  Normally 4.7K connected between SCL and VIN and SDA and VIN make thinks work.

You probably should use a logic level convertor to convert 3.3 to 5V (not a resistor divider, not sharp enough edges for digital signals).  If I remember correctly the ESP can take 7V on its pins before you kill it (its in the chip spec) but that doesn't mean its a good idea to do it.

As mentioned above you need to cross the serial leads to make the connection.  The Nano's Rx lead needs to be connected to the ESP's Tx lead and vice versa.


body:
I am building a special chamber, where I'm dealing with humidity, temperature and co2 contamination, but I'm having difficulties with software. If I separate it by parts, everything works as it should, but when I combine everything together, the CO2 measuring stops and the CO2 is being added to the chamber continuosly.

Here are my requests:
-The temperature has to be between 36 and 37°C,
-It has to be known the exact humidity,
-The amount of CO2 (carbon dioxide) has to be around 5% (50.000 ppm), around +/- 0.2% is allowed,
-Everything should be shown on 1602 LCD display.

To measure temperature, I have a LM335, for measuring humidity a HIH-4004-001 humidity sensor and for measuring CO2 contamination I have a MH-Z16 sensor. If there is lack of CO2 in the chamber, I'm adding it with a electromagnetic gas valve, which is driven by a relay. To heat up the chamber, I'm also using a relay, to turn on the heater.

Here's the code.
Does anyone has any kind of clue, what could possibly go wrong here?

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

    #include <SoftwareSerial.h>           //lib for serial communication for co2
    #include <NDIR_SoftwareSerial.h>      //lib for co2

    #include <LiquidCrystal.h>
    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);  //(RS, EN, D4, D5, D6, D7)

    //LM335 sensor TEMP
    int outputPin = 3;

    //heater
    const int rele = 2;  //relay output for HEATER
    int flag = 0;       //flag for hysteresis at 37°C

    //humidity
    int HIH4000_Pin = A2; //analog pin 2, humidity sensor

    //co2
    NDIR_SoftwareSerial mySensor(11, 12); //green= 11; yellow= 12.
    float percentage = 0.00; //co2 in percentage

    //co2 gas valve
    const int ventil = 3;  //relay output for CO2 GAS VALVE

    void setup() {
      lcd.begin(16, 2);
      pinMode(rele, OUTPUT);      //relay for HEATER
      pinMode(ventil, OUTPUT);    //relay for CO2 GAS VALVE
      Serial.begin(9600);

      digitalWrite(rele, HIGH);   //heater off
      digitalWrite(ventil, HIGH);   //co2 gas valve off

      if (mySensor.begin()) {
        Serial.println("Wait 10 seconds for sensor initialization...");

        lcd.setCursor(0, 0);
        lcd.print("Wait_10_seconds");
        lcd.setCursor(2, 1);
        lcd.print("CALIBRATION");
        delay(1000);
        lcd.clear();
        lcd.print("Wait_9_seconds");
        lcd.setCursor(2, 1);
        lcd.print("CALIBRATION");
        delay(1000);
        lcd.clear();
        lcd.print("Wait_8_seconds");
        lcd.setCursor(2, 1);
        lcd.print("CALIBRATION");
        delay(1000);
        lcd.clear();
        lcd.print("Wait_7_seconds");
        lcd.setCursor(2, 1);
        lcd.print("CALIBRATION");
        delay(1000);
        lcd.clear();
        lcd.print("Wait_6_seconds");
        lcd.setCursor(2, 1);
        lcd.print("CALIBRATION");
        delay(1000);
        lcd.clear();
        lcd.print("Wait_5_seconds");
        lcd.setCursor(2, 1);
        lcd.print("CALIBRATION");
        delay(1000);
        lcd.clear();
        lcd.print("Wait_4_seconds");
        lcd.setCursor(2, 1);
        lcd.print("CALIBRATION");
        delay(1000);
        lcd.clear();
        lcd.print("Wait_3_seconds");
        lcd.setCursor(2, 1);
        lcd.print("CALIBRATION");
        delay(1000);
        lcd.clear();
        lcd.print("Wait_2_seconds");
        lcd.setCursor(2, 1);
        lcd.print("CALIBRATION");
        delay(1000);
        lcd.clear();
        lcd.print("Wait_1_second");
        lcd.setCursor(2, 1);
        lcd.print("CALIBRATION");
        delay(1000);
        lcd.clear();
      }
      else {
        Serial.println("ERROR: Failed to connect to the sensor.");
        lcd.setCursor(0, 0);
        lcd.print("Press RST button");
        while (1);
      }

      lcd.setCursor(0, 0);
      lcd.print("T= ");
      lcd.setCursor(7, 0);
      lcd.print((char)223);
      lcd.setCursor(8, 0);
      lcd.print("C");

      lcd.setCursor(10, 0);
      lcd.print("H=");
      lcd.setCursor(15, 0);
      lcd.print("%");

      lcd.setCursor(0, 1);
      lcd.print("CO2=");
      //lcd.setCursor(8,1);
      //lcd.print("%");
    }

    void loop() {
      delay(100);

      //beggining of measuring and displaying CO2
      if (mySensor.measure()) {
        Serial.print("CO2 Concentration is ");
        Serial.print(mySensor.ppm);
        Serial.println("ppm");
        lcd.setCursor(4, 1);
        lcd.print("        ");
        lcd.setCursor(4, 1);
        lcd.print(mySensor.ppm);
        percentage = mySensor.ppm;
      } else {
        Serial.println("Sensor communication error.");
      }
      //end of measuring and displaying CO2

      //beggining of CO2 gas valve
      if (percentage < 1000) {
        digitalWrite(ventil, LOW);
        delay(1000);
        digitalWrite(ventil, HIGH);
        /*lcd.setCursor(2,0);
          lcd.print(celsius);  */
      }
      else {
        digitalWrite(ventil, HIGH);
      }
      //end of CO2 gas valve

      //start measuring temperature
      int rawvoltage = analogRead(outputPin);
      float millivolts = (rawvoltage / 1024.0) * 5000;
      float celsius = (millivolts / 10) - 276.20;
      lcd.setCursor(2, 0);
      lcd.print(celsius);
      //stop measuring temperature

      //start humidity sensor
      float relativeHumidity  = analogRead(HIH4000_Pin);
      float av = 0.0048875 * relativeHumidity;
      float vlaga = (av - 0.86) / 0.03;
      int humi = vlaga;
      if (humi < 100) {
        lcd.setCursor(12, 0);
        lcd.print(" ");
        lcd.setCursor(13, 0);
        lcd.print(humi);
      }
      else {
        lcd.setCursor(12, 0);
        lcd.print(humi);
      }
      //end humidity sensor

      //start of relay for heater
      lcd.setCursor(12, 1);
      if (celsius < 37 && flag == 0) {    //upper treshold of hysteresis 37
        digitalWrite(rele, LOW);
        //lcd.print("WARM");
      }

      if (celsius < 36 && flag == 1) {    //lower treshold of hysteresis 36
        digitalWrite(rele, LOW);
        //lcd.print("WARM");
      }

      if (celsius > 37) {               // treshold of first heating up
        digitalWrite(rele, HIGH);
        //lcd.print("COOL");
        flag = 1;
      }
      //end of relay for heater

      delay(650);
    }

title: Program hangs when correcting CO2

Answers: 2

body:
If the CO2 sensor stops working that means you should be getting a message out of the Serial console, you didn't mention it so I presume you aren't which means it is still reading a value.

If you are still reading a value and the CO2 is still being added this means the 'percentage' CO2 has to be less than 1000.

So, either the CO2 sensor is faulty (which because it works on its own it looks like it isn't) or there is a "wiring fault" and you aren't actually reading the CO2 sensor when you think you are.

Is it possible that you are misreading the result from the serial connection?  Is it possible that the library is misreading the data?

Try a simple program that reads the value from the CO2 sensor, prints it to the serial console and then opens the value for a second.

(Oh and in the setup function have a look at using a loop :) )

body:
Okay, I figured it out, what was wrong. It's completely unlogical and strange, but it solved me a problem.
First off, I tried to disconnect the valve relay from arduino, while arduino was still giving logical 0 and 1 on the output. And the strange thing was, it worked.
So I took a step further and back connected the relay, but disconnected the burden (valve). It worked fine aswell. So I figured it out, that here's some sort of a problem, that the valve SHOULDN'T be opened with relay, so I just added a 2N2222 transistor and a 12k resistor to the base, and the whole thing is working now perfectly. I just connected the output of the arduino (which was on relay for valve before) and put it on base resistor of 2N2222.

But thanks everyone for help!


body:
I have daisy-chained three MAX7219 7-segment 8-digit displays and wired it according to this diagram:

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

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

but no matter what library I use, the middle segment is in the wrong order when I display it.

So the numbers "123456789123456789"

would display as"12345678 76543219 89"

What could be wrong?

title: MAX7219 7-segment 8-digit display in wrong order

Answers: 1

body:
If you had three separate boards that you had chained together I would be surprised if one of them was wrong, but looking at the picture it looks like one board and I would think it was more likely that one display was incorrect.

I can't see your code, so I can't say if there is a bug in it or not.  It is possible that you have done something unusual, you might want to post a MINIMAL example to let people give it the once over.

As far as I know there aren't any "configuration settings" on a Max7219 to cause the affect you are seeing.  The fact that the 3rd display is correct implies that the tracks on the PCB are correct and its the IC that's got its wiring backwards, but that's a daft idea.

You might be able to work out if a track is wrong, or such like, but it would be so much easier to fix in software.  When you write to the display add an extra function that traps calls to the middle segment and flips the digits round (so `tmp == digit[7]; digit[8] == digit[0]; digit[0] = tmp; // You know what I mean`).


body:
I'm new to electronics and need some help please.

I'm planning to measure current of a 3-phase output using one sensor for each phase (thus 3 sensors would be required). The frequency of data recording should be 200 Hz.

Performance/data transfer wise: Is one Arduino Uno board enough to plug in the three sensors and get the data transferred using the USB cable onto a PC? Or should I get one board for each sensor?

I appreciate your help.

Cheers.

lorena

title: 3 AC current sensors using one Arduino Uno board measuring at 200Hz

Answers: 1

body:
1. Is the sampling speed enough?

It takes about 100 microseconds (0.0001 s) to read an analog input, so the maximum reading rate is about 10,000 times a second.

Ref.: https://www.arduino.cc/en/Reference/AnalogRead

2. Is the USB port fast enough?

The serial speed over USB is maximum 2Mbps and a fast calculation (200 samples/s x 3 sensors x 10 bit) 18kbps, so 2Mbps should be enough.


body:
I am trying to incorporate IoT to my embedded system project. I would call it soft real-time embedded system project.
But because of these '*LAZY*' lines,

    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected");
    // Start the server
    server.begin();
    Serial.println("Server started");
    if (!client) {
      return;  // Wait until the client sends some data
    }
    Serial.println("new client");
    while (!client.available()) {
      delay(1);
    }

The rest of the embedded system project has become so slow. If I don't put any of those lines, there will be obnoxious side-effects. How can I run this code along my actual embedded system project and still get done the soft real-time job?

[Edited] Full code:

    #include <ESP8266WiFi.h>

    const char* ssid = "Linux"; // SSID i.e. Service Set Identifier is the name of your WIFI
    const char* password = "0123456789"; // 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
      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

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

      // Start the server
      server.begin();
      Serial.println("Server started");

      // Print the IP address
      Serial.print("Use this URL to connect: ");
      Serial.print("http://");
      Serial.print(WiFi.localIP()); //Gets the WiFi shield's IP address and Print the IP address of serial monitor
      Serial.println("/");

    }

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

      // Wait until the client sends some data
      Serial.println("new client");
      while(!client.available()){
        delay(1);
      }

      // Read the first line of the request
      String request = client.readStringUntil('\r');
      Serial.println(request);
      client.flush();

      // Match the request

      int value = LOW;
      if (request.indexOf("/LED=ON") != -1)  {
        digitalWrite(ledPin, HIGH);
        value = HIGH;
      }
      if (request.indexOf("/LED=OFF") != -1)  {
        digitalWrite(ledPin, LOW);
        value = LOW;
      }

    // Set ledPin according to the request
    //digitalWrite(ledPin, value);

      // 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);
      Serial.println("Client disconnected");
      Serial.println("");

    }

title: ESP8266WiFi library severely slowed down my embedded system project

Answers: 2

body:
Try ESP8266WebServer instead. The following is an example included with the ESP8266 board package.

    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266mDNS.h>

    const char* ssid = "........";
    const char* password = "........";

    ESP8266WebServer server(80);

    const int led = 13;

    void handleRoot() {
      digitalWrite(led, 1);
      server.send(200, "text/plain", "hello from esp8266!");
      digitalWrite(led, 0);
    }

    void handleNotFound(){
      digitalWrite(led, 1);
      String message = "File Not Found\n\n";
      message += "URI: ";
      message += server.uri();
      message += "\nMethod: ";
      message += (server.method() == HTTP_GET)?"GET":"POST";
      message += "\nArguments: ";
      message += server.args();
      message += "\n";
      for (uint8_t i=0; i<server.args(); i++){
        message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
      }
      server.send(404, "text/plain", message);
      digitalWrite(led, 0);
    }

    void setup(void){
      pinMode(led, OUTPUT);
      digitalWrite(led, 0);
      Serial.begin(115200);
      WiFi.begin(ssid, password);
      Serial.println("");

      // Wait for connection
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.print("Connected to ");
      Serial.println(ssid);
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());

      if (MDNS.begin("esp8266")) {
        Serial.println("MDNS responder started");
      }

      server.on("/", handleRoot);

      server.on("/inline", [](){
        server.send(200, "text/plain", "this works as well");
      });

      server.onNotFound(handleNotFound);

      server.begin();
      Serial.println("HTTP server started");
    }

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

body:
I tested your sketch on a NodeMCU 0.9 and it works fine. Response times is sub-second. I'm using Firefox on a Linux Mint as a client.

[![Test run][1]][1]

I added code to timed each `loop` execution. The average time is 20-30 ms per loop. It looks fine to me or is it to long for you?

I think using a ESP8266WebServer is overkill and probably will take more resources to run. Having used ESP8266WebServer, for a project with one or two pages, using your approach is just fine.

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


body:
I need to run my servo motor within a specific pressure range, given by a pressure sensor. I don't understand how to code this. I have coded for servo motor movement but I need to activate that movement in a specific range. Please, help me.

This is my servo code:

    #include <Servo.h>

    Servo myservo;  // create servo object to control a servo
                    // twelve servo objects can be created on most boards
    int pos = 0;    // variable to store the servo position

    void setup() {
      myservo.attach(9);
      // attaches the servo on pin 9 to the servo object
    }

    void loop() {
      for(pos = 0; pos <= 30; pos += 1) {
        // goes from 0 degrees to 180 degrees
        // in steps of 1 degree
        myservo.write(pos);
        // tell servo to go to position in variable 'pos'
        delay(5); // waits 15ms for the servo to reach the position
      }
      for(pos = 30; pos>=0; pos-=1) {
        // goes from 180 degrees to 0 degrees
        myservo.write(pos);
        // tell servo to go to position in variable 'pos'
        delay(5);
        // waits 15ms for the servo to reach the position
      }
      delay(1500);
    }

I need to activate this servo within a 10-70 pressure range.

title: Servo motor activation with pressure sensor

Answers: 1

body:
You don't tell what pressure sensor are you using, but suppose that a call to `readPressure()` will give as pressure as an `int`

    #include <Servo.h>

    Servo myservo;  // create servo object to control a servo
    // twelve servo objects can be created on most boards

    int pos = 0;    // variable to store the servo position

    void setup()
    {
     myservo.attach(9);  // attaches the servo on pin 9 to the servo object
    }

    void loop()
    {
        int pressure = readPressure();

     if(pressure >= 10 && pressure <= 70) {
            //  Pressure is in range. Move the servo.
      for(pos = 0; pos <= 30; pos += 1) { // goes from 0 degrees to 180 degrees
       // in steps of 1 degree
       myservo.write(pos);              // tell servo to go to position in variable 'pos'
       delay(5);                       // waits 15ms for the servo to reach the position
      }

      for(pos = 30; pos>=0; pos-=1) {   // goes from 180 degrees to 0 degrees
       myservo.write(pos);              // tell servo to go to position in variable 'pos'
       delay(5);                       // waits 15ms for the servo to reach the position
      }
     }

        //  Wait for another 1.5 sec before next loop().
        delay(1500);
    }

Of course, you have to complete the code with the actual sensor calls.


body:
I'm currently using a Makefile for the Arduino Due I've found on [Github][1] (with some modifications). It's useful to me cause it allows me to add a [static library][2] for cryptographic functions I need and I can't do it using the IDE. Now I need to include the [WiFi library from Arduino][3] but I don't know how. I've tried to put the path to the source (/usr/share/arduino/libraries/WiFi/src) but it gives me warnings saying that some classes are undefined. Does anyone know how to include that library?

  [1]: https://github.com/jessicacarneiro/arduino-due-makefile/blob/master/Makefile
  [2]: https://github.com/relic-toolkit/relic
  [3]: https://www.arduino.cc/en/Reference/WiFi

title: Including Arduino library in a Makefile for Due

Answers: 1

body:
Adding a library isn't as simple as just adding an include path.

You also have to identify each and every source file (or use wildcards as are used for the various sections of the core) and compile them into object files. It is then quite convenient to archive those into a library (.a) file which you can then link your sketch against (if you don't archive you will have to link all the objects files with your sketch in the linking phase).


body:
My project is a vehicle tracking system. I'm using a NEO-6M for GPS and a SIM900 for GPRS. I want to send the GPS coordinates to a MySQL database. I've tested the GPS and it's working well. I've succeeded to send the data to the online MySQL database by manually typing the AT commands on the Arduino Serial Monitor. Now, I would like to put the sending of coordinates in a `loop` for Arduino to send the coordinates on the database every 3 seconds. But there's no data entering the database. What do you think is the problem here? Here's my code (by the way it has no errors reported):

sendlatlng.ino:

    #include <SoftwareSerial.h>
    #include "SIM900.h"
    #include <TinyGPS.h>
    #define pinPowerSIM900 14

    TinyGPS gps;
    SoftwareSerial ss(10, 11);

    uint16_t startAddr = 0x0000;
    uint16_t lastAddr;
    uint16_t TimeIsSet = 0xaa55;
    int currentDay = 0;
    int currentMonth = 0;
    int currentYear = 0;
    int currentHour = 0;
    int currentMinute = 0;
    float flat, flon;
    float previousFlat = 0.0;
    float previousFlon = 0.0;
    static void smartdelay(unsigned long ms);
    static void print_float(float val, float invalid, int len, int prec);
    static void print_int(unsigned long val, unsigned long invalid, int len);
    static void print_date(TinyGPS &gps);
    static void print_str(const char *str, int len);

    void setup() {
      pinMode (pinPowerSIM900, OUTPUT); digitalWrite (pinPowerSIM900, LOW);
      powerUpOrDown();
      Serial.begin(115200);
      Serial.print("Testing TinyGPS library v. ");
      Serial.println(TinyGPS::library_version());
      Serial.println("");
      Serial.println();
      Serial.println("Stats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum");
      Serial.println("          (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail");
      Serial.println("-------------------------------------------------------------------------------------------------------------------------------------");
      ss.begin(9600);
    }

    void loop() {
      bool newData = false;
      for (unsigned long start = millis(); millis() - start < 1000;) {
        while (ss.available()) {
          char c = ss.read();
          //Serial.write(c);  /*uncomment this line if you want to see GPS data*/
          if (gps.encode(c)) newData = true;
        }
      }

      if (newData) {
        float flat, flon;
        unsigned long age, date, time, chars = 0;
        unsigned short sentences = 0, failed = 0;
        static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
        print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
        print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
        gps.f_get_position(&flat, &flon, &age);  /*latitude, longitude, age*/
        print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);  /*print lat */
        print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);  /*print long */
        print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
        print_date(gps); /* print date */
        print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2); /* print altitude */
        print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
        print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
        print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " :
       TinyGPS::cardinal(gps.f_course()), 6);
        print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
        print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ?
       TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
        print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " :
       TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);
        gps.stats(&chars, &sentences, &failed);
        print_int(chars, 0xFFFFFFFF, 6);
        print_int(sentences, 0xFFFFFFFF, 10);
        print_int(failed, 0xFFFFFFFF, 9);
        Serial.println();
        smartdelay(3000);
        if ((flat != previousFlat) || (flon != previousFlon)) {
          previousFlat = flat;
          previousFlon = flon;
          SendSQL();  //Function to send the coordinates
        }
      }
    }

    static void smartdelay(unsigned long ms) {
      unsigned long start = millis();
      do {
        while (ss.available()) gps.encode(ss.read());
      } while (millis() - start < ms);
    }

    static void print_float(float val, float invalid, int len, int prec) {
      if (val == invalid) {
        while (len-- > 1) Serial.print('*');
        Serial.print(' ');
      } else {
        Serial.print(val, prec);
        int vi = abs((int)val);
        int flen = prec + (val < 0.0 ? 2 : 1); // . and -
        flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
        for (int i=flen; i<len; ++i) Serial.print(' ');
      }
      smartdelay(0);
    }

    static void print_int(unsigned long val, unsigned long invalid, int len) {
      char sz[32];
      if (val == invalid) strcpy(sz, "*******");
      else sprintf(sz, "%ld", val);
      sz[len] = 0;
      for (int i=strlen(sz); i<len; ++i) sz[i] = ' ';
      if (len > 0) sz[len-1] = ' ';
      Serial.print(sz);
      smartdelay(0);
    }

    static void print_date(TinyGPS &gps) {
      int year;
      byte month, day, hour, minute, second, hundredths;
      unsigned long age;
      gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
      if (age == TinyGPS::GPS_INVALID_AGE) Serial.print("********** ******** ");
      else {
        char sz[32];
        sprintf(sz, "d/d/d d:d:d ", month, day, year, hour, minute, second);
        Serial.print(sz);
      }
      print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
      smartdelay(0);
    }

    static void print_str(const char *str, int len) {
      int slen = strlen(str);
      for (int i=0; i<len; ++i) Serial.print(i<slen ? str[i] : ' ');
      smartdelay(0);
    }

    void powerUpOrDown() {
      digitalWrite(pinPowerSIM900, HIGH);
      delay(2000);
      digitalWrite(pinPowerSIM900, LOW);
      delay(3000);
    }

    void SendSQL() {
      Serial.println("Start Send");
      gsm.SimpleWriteln("AT+SAPBR=3,1,\"Contype\",\"GPRS\"");
      delay(500);
      gsm.SimpleWriteln("AT+SAPBR=3,1,\"APN\",\"my.apn.com\"");   //APN
      delay(500);
      gsm.SimpleWriteln("AT+SAPBR=1,1");
      delay(3000);
      gsm.SimpleWriteln("AT+SAPBR=2,1");
      delay(3000);
      gsm.SimpleWriteln("AT+HTTPINIT");
      delay(500);
      gsm.SimpleWriteln("AT+HTTPPARA=\"CID\",1 ");
      delay(500);
      gsm.SimpleWriteln("AT+HTTPPARA=\"URL\",\"http://crbphil-001-site1.1tempurl.com/adddata.php\""); //URL
      delay(500);
      gsm.SimpleWriteln("AT+HTTPPARA=\"CONTENT\",\"application/x-www-form-urlencoded\"");
      delay(500);
      gsm.SimpleWriteln("AT+HTTPDATA=38,10000");
      delay(500);
      gsm.SimpleWriteln("addlati=");
      Serial.print(previousFlat, 6);
      gsm.SimpleWriteln("&addlongti=");
      Serial.print(previousFlon, 6);
      gsm.SimpleWriteln("\"");
      delay(3000);
      gsm.SimpleWriteln("AT+HTTPACTION=1");
      delay(15000);
      gsm.SimpleWriteln("AT+HTTPTERM");
      delay(500);
      gsm.SimpleWriteln("AT+SAPBR=0,1");
      delay(500);
      Serial.println("Finish");
    }

And this is my PHP script to save data in the MySQL database:

adddata.php:

    <?php
 //Connect to MySQL
 include("config.php");

    // Perform a query, check for error
    if (!mysqli_query($connect,"INSERT INTO track (tr_date, tr_time, latitude, longitude) VALUES ('".$_POST["addday"]."','".$_POST["addhour"]."','".$_POST["addlati"]."','".$_POST["addlongti"]."')")) {
      echo("Error description: " . mysqli_error($connect));
    }
    ?>

title: Why do GPS coordinates fail to save on MySQL database using SIM900?

Answers: 1

body:
Can you see a slight discrepancy in these lines?

    gsm.SimpleWriteln("addlati=");
    Serial.print(previousFlat, 6);
    gsm.SimpleWriteln("&addlongti=");
    Serial.print(previousFlon, 6);

I can.


body:
I am trying to operate two DC motors at once using a L293D chip. I have managed to control them however, one of the motors has a slight problem. Whenever I start the program (attached below), one of the motor (I tried switching them, it isn't a problem due to the motor itself) has a counterclockwise spin for a second before starting to spin clockwise as it is suppose to. When it is spinning counterclockwise, the other motor is not doing any movements.

Is something wrong in the code or in the circuit? (I've also attached a hyperlink to my circuit which I found online, as well as my code)

Thank you

    #define E1 11  // Enable Pin for motor 1
    #define E2 10  // Enable Pin for motor 2
    #define I1 12  // Control pin 1 for motor 1
    #define I2 13  // Control pin 2 for motor 1
    #define I3 8   // Control pin 1 for motor 2
    #define I4 9   // Control pin 2 for motor 2

    void setup() {
      pinMode(E1, OUTPUT);
      pinMode(E2, OUTPUT);
      pinMode(I1, OUTPUT);
      pinMode(I2, OUTPUT);
      pinMode(I3, OUTPUT);
      pinMode(I4, OUTPUT);
    }

    void loop() {
      analogWrite(E1, 255); // Run at full speed
      analogWrite(E2, 255); // Run at full speed
      digitalWrite(I1, HIGH);
      digitalWrite(I2, LOW);
      digitalWrite(I3, HIGH);
      digitalWrite(I4, LOW);
      delay(4500);
      // change direction
      digitalWrite(E1, LOW);
      digitalWrite(E2, LOW);
      delay(2000000000000);
      analogWrite(E1, 255);  // Run at full speed
      analogWrite(E2, 255);  // Run at full speed
      digitalWrite(I1, LOW);
      digitalWrite(I2, HIGH);
      digitalWrite(I3, LOW);
      digitalWrite(I4, HIGH);
      delay(000);
    }

http://hw.sudarmuthu.com/wp-content/uploads/sites/2/2013/06/basic-bot1.png

title: Problem with my 2 motor system

Answers: 2

body:
    #define I2 13  // Control pin 2 for motor 1

Pin 13 is the LED and is blinked by the bootloader. You will have to use a different pin for your motor.

body:
I'm having trouble compiling your code Max. It's failing on this line: delay(2000000000000);

The last line of code: delay(000); doesn't seem to be doing anything useful and can be removed.

I do not have a L293D IC to test the following code with so I need you to test it for me please.

    #define E1 11  // Enable Pin for motor 1
    #define E2 10  // Enable Pin for motor 2

    #define I1 12  // Control pin 1 for motor 1
    #define I2 7   // Control pin 2 for motor 1 (change pin 13 to pin 7)
    #define I3 8   // Control pin 1 for motor 2
    #define I4 9   // Control pin 2 for motor 2

    void setup() {
      pinMode(E1, OUTPUT);
      pinMode(E2, OUTPUT);
      pinMode(I1, OUTPUT);
      pinMode(I2, OUTPUT);
      pinMode(I3, OUTPUT);
      pinMode(I4, OUTPUT);

      // Disable motors
      digitalWrite(E1, LOW);
      digitalWrite(E2, LOW);
    }

    void loop() {

        // Set direction first
        digitalWrite(I1, HIGH);
        digitalWrite(I2, LOW);
        digitalWrite(I3, HIGH);
        digitalWrite(I4, LOW);

        // Enable motors
        analogWrite(E1, 255);
        analogWrite(E2, 255);

        // Motors run for 4.5 seconds
        delay(4500);

        // change direction

        // Disable motors
        digitalWrite(E1, LOW);
        digitalWrite(E2, LOW);

        // Give the motors time to stop if required
        delay(500);

        // Change motor direction
        digitalWrite(I1, LOW);
        digitalWrite(I2, HIGH);
        digitalWrite(I3, LOW);
        digitalWrite(I4, HIGH);

        // Enable motors
        analogWrite(E1, 255);
        analogWrite(E2, 255);

        // Motors run for 4.5 seconds
        delay(4500);

        // Disable motors
        digitalWrite(E1, LOW);
        digitalWrite(E2, LOW);

        // Give the motors time to stop if required
        delay(500);
    }


body:
The source code for the `analogWrite` function looks like this:

    void analogWrite(uint8_t pin, int val) {
        ...
        sbi(TCCRnA, COM0x);
        OCRnx = val;
        ...
    }

Where n is which timer (0, 1, 2...) and x is which pin is controlled by that timer (A, B).

This doesn't make sense to me, because the ATmega328P datasheet says that the bits `TCCRnA.WGM0[1:0]`, and `TCCRnB.WGM0` need to be set up as well.

[Datasheet][1]

Obviously the above code works, but how, with the missing bit settings?

  [1]: http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf

title: Arduino analogWrite source code explanation

Answers: 2

body:
> because the ATmega328P datasheet says that the bits TCCRnA.WGM0[1:0], TCCRnB.WGM02, and TIMSKn.OCIEx all need to be set as well.

they use different meanings for the word "set".

1. the datasheet is saying that you need to SET UP those bits for the appropriate mode. "SET" here means both set or clear, as appropriate.

2. the code, poorly written actually, sets those bits that need to be set, and let the rest is in their default / reset state, presumably cleared. a more robust way would have been to explicitly clear those bits.

body: Look at the init() function in wiring.c.  All of the timers get set up there depending on which chip is selected.  I don't know if some might also be done by initVariant().  But all it leaves for analogWrite to do is set the bit in the COM register to enable the PWM.


body:
I am having some issues with a new [DS3231 Precision RTC module][1]. I have made connections as in the guide linked, and when used, the serial output from the Arduino is garbled, and the arduino apparently crashes, endlessly flowing garbled messages (which appear to be bits of the beginning of the first serial output).

Sometimes I can get better output, but only up until I try to set the datetime, where it then crashes, with endless garble.

Code used to set datetime (all vars given are `int`s):

    rtc.adjust(DateTime(year, month, day, hour, minute, second));

The way I have things wired is the same as on the guide listed. I am basing my code off of the example on the guide (which is the same as on the guide), yet the example code functions well.

Relevant excerpt(s) from my code:

    //includes
    #include <Servo.h> //for running the servo
    #include <Wire.h> //required for RTClib
    #include "RTClib.h" //to run the real time clock functionality. https://github.com/adafruit/RTClib

    boolean timingEnabled = true;
    RTC_DS3231 rtc;
    void setup(){
      Serial.begin(9600);
      if(timingEnabled){
        //clock
        boolean rtcOn = rtc.begin();
     Serial.print(String(rtcOn) + "\n");
        if(! rtcOn){
          Serial.print("Couldn't find RTC. Timing Disabled\n");
          timingEnabled = false;
        }else{
          if(rtc.lostPower()){
         Serial.println("Clock lost power.\n");
         setTime();//set the clock
          }
        }
      }
    }

Since it was asked for, full code (minus `loop()`):

    /* Sketch for Arduino to run the automatic cat feeder.
     *
     *
     */

    //includes
    #include <Servo.h> //for running the servo
    #include <Wire.h> //required for RTClib
    #include "RTClib.h" //to run the real time clock functionality. https://github.com/adafruit/RTClib

    //status indicator values
    const int onboardLedPin = 13;

    //buzzer values
    const boolean buzz = true; //turns on and off the buzzer functionality
    const int buzzerPin = 8;
    const int buzzLength = 250;
    const int buzzDefaultFreq = 1000;
    const int buzzFeedStartFreq = 2000;
    const int buzzFeedEndFreq = 500;
    const int buzzBattWarnFreq = 2000;
    const int buzzConfirmFreq = 100;

    //Servo setup
    Servo dispenserServo;
    const int servoPin = 11;
    const int feedServoSpinTime = 2000;
    const int STOP = 90;
    const int SPIN_CLOCKWISE = 180;
    const int SPIN_COUNTER_CLOCKWISE = 0;

    //clock
    boolean timingEnabled = true;
    RTC_DS3231 rtc;
    String feedTimes[] = {"7:00"};

    //button
    const int buttonPin = 7;
    int buttonVal = 0;

    //other
    const int mainWait = 5000;

    /*
     * Does a buzz if it is set to.
     */
    void doBuzz(int frequency, boolean wait){
      if(buzz){
        tone(buzzerPin, frequency, buzzLength);
        if(wait){
          delay(buzzLength);
        }
      }
    }

    /*
     * Default function to not wait for buzz to finish.
     */
    void doBuzz(){
      doBuzz(buzzDefaultFreq, false);
    }

    void checkButton(){
      buttonVal = digitalRead(buttonPin);
    }

    /*
     * Determines if it is time to do the feeding.
     */
    boolean isFoodTime(){
      if(!timingEnabled){
        return false;
      }
      DateTime curTime = rtc.now();

      String hr = String(curTime.hour());
      String mn = String(curTime.minute());

      String time = hr + ":" + mn;

      for(int i = 0; i < sizeof(feedTimes); i++){
        if(feedTimes[i] == time){
          return true;
        }
      }

      return false;
    }

    String formatDateTime(DateTime dtIn){
      return String(dtIn.month()) + "/" + String(dtIn.day()) + "/" + String(dtIn.year()) + " " + String(dtIn.hour()) + ":" + String(dtIn.minute()) + ":" + String(dtIn.second());
    }

    String formatDateTime(){
     formatDateTime(rtc.now());
    }

    int getNumFromButton(int startAt){
      doBuzz(buzzFeedEndFreq, true);
      int longPressLength = 500;
      int output = startAt;
      bool counting = true;
      do{
        checkButton();
        if(buttonVal == HIGH){
            delay(longPressLength);
            checkButton();
            if(buttonVal == HIGH){
              counting = false;
            }else{
              output++;
              doBuzz(buzzConfirmFreq, true);
              delay(longPressLength);
            }
        }
      }while(counting);
      doBuzz(buzzConfirmFreq, true);
      delay(buzzLength);
      doBuzz(buzzConfirmFreq, true);
      return output;
    }

    void setTime(){
      //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
      //Serial.print("Setting the clock... ("+formatDateTime()+")\n");
      delay(buzzLength);
      delay(buzzLength);
      doBuzz(buzzConfirmFreq, true);
      delay(buzzLength);
      doBuzz(buzzConfirmFreq, true);
      delay(buzzLength);
      doBuzz(buzzConfirmFreq, true);
      Serial.print("Getting Year... (");
      int year = getNumFromButton(2000);
      Serial.print(String(year) + ")\nGetting Month... (");
      int month = getNumFromButton(1);
      Serial.print(String(month) + ")\nGetting Day... (");
      int day = getNumFromButton(1);
      Serial.print(String(day) + ")\nGetting Hour... (");
      int hour = getNumFromButton(0);
      Serial.print(String(hour) + ")\nGetting Minute... (");
      int minute = getNumFromButton(0);
      Serial.print(String(minute) + ")\nGetting Second... (");
      int second = getNumFromButton(0);
      Serial.print(String(second) + ")\n");
      delay(buzzLength);
      doBuzz(buzzConfirmFreq, true);

      Serial.print("Finished getting numbers.\n");
      rtc.adjust(DateTime(year, month, day, hour, minute, second));
      Serial.print("Clock set to: " + formatDateTime() + "\n");
    }

    /*
     * Setup of things:
     *  - status led
     *  - buzzer
     *  - servo
     */
    void setup(){
      Serial.begin(9600);
      Serial.print("\nBeginning setup of the CatFeeder.\n");
      // status led
      pinMode(onboardLedPin, OUTPUT);
      // buzzer
      pinMode(buzzerPin, OUTPUT);
      doBuzz();
      //servo
      dispenserServo.attach(servoPin);
      pinMode(servoPin, OUTPUT);
      dispenserServo.write(STOP);

      if(timingEnabled){
        //clock
        boolean rtcOn = rtc.begin();
     Serial.print(String(rtcOn) + "\n");
        if(! rtcOn){
          Serial.print("Couldn't find RTC. Timing Disabled\n");
          timingEnabled = false;
          doBuzz(buzzConfirmFreq, true);
          delay(buzzLength);
          doBuzz(buzzConfirmFreq, true);
          delay(buzzLength);
          doBuzz(buzzConfirmFreq, true);
          delay(buzzLength);
          doBuzz(buzzConfirmFreq, true);
        }else{
          if(rtc.lostPower()){
         Serial.println("Clock lost power.\n");
         setTime();
          }
        }
      }
      if(!timingEnabled){
        Serial.print("Timing disabled. Will only actuate on button press.\n");
      }else{
        Serial.print("Current time: " + formatDateTime());
      }

      //button
      pinMode(buttonPin, INPUT);

      Serial.print("Finished setup.\n\n");
    }

Full code size:

`Binary sketch size: 12,416 bytes (of a 32,256 byte maximum)`

  [1]: https://learn.adafruit.com/adafruit-ds3231-precision-rtc-breakout/wiring-and-test
  [2]: http://tronixstuff.com/2014/12/01/tutorial-using-ds1307-and-ds3231-real-time-clock-modules-with-arduino/

title: Adafruit RTC DS3231 Crashing Arduino Uno

Answers: 1

body:
Memory is never allocated for the result of formatDateTime().

Or more exactly there is a local variable inside formatDateTime() which has memory allocated as the string is built, then formatDateTime() returns a pointer to this memory, but as soon as the formatDateTime() exits this memory is freed, hence when Serial.print() is called and passed this pointer the memory at this pointer that used to hold the string may have already been reused.


body:
I'm doing a radiation-seeking robot, which will find the source of the radiation autonomously. But in this case, my robot will spin 180 degrees to detect the nearest source of radiation and 1 set of data recorded is considered for every 180 degree turn. However I think it is not possible to store all of the data in the Arduino due to a storage problem.

Therefore is there any function in Arduino that can only record the last 3 sets of data from the sensor? For example, after it has recorded 3 sets of data, the fourth set data could be recorded by overwriting the first set of data. I would be really grateful if anyone could help me with this.

PS if possible I don't want to install an SD card in my Arduino.

title: Recording of sensor results but only retain the last 3 sets of data

Answers: 1

body:
It depends how big the data is... if one data set is 100 bytes, you can spend 300 bytes of internal SRAM memory.

What you also can do if the memory usage is too big, is to add external SRAM, like the 32K256 which has 32 kb (kilobyte) SRAM or the 23LC1024 which has 128 kb SRAM.

To loop through the data sets you can easily use a so called 'ring buffer'.

You allocate 3 sets of data (like 3 arrays of a byte array), and an index. the index you increase after every use like:

    index = (index + 1) % 3

External SRAM normally uses SPI to communicate with, and you can read/write it by a single byte, multiple bytes or page (typically 128 to 512 bytes). You cannot directly store variables in it, but you have to manually keep track where you store what ... for 3 data sets this will be relatively easy. You can even calculate (beforehand) the number of data sets that can be stored and cycle through them as needed.


body:
A very simple

    digitalwrite(pin, HIGH)
    delay(1200)
    digitalwrite(pin, LOW)
    delay(1200)

crashes the uno after about half an hour. Of course it works again after pressing the reset button.

It's switching this [relay][2]

 [![relay][1]][1]

Which is connected to a 230v 80W DC motor. The relay cuts the '+'

Because I've read that 230v stuff can be too much for such a litte relay,
I've disconnected the motor and not the relay switches another 24v OMRON P2RF-05-PU (10A250VAC) relay, which has his own 24V Mean Well power supply. And connected the motor to that one.

I thought this solved my problem, but now the Arduino crashes after about 3 hours.
Any thoughts on what else I could try?

  [1]: https://i.stack.imgur.com/5hEHo.png
  [2]: http://store.cutedigi.com/relay-module-of-linker-kit-for-pcduino-arduino/

title: Simple relay switching program crashes UNO

Answers: 0


body:
I am new to arduino and sensor. I am going to do a project related to E-nose to detect children breath odor. I wanted to use few sensors including
Figaro TGS2602, TGS2600, TGS825, TGS2620 and TGS2180 together with arduino. May I ask is it possible for an Arduino Uno or Mega to support all these 5 sensors at one time?

title: Arduino with sensor

Answers: 1

body: They are all analog sensors, so yes - you have 6 analog inputs on an Uno and 5 analog sensors, so you have one spare analog pin to do something else with if you want.


body:
I am using millis() to flash some lights (neopixels) on an arduino pro mini. The problem is that I cannot flash the lights for the desired period. More specifically, the lights flash for ~250 ms, whereas I want to flash for 9 seconds! Here is a simplified version of what I am doing.

In loop(), I have a while loop (let's call it loop 1) that should run for 250 ms. Inside loop 1, I call a function flash(), that has to run for 9 seconds! I put another loop (loop 2) after loop 1, that would run for 3 seconds.

Here is the bigger picture...I actually want a radio to wake up for 250 ms. If in that time interval it receives anything, flash() will be called that will flash the lights for 9 secs. If it doesn't receive anything it will simply go to sleep for 3 secs, then come back alive for 250 ms, so on and so on

    void loop() {
        previousMillis = millis();
        while (millis() - previousMillis < awake_interval) {  //awake_interval = 250 ms
            flash();  //flash for 9 seconds
        }

        previousMillis = millis();
        while (millis() - previousMillis < sleep_interval);  //sleep_interval = 3 secs
    }

The flash() function looks like this,

    void flash() {
        unsigned long x = millis();
        while(millis() - x < flash_time){  //flash_time = 9 secs
            lights_on();
            delay(t1);
            lights_off();
            delay(t2);
        }
    }

I put loop 2 in there because without it the lights flash forever. This makes sense because all the code is in an infinite loop - void loop().

For debugging, I put serial prints after entering the loops. It seems that nesting two loops (in my case flash() inside loop 1), both of which uses millis() is the source of the problem. If that is true, how else should I do this? If that is not the problem, any ideas will be appreciated.

**Edit:** The suggestions made by @VE7JRO and @ratchet freak are neat but I was still having problems making my thing work. Turns out it was a problem with one my initializations. I am posting my whole code below (that uses LEDs). I guess I should post the correct code as an answer.

    const long sleep_interval = 3000;
    const long awake_interval = 250;
    const int ledPin = 3;

    const uint8_t flash_time = 9000;  //bug
    const uint16_t t1 = 5;
    const uint16_t t2 = 495;

    void flash() {
        unsigned long x = millis();
        while(millis() - x < flash_time){
            digitalWrite(ledPin, HIGH);
            delay(t1);
            digitalWrite(ledPin, LOW);
            delay(t2);
        }
    }

    void setup() {
        Serial.begin(57600);
        pinMode(ledPin, OUTPUT);
    }

    void loop() {
        unsigned long x = millis();
        while(millis() - x < awake_interval){
            Serial.println("flash time!");
            flash();  //overflow will occur
        }

        unsigned long y = millis();;
        while (millis() - y < sleep_interval) {  //sleep_interval = 3 secs
            Serial.println("Sleep time!");
        }
    }

title: Using millis(), in nested loops

Answers: 5

body:
Your logic is wrong. If you update previousMillis with millis() value in the first line, you are always subtracting the time difference between the the first and second lines of your code (which is the same you are doing in the loop inside flash()). If what you need is to get the time passed since the program started running, you need to have a fixed variable for that in setup() instead of updating it every time in loop().

Even so, I don't see why millis() is necessary in your case. Using delay() would be much more simple and still get the job done. Example:

    void setup() {
 delay(250);
    }

    void loop(){

     for(int i = 0; i < 9; i++){
      digitalWrite(LED, HIGH);
      delay(time);
      digitalWrite(LED, LOW);
      delay(time);

      delay(1000 - 2*time); //Delays the loop exactly one second per iteraction
     }

    }

body:
Use a state machine instead:

    bool  flashing;
    unsigned long lastflashingChange;

    void loop() {
        unsigned long currentMillis = millis;
        if(flashing){
            flash();  //update flash state and change IO pin
            if (lastflashingChange - currentMillis >= awake_interval) {  //awake_interval = 250 ms
                flahsing = false;
                //turn off the led
                lastflashingChange = currentMillis;
            }
        } else {
            if (lastflashingChange - currentMillis >= sleep_interval) {  //awake_interval = 250 ms
                flashing = true;
                //possible initialize flash state
                lastflashingChange = currentMillis;
            }
        }
    }

And a similar bit of code inside `flash()`

    bool flashOn;
    unsigned long lastFlashLightChange;
    void flash() {
        unsigned long x = millis();

        if(flashOn){
            if (lastFlashLightChange - x >= t1) {
                flashOn = false;
                lights_off();
                lastFlashLightChange = currentMillis;
            }
        } else {
            if (lastFlashLightChange - x >= t2) {
                flashOn = true;
                lights_on();
                lastFlashLightChange = currentMillis;
            }
        }

    }

body:
> the lights flash for ~250 ms, whereas I want to flash for 9 seconds!

that logic doesn't make sense. Essentially you want to eat a 2 hour meal within 5 seconds.

your code reflects that kind of logic: when the execution exits flash(), it must also exit the while loop in loop().

so think exactly what you want to do, write it down and then code to it.

body:
Here is a sketch to get you started. It doesn't use delay or any libraries. I don't have any NeoPixel devices so I used the Arduino built in LED for testing purposes. Just remove the "myTimer4" function and related code/variables to stop the blinking LED. I don't know what type of "radio" you are using so I used a character inputed in the serial monitor to simulate a radio signal being received. There are several serial print statements throughout the code for testing purposes as well.

    const unsigned long delayTime = 3000;
    const unsigned long delayTime2 = 250;
    const unsigned long delayTime3 = 9000;
    const unsigned long delayTime4 = 500;
    unsigned long previousMillis = 0;
    unsigned long previousMillis2 = 0;
    unsigned long previousMillis3 = 0;
    unsigned long previousMillis4 = 0;
    byte checkForData = 0;
    byte dataReceived = 0;
    byte flashLED = 0;
    byte doOnce = 0;

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

    void loop(){

      // Get current time.
      unsigned long currentMillis = millis();

      // First event.
      if(checkForData == 0){
        if(myTimer1(delayTime, currentMillis) == 1){
          Serial.println("3 second timer done");
          checkForData = 1;
          previousMillis2 = currentMillis;
        }
      }

      // Second event.
      if(checkForData == 1){

        // Your radio code here to check for data.

        // I'm simulating data input from your device using the serial monitor.
        if(Serial.read() > 0){dataReceived = 1;}

        if(myTimer2(delayTime2, currentMillis) == 1){
          Serial.println("250 ms timer done");
          checkForData = 0;
          previousMillis = currentMillis;
          if(dataReceived == 1){
            flashLED = 1;
            previousMillis3 = currentMillis;
            dataReceived = 0;
          }
        }
      }

      // Third event.
      if(flashLED == 1){
        if(doOnce == 0){
          flash(1);
          doOnce = 1;
        }
        if(myTimer3(delayTime3, currentMillis) == 1){
          Serial.println("9 second timer done");
          flashLED = 0;
          flash(0);
          doOnce = 0;
          digitalWrite(LED_BUILTIN, LOW);
        }
      }

      // Fourth event.
      if(myTimer4(delayTime4, currentMillis) == 1 && flashLED == 1){
        //Serial.println("500 ms timer done");
        digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
        previousMillis4 = currentMillis;
      }

    }

    // Function to send data to the NeoPixel device.
    void flash(byte startStop){
      if(startStop == 1){Serial.println("flash function started");}
      if(startStop == 0){Serial.println("flash function ended");}
    }

    // First event timer.
    byte myTimer1(unsigned long delayTime, unsigned long currentMillis){
      if(currentMillis - previousMillis >= delayTime){previousMillis = currentMillis;return 1;}
      else{return 0;}
    }

    // Second event timer.
    byte myTimer2(unsigned long delayTime2, unsigned long currentMillis){
      if(currentMillis - previousMillis2 >= delayTime2){previousMillis2 = currentMillis;return 1;}
      else{return 0;}
    }

    // Third event timer.
    byte myTimer3(unsigned long delayTime3, unsigned long currentMillis){
      if(currentMillis - previousMillis3 >= delayTime3){previousMillis3 = currentMillis;return 1;}
      else{return 0;}
    }

    // Fourth event timer.
    byte myTimer4(unsigned long delayTime4, unsigned long currentMillis){
      if(currentMillis - previousMillis4 >= delayTime4){previousMillis4 = currentMillis;return 1;}
      else{return 0;}
    }

body:
I was wrong being too confident about my whole code. When people suggested posting my whole code, I should have just done it!!!

Anyway, here is the mistake I made. I initialized the variable flash_time as an 8-bit integer. Of course, 8 bit can only hold up to 255. I am trying to store 9000!!! The following code has this bug fixed.

    const long sleep_interval = 3000;
    const long awake_interval = 250;
    const int ledPin = 3;

    const uint16_t flash_time = 9000;  //bug fixed by using uint16_t instead of uint8_t
    const uint16_t t1 = 5;
    const uint16_t t2 = 495;

    void flash() {
        unsigned long x = millis();
        while(millis() - x < flash_time){
            digitalWrite(ledPin, HIGH);
            delay(t1);
            digitalWrite(ledPin, LOW);
            delay(t2);
        }
    }

    void setup() {
        Serial.begin(57600);
        pinMode(ledPin, OUTPUT);
    }

    void loop() {
        unsigned long x = millis();
        while(millis() - x < awake_interval){
            Serial.println("flash time!");
            flash();
        }

        unsigned long y = millis();;
        while (millis() - y < sleep_interval) {  //sleep_interval = 3 secs
            Serial.println("Sleep time!");
        }
    }

So, nested loops that use millis() to determine the terminating conditions work just fine, even if loop 1 runs for 250 ms and loop 2 (that's inside loop 1) runs for much longer, like 9 seconds.

Apologies if I have wasted too much of people's time.


body:
I'm designing a shield for the Arduino Uno with some sensors that require +5V, +3V3 and +3V Vdd. I want to power everything with a single DC adapter so I have a voltage regulator that converts the DC input (+12 - +26V DC) to 5V DC with a maximum current of 1A. That output goes into the 5V sensors, 3V3 and 3V regulators.

Since this is already regulated power can I connect the 5V 1A output to the +5V pin on the Arduino, bypassing the voltage regulator on the Arduino? Or is it better to have another +10V voltage regulator parallel to the 5V regulator that goes into the 9-12V Vin on the Arduino (that than goes to the 5V voltage regulator on the Arduino)?

If I do the first option, is it then save to have the USB connector plugged in?

title: Arduino external 5V power supply

Answers: 0


body:
I wish to control two 3.7V 6x12mm Coreless DC motors (both direction and speed individually). The only constraint is that the motor driver (circuit) has to be as small as possible.

I've seen couple of driver circuits used in quadcopters where a single FET (such as IRLML2502) is used to control the speed of coreless motors. However, the direction control is not possible with such a circuit.

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

It requires at least 6 MOSFETs and maybe Schottky diodes to prevent back EMF (similar to half H-bridge [like here][2]). Even after this, opposite direction control for two motors at once cannot be achieved. Then I figured all of this will increase the area required and decided to replace it with L293DD IC. Now my question is:

1. Can the L293DD SMD IC be used to control these motors?
2. Is there an alternate solution/circuit/IC which can minimize the size and area?
3. Are ESCs required for these small coreless motors? Can they be controlled directly via the L293DD (like normal motors)?

PS: The controller will be ESP8266 and the entire system will powered by a 3.7V 300mAh LiPo battery.

  [1]: https://i.stack.imgur.com/CfeuA.png
  [2]: http://warrantyvoidifremoved.com/formica/circuit-design

title: Can I control two coreless DC motors using L293DD SMD IC?

Answers: 1

body:
> Can the L293DD SMD IC be used to control these motors?

Yes

> Is there an alternate solution/circuit/IC which can minimize the size and area?

Any of the more modern MOSFET based H-Bridge drivers that exhibit far less loss than the antiquated l293d

> Are ESCs required for these small coreless motors?

No

> Can they be controlled directly via the L293DD (like normal motors)?

Yes

The L293 is old and, well, basically crap. For efficient battery based operation you realy need to be looking for something a little more modern and efficient. There's length to choose from - take a look on your favourite electronics supplier (which means *not Amazon*...)