body:
I'm using a DS1307 RTC (https://www.adafruit.com/product/3296) and an Arduino mega microcontroller trying to simply set and read the time of the RTC. However, whenever I try to output anything to the Serial Monitor, I get stuff like this:

[![Example Output][1]][1]

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

The code and the wiring is fairly straightforward which is why I'm confused. I'm just directly attaching the Vcc, GRND, SCL and SDA pins of the clock to the Arduino and using a slightly modified version of the example code as a part of the RTC library Adafruit supplied.

    #include <Wire.h>
    #include "RTClib.h"

    RTC_DS1307 rtc;

    void setup () {
      while (!Serial); // for Leonardo/Micro/Zero

      Serial.begin(57600);
      rtc.begin();

      rtc.adjust(DateTime(2017, 11, 17, 20, 33, 0));

    }

    void loop () {
        DateTime now = rtc.now();

        Serial.print(now.year(), DEC);
        Serial.print('/');
        Serial.print(now.month(), DEC);
        Serial.print('/');
        Serial.print(now.day(), DEC);
        Serial.print(' ');
        Serial.print(now.hour(), DEC);
        Serial.print(':');
        Serial.print(now.minute(), DEC);
        Serial.print(':');
        Serial.print(now.second(), DEC);
        Serial.println();

        Serial.println();
        delay(1000);
    }

So I know I'm doing something wrong but I'm not sure what. Any help would be hugely appreciated.

title: Strange Output from DS1307 RTC

Answers: 1

body:
Change the baud rate to 57600, it specifies at:
    Serial.begin(57600);


body:
I have the same problem as [described on this topic][1]

I needed to set my prescale factor for Timer0 to 1 so I can get a 62.5Khz PWM out of pin 4

My issue is that now the delays() function on my sketches doesn't work correctly.
As mentioned also in the above topic, I've changed the `MICROSECONDS_PER_TIMER0_OVERFLOW` macro on the `wiring.c` library, but this doesn't fix the delay() function.

I understand I need to fix the micros() function as well, however I'm confused on how to address the problem.

Isn't the Timer0 Interrupt overflowing 64 times faster now?
So dividing the micros by 64 shouldn't address the problem

  [1]: https://arduino.stackexchange.com/questions/13518/adjust-time-calculation-after-timer0-frequency-change

title: Arduino Timer 0 in fast PWM mode and micros()

Answers: 0


body:
I am using an Arduino Uno and a DTH11 temperature sensor to read temperature and then send that value to a computer via the serial port.

A NodeJS application is running on the computer and captures that value and writes to a log file.

When I try to get values from my NodeJS application, sometimes the value is broken into two values. `Eg: 25 -> 2 and 5`

This is my Arduino code:

    dht DHT;

    #define DHT11_PIN 7
    float tem [4];

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

    void loop() {
      int chk = DHT.read11(DHT11_PIN);
      int val = (int)(DHT.temperature);
      Serial.println(val);
      delay(600000);
    }

This is my NodeJS program.

    var fs = require('fs')
    var logger = fs.createWriteStream('/data/Temperature/temperature.csv', {
      flags: 'a' // 'a' means appending (old data will be preserved)
    })

    var SerialPort = require("serialport")
    var serialPort = new SerialPort("/dev/ttyACM0", {
      baudRate: 9600,
    });

    serialPort.on("open", function () {
      serialPort.on('data', function(data) {
        var moment = require('moment');
        var dayTime = moment().format('YYYY-MM-DD,hh:mm');
        var val1 = data.toString();
        var val = val1.trim();
        if (val == '') {
          console.log('no data');
        else {
          console.log(val);
          logger.write(dayTime + ',' + val + '\n');
        }
      });
    });

Is it a problem with my code?

Thanks in advance.

title: Arduino Serial data communication with NodeJS

Answers: 1

body: As Look Alterno wrote in a comment, you need to parse the incoming data on the receiving side. In this instance, you have to look for the line terminators. The Node.js serialport module provides a parser for this called [Readline](https://doclets.io/node-serialport/node-serialport/master#dl-ReadLineParser). Read that doc and use it.


body:
I am designing a PCB using a 328P. As I understand it, I can either flash the chip via the ICSP header (without bootloader) or via Serial (if it has a bootloader already). But how does programming actually work?

1. According to my program running on the chip, it acts as master for SPI peripherals. If using ICSP, how does the chip know that it is supposed to act as SPI slave and receive a program?

2. Is there anything I must take into account with regards to what is connected to the SPI pins? i.e. does it harm in any way if I have other SPI slaves on the board connected to these same pins?

3. Same for serial programming: how does the chip know that it's supposed to receive a program on the serial interface, when my application uses this port for a different purpose?

title: Programming standalone 328P in circuit

Answers: 3

body:
> According to my program running on the chip, it acts as master for SPI peripherals. If using ICSP, how does the chip know that it is supposed to act as SPI slave and receive a program?

A special signal is sent using the RESET pin. From [the datasheet (p361)](http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf):

> 1. Power-up sequence: Apply power between VCC and GND while RESET and SCK are set to “0”. In some systems, the programmer can not guarantee that SCK is held low during power-up. In this case, RESET must be given a positive pulse of at least two CPU clock cycles duration after SCK has been set to “0”.
> 2. Wait for at least 20ms and enable serial programming by sending the Programming Enable serial instruction to pin MOSI.
> 3. The serial programming instructions will not work if the communication is out of synchronization. When in sync. the second byte (0x53), will echo back when issuing the third byte of the Programming Enable instruction. Whether the echo is correct or not, all four bytes of the instruction must be transmitted. If the 0x53 did not echo back, give RESET a positive pulse and issue a new Programming Enable command.

----

> Is there anything I must take into account with regards to what is connected to the SPI pins? i.e. does it harm in any way if I have other SPI slaves on the board connected to these same pins?

Yes. It is possible that a chip may respond to the ICSP signals. You should have pullup resistors on all your CS (or SS if you prefer to call it that) pins on all your slave chips so that while the ATMega328P is in programming mode (and all the GPIO pins are in INPUT mode by default) the CS pins of your slaves aren't floating.

----

> Same for serial programming: how does the chip know that it's supposed to receive a program on the serial interface, when my application uses this port for a different purpose?

Simple: it listens for 2 seconds after power-on or reset for a special sequence of bytes arriving on the serial port. If they arrive within that 2-second window (8 seconds for ATMega32U4 based boards, to allow time for USB enumeration) the bootloader keeps running and looking for programming instructions. If it doesn't see that start sequence within the timeout period it exits the bootloader and runs your sketch.

The STK500 protocol (which the Arduino bootloader is based around) is detailed [here](http://www.atmel.com/images/doc2591.pdf). The trigger sequence is the "CMD_SIGN_ON" command detailed on page 4.

body:
1. You pull the reset pin LOW.

> Both the Flash and EEPROM memory arrays can be programmed using the serial SPI bus while RESET is pulled to GND. The serial interface consists of pins SCK, MOSI (input) and MISO (output). After RESET is set low, the Programming Enable instruction needs to be executed first before program/erase operations can be executed.

2. Most SPI devices have a Chip Select pin. Unless this pin reads LOW, the device isn't listening. That way you can have multiple devices sharing a single SPI bus.

3. You pull the reset pin LOW for a moment. That makes the chip reset itself. When the chip resets, it first runs the bootloader program. The Arduino bootloader waits 3 seconds for any programming instructions coming in via the serial connection. If these 3 seconds have past, it will exit the bootloader and run your main sketch.

body:
Simply follow the [hardware design guide from Atmel AVR042][1]

  [1]: http://www.atmel.com/Images/Atmel-2521-AVR-Hardware-Design-Considerations_ApplicationNote_AVR042.pdf


body:
I'm defining a variable as integer and want to use thati

    int specLength = 17;
    int spec[specLength-1];

When I do this, I get the following error message:

     TestProgram:34: error: array bound is not an integer constant before  ']' token
     int spec[specLength-1];

But when I set it up as

    int specLength = 17;
    int spec[16];

it all works fine.

What is the magic here?

Many thanks

title: Integer array definitions: Length

Answers: 1

body:
You have to use a constant expression, one that produce always the same value.

    const int specLength = 17;
    int spec[specLength - 1];

Otherwise, the compiler won't know how much space reserve for the array.

The problem with C/C++ is that the compiler doesn't really know if a variable is modified somewhere or not (thru pointers, for example). You have to tell the compiler that something is `static`, not changing.

You can also use a #define for the same porpuse:

    #define SPEC_LENGTH 17
    int spec[SPEC_LENGTH]

Why both? `const int val=17` means that `val` has a type (`int`). Using `#define` is just a text search-and-replace before compiling. So, SPEC_LENGTH has no type at all. If needed, you have to use a cast, like `(int) SPEC_LENGTH`.


body:
I am receiving this error after reinstalling Arduino IDE (everything was working fine [same components, same code]):

> Board nodemcuv2 (platform esp8266, package esp8266) is unknown

I have recently reinstalled ESP8266 libraries. Could that have caused this issue?

title: Arduino IDE: Board nodemcuv2 (platform esp8266, package esp8266) is unknown

Answers: 1

body:
Did some digging and found a solution that worked for me:

Uninstall (by logically deleting folders) and reinstall ESP Libraries.

Open Arduino IDE
Go to FILE -> PREFERENCES

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

Open the preferences folder (this works in Linux, Mac and Windows)
Go to PACKAGES > ESP8266 > HARDWARE > ESP8266

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

Delete all libraries (if your issue is similar to mine and to others', you should have 2 or more folders, with different versions).

Restart Arduino IDE.
Go to SKETCH > INCLUDE LIBRARY > MANAGE LIBRARIES
Install ESP8266 Community
Go to TOOLS > BOARD and scroll down to your model of NODEMCU

Run compile and your problem should be fixed.

  [1]: https://i.stack.imgur.com/k5Ghz.jpg
  [2]: https://i.stack.imgur.com/z27OA.jpg


body:
I have a LCD that displays a float variable. I would like to show a comma instead of a dot as the decimal separator.

    float temp = 23.50;
    lcd.setCursor(0, 0);
    lcd.print(temp);

I want to show **23,50** instead of **23.50**.

Is there any function to convert or format it?

title: How to use a coma as the decimal separator?

Answers: 3

body:
Print the integer part, print a comma, then print the value minus the integer part.

    float value = 123.45;
    int ival = (int)value;
    int frac = (value - ival) * 100;

    Serial.print(ival);
    Serial.print(",");
    if (frac < 10) Serial.print("0");
    Serial.println(frac);

body:
Due to some performance reasons %f is not included in the Arduino's implementation of sprintf(). A better option would be to use dtostrf() - you convert the floating point value to a C-style string, Method signature looks like:

    char *dtostrf(double val, signed char width, unsigned char prec, char *s)

**Demo**

    void setup() {
      Serial.begin(9600);
      while(!Serial);

      float a = 12.34;
      char buffer[] = "9999.99";
      dtostrf(a, 4, 2, buffer);
      char* p  = strchr(buffer, '.');
      *p = ',';
      Serial.println(buffer);
    }

    void loop() {

    }

The `strchr` search for the first ocurrence of second arg ('.' in this case) and return a pointer to that char. You then use that pointer to sustitute '.' with ','.

You have the final string in buffer, where you can use it for whatever purpose you fancy.

Caution: You have to reserve space (buffer) to hold your biggest value.

body:
May be overkill for this simple usage but, if you are printing numbers
in more than one place in your program, it may be convenient to
implement a filter that replaces all dots with commas.

Here is one such filter:

<!-- language: lang-c++ -->

    // Replace dots with commas.
    class CommaForDot : public Print
    {
    public:
        CommaForDot(Print &downstream) : downstream(downstream) {}
        virtual size_t write(uint8_t c) {
            return downstream.write(c=='.' ? ',' : c);  // replacement
        }
    private:
        Print &downstream;
    };

And here is a simple test:

<!-- language: lang-c++ -->

    void setup()
    {
        Serial.begin(9600);
        float a = 12.34;

        Serial.print("Through Serial:      ");
        Serial.println(a);

        CommaForDot filteredSerial(Serial);
        Serial.print("Through CommaForDot: ");
        filteredSerial.println(a);
    }

    void loop(){}

The output is:

    Through Serial:      12.34
    Through CommaForDot: 12,34


body:
I'm using 3 ESP8266 for my project: one ESP8266 is a server and controls any action.

I want to be able to connect to any ESP8266 with a phone and if that ESP8266 is a client, send data to the server.

I'm using TCP/IP for communication between ESP8266 models and ESP8266 with PC or phone.

My problem is with the number of clients. In ESP8266, a maximum of 5 TCP clients can connect to a server, and my master ESP8266 is using 2 (to connect to the other ESP8266), so that just leaves 3 clients (PC or phone) that can connect to the master ESP8266.

Is there any way to increase the number of clients?

Is there any alternative for communicating between ESP8266 models other than TCP/IP and leave 5 clients in ESP8266 for the user to connect?

title: ESP8266 wifi mesh

Answers: 2

body: You don't need a separate socket for every client. A client connects to server, sends data or gets data and disconnects. Then the next client connects. One server and one client at the time plus one client connection to PC.

body:
If I understand correctly the problem is only 5 clients can connect to an ESP8266 at any one time.  This is an early morning solution to the problem and to be honest I haven't though it through that much, but hopefully its a starting point.

Rather than having all the clients in the mesh connect to the Master node, run an aggregation service on the slaves.  One slave will accept connections fro up to 4 other slaves and it will forward the data to the master.  If you ever wanted more than 5 slave nodes you would need to have the aggregator nodes feeding into another aggregator (like a tree structure). Its quite easy to do statically, but could be tricky if you wanted to do it dynamically.  These aggregators might need to be dedicated nodes, it depends on traffic.

That leaves the master 4 connections for clients.  If that isn't enough then you could send the data from the master to additional ESP8266s acting as dedicated webservers and get the clients to connect to them instead.  There may even be a method of sharing the load between these two web servers in the same way as proper servers do.


body:
I have some small functions to format numbers. I move them to a new file and I would like to import it to my proyect.

I can't find how to do it without defining a class (maybe it's the only way). I would like to import like JavaScript, PHP or other languages: just using the import word or something similar.

I know how to import libraries. Example:

    #include <OneWire.h>
    #include <DallasTemperature.h>

title: How to import my own library or file?

Answers: 1

body:
If the file is in your sketch folder then you use this syntax:

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

    #include "foo.h"

All source files in the root of the sketch folder are shown as tabs in the Arduino IDE. In some cases that might not be desirable. If so, you can put the file in the `src` subfolder of your sketch folder and use this syntax:

    #include "src/foo.h"

Or you might want to group files together into separate subfolders:

    #include "src/foo/foo.h"

If you want to access the file from multiple sketches then you should turn it into a library and use this syntax:

    #include <foo.h>


body:
I have a 16x2 LCD and I want to show a temperature: **23 ºC**.

But the **º** symbol is not properly shown. It shows a strange character instead of the **º** symbol .

title: How to show the º character in a LCD?

Answers: 4

body:
Easy.

1. Pull up the datasheet and pick the character that most resembles your symbol. Char 0b11011111 looks the best to me but 0b10110000 isn't bad.

2. While you are in the datasheet, check out CGRAM.

body:
It depends on the exact model of LCD you are using. Or more exactly, on the Dot Matrix Liquid Crystal Display Controller/Driver, like the Hitachi HD44780U that is used in many 16x2 LCD.

For that driver, you have a table of native chars, like this:

[![LCD Character Set - source: mil.ufl.edu][1]][1]

In this table, the char "°" is at col 0b1101, row 1111, (0xDF, or 223). But, you have to cast that value to a char before displaying, otherwise you will get the value (223), not the symbol.

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

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

    void setup()
    {
      lcd.init();                      // initialize the lcd
      lcd.backlight();
      lcd.print("temp 27");
      lcd.print((char) 223);
      lcd.print(" ");
      lcd.print(223);

    }

    void loop()
    {
    }

  [1]: https://i.stack.imgur.com/1TKZH.gif "LCD Character Set - source: mil.ufl.edu"

body:
Some displays have different characters above 128. It is best to make your own character.

That is what @dannyf ment with "CGRAM". The custom characters are stored in CGRAM. There is no need to read the datasheet though, because there is a function in the Arduino LiquidCrystal library for it.

Start here: [Arduino CreateChar reference][1]
There are even websites that help you to create the character: [omerk][2] and [maxpromer][3].

  [1]: https://www.arduino.cc/en/Reference/LiquidCrystalCreateChar
  [2]: https://omerk.github.io/lcdchargen/
  [3]: http://maxpromer.github.io/LCD-Character-Creator/

body:
do `lcd.write(223);`
Transform the Decimal into an ASCII symbol.


body:
So, I naively bought two of these JX PDI-6221MG Digital Servos thought they would work with the Arduino straight out of the box, just like MG996R did, for instance, but it seems they won't. However, I hear some clicking noise when the motor is connected, tho.

These are the Servo specs:

    Dead band: 2μs
    Working frequence: 1520μs / 330hz
    Operating Speed (4.8V): 0.18 sec/60°
    Operating Speed (6V): 0.16 sec/60°
    Stall Torque (4.8V): 17.25 kg/cm
    Stall Torque (6V):  20.32 kg/cm
    Dimensions: 40.5X20.2X38mm
    Weight:  62 g
    Connector Wire Length: JR  265 mm
    Bearing: 2BB

Manufacturer site: http://www.jx-servo.com/English/Product/49513727.html

Additionally, I used 5V 2.4A power input alongside with the Arduino Nano running just some sample 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(3);  // attaches the servo on pin 9 to the servo object
    }

    void loop() {
      for (pos = 0; pos <= 180; 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(15);                       // waits 15ms for the servo to reach the position
      }
      for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        delay(15);                       // waits 15ms for the servo to reach the position
      }
    }

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

I tested the same configuration with MG996R and SG90 and it worked. So what am I missing here?

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

title: Controlling JX PDI-6221MG Digital Servo with Arduino

Answers: 2

body: I managed to get servos running with 6 V and 3 A powered from lab power supply (GOPHERT CPS-1620 0-16V 0-20A). I guess, at the end, it was power supply which was crucial.

body: If you connect the servo to the same power supply as the MPU make sure you have a robust amperage rating.  As soon as the servo tries to move, the current draw shoots way up and your MPU will hit a brownout state and reboot.  At the very least you will need a capacitor at the power input to the MPU.


body:
When I connect my Arduino Uno board it instantly detects the board and shows it in the list. But when I connect my new Uno + Wifi board it doesn't detect it. I also manually selected Arduino Uno Wifi but it still gives me the message

`Error uploading check if the selected board is currently available`

How can I fix this?

This is the one that's not working:

[Arduino Uno + Wifi][1]

While this one I got does work:

[Arduino Uno][2]

  [1]: https://www.aliexpress.com/item/UNO-WiFi-R3-ATmega328P-ESP8266-8Mb-memory-USB-TTL-CH340G-Compatible-for-Arduino-Uno-NodeMCU-WeMos/32739934767.html?spm=a2g0s.9042311.0.0.WA5MYA
  [2]: https://www.aliexpress.com/item/Arduino-UNO-R3-Official-Genuine-Chinese-Version/32824877267.html?spm=2114.search0104.3.1.dX8tcR&ws_ab_test=searchweb0_0,searchweb201602_2_10152_10065_10151_10344_10068_10345_10342_10343_10340_10341_10541_10562_10084_10083_10304_10307_10301_10177_10060_10155_10154_10539_10312_10059_10313_10314_10534_10533_100031_10103_10073_10594_10557_10596_10595_10142_10107,searchweb201603_14,ppcSwitch_5&btsid=38a8ce51-b63b-4aaf-9e1a-be69a7e114e1&algo_expid=4321f1cc-8e32-4caa-abad-e6d67a3cb87e-0&algo_pvid=4321f1cc-8e32-4caa-abad-e6d67a3cb87e&rmStoreLevelAB=0

title: Arduino Uno board works but Arduino Uno + Wifi is not being detected

Answers: 1

body:
What you have there is a cheap Chinese clone. It uses the cheap CH340G USB chip instead of the proper ATMega16u2 that real Arduinos use.

Install the right drivers and it should start working.


body:
Hi I am working on small project where I want to run ws2812b module via arduino and lipo battery. I have purchased 64 matrix for ws2812b from eBay and lipo battery with 500mah.

I am looking to find how I can calculate how much power does WS2818b modules will consume with all leds running and will the battery be sufficient for it. How long will it run on full charge.

Can someone please point me to the formula how I can calculate this. Also to note I am using a power up converter from 3.7 to 5v.

title: Calculate power requirement for 64 rgb led ws2812b

Answers: 1

body:
If all LEDs are in full bright white, assume 60mA per LED. 64 would mean a maximum current draw of 64*60mA=3840mA. This figured would not include the Arduino itself.

a 500mAh battery could power this for no more than 7.8 minutes (500mAh / 3840mA = 0.17 hours = 7.8 minutes)

If your usage will not be full bright 100% if the time, then you could run longer.

You didn’t say how long you want it to run. Perhaps start with the design goal before specifying parts.

For a more realistic view of how much power it takes, measure with a multimeter the current draw from the battery or bench power supply to your boost converter while displaying a typical usage on the matrix. Use calculations as above to determine the expected battery lifespan.


body:
I have radiator valves that send readings about the temperature and valve opening to the serial output: [Honeywell HR-25][1].

I want to collect those readings in a central server at home without flashing the thermostat with a custom firmware.

To do that, I need an Arduino (very bare one) that can receive the serial data, but at the same time I need it to be powered down most of the time, or it would kill the battery life of the thermostat.

Can I wake up an Arduino from power down using the serial transmission, and immediately capture the serial data without dropping bits? how?

  [1]: http://www.homexpertbyhoneywell.com/en-DE/Products/rondostat/Pages/HR-25.aspx

title: Is it possible to power up Arduino upon serial transmission without dropping data?

Answers: 3

body:
I never tried myself, but afaik you can define an wake up/interrupt from USART, meaning that if you get a receiving byte from the UART it will wakeup the Arduino.

When powered up, you can read continuous data. I would be surprised if they make an UART wakeup signal, that bytes would be lost (i.e. that powering up would take too long to miss more UART bytes).

body:
I don't think you can use the HW peripheral, so IF you really want/need low power you will need something like this (note: this may be very overkill for your application)

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

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

<!-- End schematic -->

NOTE: I assume the "serial" is a UART and its "rest" voltage is 5V. Choose the PMOS so that it is turned on with about 3V.

In this case, the circuit is normally powered off. When you receive a START, the PMOS start conducting. The ATMEL will then pull pin B to 5V, thus keeping the circuit powered. Through pin A it can sense the UART.

In this case, since you miss the start bit, you won't be able to use the usual libraries or peripherals. You can, however, implement a software uart which can avoid the first start bit to overcome this.

Just a suggestion, however. If your thermostat is transmitting frequently, maybe a more useful approach can be to listen to one transmission, then put everything to sleep for let's say 30 seconds, then turn on again and wait for the first serial transmission. This can be simpler than this solution and more effective

body:
You can build a circuit using an electronic counter to only start supplying power to the Arduino at a specific given time. You would still need to supply the circuit, but the energy need would be a small fraction of the Arduino's needs.

On the other hand, can't you use a second power source for the Arduino? Li-On batteries are pretty cheap nowadays, and you can always savage something from an old Notebook's battery.


body:
I have been using an Arduino Nano as a PWM controller for a heating element.

I am currently using **D11** (PB3). I could change, although all pins with PWM are in use, and would require a re-write and re-wire.

This produces a signal at ~490Hz, but I would like to experiment with changing this to a higher frequesncy.

I gather it its possible to vary the frequency by changing the divisor from its default 64.

My sketch uses Uses http://playground.arduino.cc/Main/SevenSegmentLibrary and calls millis() - will changing PWM divisor impact on either of these?

NOTE I have read the `setPwmFrequency` documentation, but find "disrupts the normal operation" unhelpful - I am actually after some explanation of the concrete effect. I only use `millis()` to time button presses and flash a LED, which are not time critical

*Please keep in mind that changing the PWM frequency changes the Atmega's timers and disrupts the normal operation of many functions that rely on time (delay(), millis(), Servo library).*

I have been doing some further study. http://playground.arduino.cc/Code/PwmFrequency states  *Changes on pins 3, 5, 6, or 11 may cause the delay() and millis() functions to stop working.*

Other references say 3, 11 use `timer 2` so **do they affect `millis()` or not** as other references claim `timer 0` is used for these.

title: Arduino Nano PWM frequency

Answers: 3

body:
Depends on the pin you used for the PWM.

***Arduino UNO/NANO specs say following things:***

The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.

The base frequency for pins 5 and 6 is 62500 Hz.

The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64, 256, and 1024.

The divisors available on pins 3 and 11 are: 1, 8, 32, 64, 128, 256, and 1024.

PWM frequencies are tied together in pairs of pins. If one in a pair is changed, the other is also changed to match.

Pins 5 and 6 are paired on timer0.

Pins 9 and 10 are paired on timer1.

Pins 3 and 11 are paired on timer2.

**Changes on pins 3, 5, 6, or 11 may cause the delay() and millis() functions to stop working. Other timing-related  functions may also be affected.**

body:
I don't know where this misinformation comes from... The answer is
**no**, reconfiguring Timer 2 does **not** affect `millis()` nor
`delay()`, as these functions rely on Timer 0. AFAIK the Arduino core
does not use Timer 2 at all. But note that there may be other Arduino or
third party libraries that rely on Timer 2.

You can see here the [source code of `millis()` and
`delay()`][wiring.c].

As MITU RAJ correctly states in his answer, the PWM signal on pin 11 is
provided by Timer 2, so you can use it safely.

[wiring.c]: https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring.c

body:
The answer is **NO**, changing the PWM divider for pin 11 will not affect the `millis()` function (nor `delay()`).

----------

**Explanation:**
The [Arduino Nano][1] uses the ATMega328P microcontroller, same as the [Arduino Uno][2].

Pin 11's PWM is controlled by Timer 2. By default Timer 2 has a prescale of 64 (ie. setting 0x04). The base frequency of Timer 2 is 31372.55 Hz resulting in a frequency of 490.2 Hz (ie. 31372.55/64 = 490.1961).

On the other hand, the microsecond timer (ie. the one used by `millis()`, `micros()`, `delay()` and `delayMicroseconds()`) is controlled by Timer 0.

So changing the prescaler of Timer 2 will not affect `millis()`.

It will however change the PWM frequency of Pin 3.

----------

**Back to your question:**
The possible PWM frequencies of Pin 11 (higher than 488 Hz) are:

31373 / 32 = 980.4 Hz
31373 / 8 = 3921.6 Hz
31373 / 1 = 31373 Hz

Where 32, 8, 1 are the prescaler.
Which equates to a setting value of 0x03, 0x02 & 0x01 respectively.

Add this line of code:

    TCCR2B = TCCR2B & 0b11111000 | setting;

Where `setting` is the value of the setting for the respective prescaler.

    ============================================
    || Frequency [Hz] || Prescaler || Setting ||
    ============================================
    || 31373.55       || 1         || 0x01    ||
    || 3921.57        || 8         || 0x02    ||
    || 980.39         || 32        || 0x03    ||
    || 490.20         || 64        || 0x04    ||
    || 245.10         || 128       || 0x05    ||
    || 122.55         || 256       || 0x06    ||
    || 30.64          || 1024      || 0x07    ||
    ============================================

Source code: [https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring.c][3]

  [1]: https://store.arduino.cc/usa/arduino-nano
  [2]: https://store.arduino.cc/usa/arduino-uno-rev3
  [3]: https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring.c


body:
Is it possible to connect to one of these, which run at 12v, to turn on the LED strip using an ESP8266? It doesn't matter if it's an Arduino or the ESP8266, both should be able to do this. The board looks like this:

<img src="https://i.stack.imgur.com/n6s6w.jpg" />

If I turn on the red light, the "R" gets grounded and therefore applies 12v to the rail. The 3 MOSFETs on the images are P0903BDG MOSFETs.

Alternatively, I can hook into the IR signal and send an IR signal using the ESP8266. That would be really awesome, as it only requires 3 wires. How that is possible, I'm not really sure, though.

I know it's possible to make your own circuit using IRLZ44N MOSFETs, which I have done before, but I want to try and use as much as this circuit as possible.

title: Control LED strip IR controller using Arduino

Answers: 1

body:
I tried to do the same thing with hooking up an IR LED on a Raspberry Pi. It worked pretty well but the chip on the receiver board could not take fast switchings. I ended up doing my own PCB.

The problem is that the chips run at voltages higher than you would use for an ESP8266 or Arduino. This will be the biggest problem if you want to supply it with the voltages available on the board.

I think the safest thing is to see if you can simulate IR input by just connecting to GND and OUT of the IR receiver port.


body:
We are trying to communicate between multiple Arduino's (in this example a Nano and a Mega) and a Raspberry Pi. The Raspberry pi is defined as master and the Arduino's as slaves. We would also like that the Arduino's communicate between each other. For example: The Mega requests from the Nano and at some point, the Mega also communicates with the Raspberry Pi. This is the short version of what we are trying to accomplish but we ran into the problem that the i2c communication failed between the Nano and Mega upon the request from the Mega to the Nano.

**Schematic**
[![Schematic][1]][1]

**Problem**

After some time the i2c bus 'fills' up...

[![Problem][2]][2]

**Code Nano**

(We send RFID data to Mega)

    #include <Wire.h>
    #include "SPI.h"
    #include "MFRC522.h"

    #define SS_PIN 10
    #define RST_PIN 9
    #define SP_PIN 8

    MFRC522 rfid(SS_PIN, RST_PIN);

    MFRC522::MIFARE_Key key;

    void setup() {
      Serial.begin(9600);
      SPI.begin();
      rfid.PCD_Init();

      Wire.begin(0x10);
      Wire.onRequest(requestEvent);
    }

    void loop() {

    }

    void requestEvent() {
      if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial())
        return;

      // Serial.print(F("PICC type: "));
      MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
      // Serial.println(rfid.PICC_GetTypeName(piccType));

      // Check is the PICC of Classic MIFARE type
      if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
          piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
          piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
        Serial.println(F("Your tag is not of type MIFARE Classic."));
        return;
      }

      String strID = "";
      for (byte i = 0; i < 4; i++) {
        strID +=
          (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
          String(rfid.uid.uidByte[i], HEX) +
          (i != 3 ? ":" : "");
      }
      strID.toUpperCase();
      //81:AE:1D:29
      Serial.print("Send to Mega: ");
      Serial.println(strID);

      Wire.write(strID.c_str());

      rfid.PICC_HaltA();
      rfid.PCD_StopCrypto1();

    }

**Code Mega**

    #include <Wire.h>

    void setup() {
      Wire.begin(0x03);
    }

    void loop() {
      Wire.requestFrom(0x10, 11);

      String uid = "";

      while (Wire.available()) {
        char c = "";
        c = Wire.read();
        uid += c;
      }

      if (uid.indexOf(':') != 2) {
        return;
      }

      Serial.println(uid);

      delay(500);
    }

We would like to communicate between the Arduino's when the Raspberry Pi is master.

  [1]: https://i.stack.imgur.com/KXilP.png
  [2]: https://i.stack.imgur.com/pdxLr.png

title: Arduino I2C communication between Raspberry Pi

Answers: 2

body: Its a long time since I used a Pi, but isn't it a 3.3V device and the Arduinos are 5V devices.  I think you may need a logic level shifter (not a resistor divider).  I suspect that's the reason I2Cdetect isn't working and without that working, nothing else will.

body: Pi and arduino works at different logic level bro. Also you gotta check if pull up resistors are needed in the SDA lines of I2C bus. I suspect internal pullups of UNO are not really useful. Use 2.2K pull-ups externally.


body:
I've tried to modify this code, but everything I tried failed.
Where am I going wrong?

All I want to happen is when button 1 is pressed LED 1 fades up and when released LED 1 fades out and the same again with the 2nd LED when button 2 is pressed LED 2 fades up and when released it fades out.

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

    int ledpin = 10;
    int ledpin1 = 11;
    int pushbutton = 7;
    int pushbutton1 = 8;

    int brightness = 255;
    int fadeamount = 1;

    void setup ()
    {
      pinMode (ledpin,OUTPUT);
      pinMode (ledpin1,OUTPUT);
      pinMode (pushbutton,INPUT);
      pinMode (pushbutton1,INPUT);
    }

    void loop ()
    {
      if( digitalRead(pushbutton)==HIGH && brightness<255 )
      {
        // fade in ledpin
        brightness = brightness + fadeamount;// increase brightness
        if( brightness>255 ) // check that brightness doesn't exceed 255
          brightness = 255;
        analogWrite(ledpin,brightness);
        delay (1);
      }
      else if( digitalRead(pushbutton)==LOW && brightness>0 )
      {
        // fade out ledpin
        brightness = brightness - fadeamount;// decrease brightness
        if( brightness<0 ) // check that brightness doesn't go below 0
          brightness = 0;
        analogWrite(ledpin,brightness);
        delay (1);

      }

      if( digitalRead(pushbutton1)==HIGH && brightness<255 )
      {
        // fade in ledpin1
        brightness = brightness + fadeamount;// increase brightness
        if( brightness>255 ) // check that brightness doesn't exceed 255
          brightness = 255;
        analogWrite(ledpin1,brightness);
        delay (1);
      }
      else if( digitalRead(pushbutton1)==LOW && brightness>0 )
      {
        // fade out ledpin1
        brightness = brightness - fadeamount;// decrease brightness
        if( brightness<0 ) // check that brightness doesn't go below 0
          brightness = 0;
        analogWrite(ledpin1,brightness);
        delay (1);

      }

    }

title: I am having trouble with fading two LEDs

Answers: 2

body:
Create 2 sets of brightness, fadeamount variables, one for each button/LED. You can put them in a struct to make things simpler:

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

    struct brightness {
        int brightness;
        int fadeamount;
        int ledpin;
        int pushbutton;
    };

    struct brightness set1;
    struct brightness set2;

Then initialize them in init.

The LED goes from full brightness to off in 0.255 seconds. That is pretty quick.

You can add a `millis()` based timer on the brightness change:

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

    struct brightness {
        int brightness;
        int fadeamount;
        int ledpin;
        int pushbutton;

        //add the following
        unsigned long timeChanged;
        unsigned long timeBetweenChanges;
    };

    void handleButtonFade(struct brightness* set){
          if( millis() - set.timeChanged < set.timeBetweenChanges)
              return;

          if(digitalRead(set1.pushbutton)==HIGH && set.brightness<255 )
          {
            // fade in ledpin
            set.brightness = set.brightness + set.fadeamount;// increase brightness
            if( set.brightness>255 ) // check that brightness doesn't exceed 255
              set.brightness = 255;
            analogWrite(set.ledpin,set.brightness);
          }
          else if( digitalRead(set.pushbutton)==LOW && set.brightness>0 )
          {
            // fade out ledpin
            set.brightness = set.brightness - set.fadeamount;// decrease brightness
            if( set.brightness<0 ) // check that brightness doesn't go below 0
              set.brightness = 0;
            analogWrite(set.ledpin,set.brightness);

          }

    }

    void loop(){
        handleButtonFade(&set1);
        handleButtonFade(&set2);
    }

body:
Small Change in these lines :

 - if( digitalRead(pushbutton)==HIGH && **brightness<=255** )

 - else if( digitalRead(pushbutton)==LOW && **brightness>=0** )

Also change delay to delay(10) something, instead of delay(1). Only then, human eye can observe that change in brightness from 0-255 :-)

Also adding a capacitor to reduce the debounce in your pushbutton would be a thing to do.


body:
I am measuring pressure in bars from OsiSense™ XMLP pressure sensor (4-20 milliamp) on a arduino uno.  When the machine im measuring pressure on is switched off the reading is 0v as expected.
When the machine is on (the sensor is on) the reading is 1v as expected.
When the machine is on and hydraulics are active the voltage fluctuates as expected.

The problem I have is I don't know the maths to translate the voltage to bar pressure.

From a previus question i've asked from 0v to 5v the equation is:

    // This is for the DEFAULT 5V analog reference.
    // v = the voltage at the pin in Volts.
    // p = the pressure in bar.
    // Note that 'bar' is the pressure relative to the
    // normal atmospheric pressure at that moment.
    float v = (float) analogRead(A0) / 1024.0 * 5.0;
    float p = v / 5.0 * 100.0;"

Is it just a matter of changing the equation to take into account the 1v when the sensor has power and then dividing by 4 instead of 5:

    RawVoltage = (float) analogRead(A0) - 1;
    float v = RawVoltage / 1024.0 * 4.0;
    float p = v / 5.0 * 100.0;"

title: 4-20 milliamp to volts to pressure maths

Answers: 1

body:
If I understand your question correctly, when the sensor is on,

* 4 mA (1 V on the Arduino) means 0 bar
* 20 mA (5 V on the Arduino) means 100 bar.

Is that correct?

If that is correct, there you just have to linearly map the voltage
range to the pressure range. The equation is

P = (v − 1 V) / 4 V × 100 bar

or, in C++:

    float v = analogRead(A0) / 1024.0 * 5.0;  // in volts
    float p = (v - 1) / 4 * 100;              // in bars


body:
Trying to run the below code but getting the following error message:

> exit status 1 expected unqualified-id before '==' token

Code is as follows:

    ==============================================
    = Arduino SOS CAll sim900 shield Project =
    = with Arduino =
    = http://www.mrmodder.com =
    ==============================================
    #include "SIM900.h"
    #include <SoftwareSerial.h>
    #include "call.h"

    #define ACTIVE LOW

    const int ledPin = 13; // the number of the LED pin

    CallGSM call;
    boolean started=false;
    int buttonState = 1;
    const int buttonPin = 7; // the number of the pushbutton pin
    boolean calling = false;

    void setup()
    {

    Serial.begin(9600);
    pinMode(ledPin,OUTPUT);
    pinMode(buttonPin, INPUT);
    digitalWrite(buttonPin,HIGH);
    if (gsm.begin(9600))
    {
    Serial.println("\nstatus=READY");
    started=true;
    }
    else
    Serial.println("\nstatus=IDLE");
    }

    void loop()
    {
    buttonState = digitalRead(buttonPin);
    if (buttonState == ACTIVE) {
    if(calling)
    {
    digitalWrite(ledPin,LOW);
    calling = false;
    call.HangUp();
    delay(1000);
    }else
    {
    calling = true;
    digitalWrite(ledPin, HIGH);
    delay(1000);
    call.Call("+300000000000"); //Insert telephone number here

    }

https://mrmodder.com/make-a-call-using-gsm-module-arduino/

Have a GSM shield and trying to call a preset number using the above tutorial but I cant get the code to run properly

title: Arduino GSM shield code help

Answers: 1

body:
**This is where the problem is:**

==============================================

= Arduino SOS CAll sim900 shield Project =

= with Arduino =

= http://www.mrmodder.com =

==============================================

**COMMENT THIS WHOLE TEXT using**

**/* [insert text here] */**


body:
I want to know why to declare variables with static volatile and arrays with only static in TWI library?

For example;

    static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
    static volatile uint8_t twi_masterBufferIndex;
    static volatile uint8_t twi_masterBufferLength;

title: Why using static volatile for variables and only static for arrays in TWI library?

Answers: 1

body:
You use `volatile` to mark variables that are going to change at any moment, in a ISR (Interrupt Service Routine) typically.

You mark them so the compiler doesn't optimize, and always go and pick its actual value. If you don't do that, then an ISR may update a variable while the main "thread" of execution keeps using its old value. That's is a nasty situation to debug.

You only need to mark variables that are used both in the ISR and in the main sketch. If `twi_masterBuffer` is not changed inside an ISR, you don't need to mark it with `volatile`.

`static` is used inside function to mark variables that need to be permanent, i.e., keep their values between calls, but not accessible from outside that function.


body:
I am new to Arduino and am trying to implement different rotational speeds for a stepper motor. I am using a Nema 17 bipolar stepper motor, a Big Easy Driver, and an Arduino Uno.

I've been trying to modify a tutorial code such that it will run at variable speeds:

    //Declare pin functions on Arduino
    #define stp 2
    #define dir 3
    #define MS1 4
    #define MS2 5
    #define MS3 6
    #define EN  7

    //Declare variables for functions
    char user_input;
    int x;
    int y;
    int state;

    #include <AccelStepper.h>
    #include <Stepper.h>
    Stepper stepper1 (1,stp,dir);

    void setup() {

      pinMode(stp, OUTPUT);
      pinMode(dir, OUTPUT);
      pinMode(MS1, OUTPUT);
      pinMode(MS2, OUTPUT);
      pinMode(MS3, OUTPUT);
      pinMode(EN, OUTPUT);
      resetBEDPins(); //Set step, direction, microstep and enable pins to default states
      Serial.begin(9600); //Open Serial connection for debugging
      stepper1.setSpeed(1);
      Serial.println("Begin motor control");
      Serial.println();
      //Print function list for user selection
      Serial.println("Enter number for control option:");
      Serial.println("1. Turn at default microstep mode.");
      Serial.println("2. Reverse direction at default microstep mode.");
      Serial.println();

    }

    //Main loop
    void loop() {
      while(Serial.available()){
          user_input = Serial.read(); //Read user input and trigger appropriate
    function
          digitalWrite(EN, LOW); //Pull enable pin low to set FETs active and allow motor control
          if (user_input =='1')
          {
             StepForwardDefault();
          }
          else if(user_input =='2')
          {
            ReverseStepDefault();
          }
          else
          {
            Serial.println("Invalid option entered.");
          }
          resetBEDPins();
      }
    }

    //Reset Big Easy Driver pins to default states
    void resetBEDPins()
    {
      digitalWrite(stp, LOW);
      digitalWrite(dir, LOW);
      digitalWrite(MS1, LOW);
      digitalWrite(MS2, LOW);
      digitalWrite(MS3, LOW);
      digitalWrite(EN, HIGH);
    }

    //Default microstep mode function
    void StepForwardDefault()
    {
      Serial.println("Moving forward at default step mode.");
      digitalWrite(dir, LOW); //Pull direction pin low to move "forward"
      for(x= 1; x<4000; x++)  //Loop the forward stepping enough times for motion to be visible
      {
        digitalWrite(stp,HIGH); //Trigger one step forward
        delay(1);
        digitalWrite(stp,LOW); //Pull step pin low so it can be triggered again
        delay(1);
      }
      Serial.println("Enter new option");
      Serial.println();
    }

    //Reverse default microstep mode function
    void ReverseStepDefault()
    {
      Serial.println("Moving in reverse at default step mode.");
      digitalWrite(dir, HIGH); //Pull direction pin high to move in "reverse"
      for(x= 1; x<4000; x++)  //Loop the stepping enough times for motion to be visible
      {
        digitalWrite(stp,HIGH); //Trigger one step
        delay(1);
        digitalWrite(stp,LOW); //Pull step pin low so it can be triggered again
        delay(1);
      }
      Serial.println("Enter new option");
      Serial.println();
    }

Adjusting the potentiometer on the Big Easy Driver will either stop the motor turning completely or run at a constant speed regardless of further adjustment.

Do you have any suggestions for debugging my code, or are there other functions I should be using in addition to/instead of those I have?

title: How can I change the speed of a stepper motor?

Answers: 1

body:
Do you understand how a stepper works?  You send it pulses and it steps for each pulse you send it.  The faster you send the pulses the faster it will run.  The slower you send the pulses the slower it will run.  You have lines in your code like this:

    void StepForwardDefault()
    {
      Serial.println("Moving forward at default step mode.");
      digitalWrite(dir, LOW); //Pull direction pin low to move "forward"
      for(x= 1; x<4000; x++)  //Loop the forward stepping enough times for motion to be visible
      {
        digitalWrite(stp,HIGH); //Trigger one step forward
        delay(1);
        digitalWrite(stp,LOW); //Pull step pin low so it can be triggered again
        delay(1);
      }
      Serial.println("Enter new option");
      Serial.println();
    }

Can you see the part that is sending HIGH and LOW to your step pin?  See the delay that is determining how fast those pulses go out?  Can you imagine how you might change that delay so that the pulses go out faster or slower?  Here's a hint, delay works in milliseconds, but if you want to go faster than this then you'll need to work in microseconds.  Can you find the version of delay that works in microseconds in the Arduino reference?


body:
# Problem #
I have a few large objects in my code that need global visibility, but creating them seems to eat up memory significantly faster than simple math would dictate, and furthermore, using them differently in code seems to change how much RAM the compiler tells me I have left for local variables.

**How do I optimize the use of my RAM while still being able to use an object in both my `setup()` and my `loop()` functions?**

Note: Skim the **Pseudo-Code** section and then skip to the **Discussion** section if want to get to the meat of my question (I just wanted to provide plenty of background, if needed).

# Test Code #
To demonstrate that reported global RAM usage changes due not only the number of variables I define globally, but **how those variables are used in code**, I created a test program.  I compiled this code on the Arduino IDE on a Mac, and ran this on multiple Elegoo Nanos.

Please forgive the particularly long "minimal" complete verifiable code, but it has a bit going on.  Here's the pseudo-code for it.
### Pseudo-Code ###
"T" (for tested) before a line means that I commented out a line or left it be depending on what test I was running:

    Define a function to check how much memory remains, freeRam() (taken from https://playground.arduino.cc/Code/AvailableMemory, bottom of page)
    Create a class that uses a ton of RAM, about 1024B (GinormousClass)
    Create a wrapper for GinormousClass (GinormousClassWrapper) that may or may not construct the GinormousClass, based on how it is implemented

    Global scope:
    Run freeRAM() to see how much initial RAM is available before setup() is run.
    T Create a global pointer to the wrapper class

    Local scope (setup):
    Report initial RAM
    T Create a local pointer to the wrapper class
    T Assign a newly constructed wrapper object to the pointer, which does NOT instantiate the huge class
        Report how much RAM remains after creation and after deletion
    T Assign a newly constructed wrapper object to the pointer, which DOES instantiate the huge class
        Report how much RAM remains after creation and after deletion

Note: Remaining RAM before creation and after deletion were always the same.

### Actual Code ###

    #define ARRAY_SIZE 256

    // Method to determine how much memory is left (https://playground.arduino.cc/Code/AvailableMemory, bottom of page)
    int freeRam() {
      extern int __heap_start, *__brkval;
      int v;
      return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
    };

    // Define a class that uses a ton of RAM
    class GinormousClass {
      public:
        GinormousClass() { // Fill array with (kind of) random numbers
          for (int i = 0; i < ARRAY_SIZE; i++) {
            BIG[i] = random(1000);
          }
        };

        long BIG[ARRAY_SIZE]; // Have this class control a huge array
    };

    // Define a class that has the potential to use a ton of RAM
    class GinormousClassWrapper {
      public:
        GinormousClassWrapper(bool createGiantObject) { // Constructor
          if (createGiantObject) {
            // Create a GinormousClass object (use a ton of RAM)
            gPointer = new GinormousClass();
          } else {
            // Do not create GinormousClass object
          }
        };

        ~GinormousClassWrapper() { // Delete the Ginormous Class, if it exists
          if (gPointer) {
            delete gPointer;
          }
        }

        GinormousClass *gPointer = NULL; // Initialize pointer to NULL
    };

    int initialFreeRam = freeRam(); // Figure out how much RAM is available before the fun begins
    GinormousClassWrapper *ginny; // Declare a GLOBAL pointer to the potentially enormous class

    void setup() {
      // Start the Serial connection, and get the initial amount of RAM
      Serial.begin(9600);
      Serial.print("Initial free RAM: ");
      Serial.println(initialFreeRam);

      //  GinormousClassWrapper *ginny; // Declare a LOCAL pointer to the potentially enormous class

      // Try making the class, without defining the array
      Serial.println("Making Ginormous Class (do nothing constructor)...");
      ginny = new GinormousClassWrapper(false);

      Serial.print("Current free RAM: ");
      Serial.println(freeRam());
      Serial.println();

      // Delete the class
      Serial.println("Deleting first class...");
      delete ginny;

      Serial.print("Current free RAM: ");
      Serial.println(freeRam());
      Serial.println();

      // Try making the class, WITH defining the array
      Serial.println("Making Ginormous Class (use a ton of RAM constructor)...");
      ginny = new GinormousClassWrapper(true);

      Serial.print("Current free RAM: ");
      Serial.println(freeRam());
      Serial.println();

      //  Delete the class
      Serial.println("Deleting second class...");
      delete ginny;

      Serial.print("Current free RAM: ");
      Serial.println(freeRam());
      Serial.println();
    };

    void loop() {

    };

# Results #
I've collected the RAM reported at 4 different times:

 1. after compilation
 2. before `setup()`
 3. after the "do-nothing" construction of the wrapper
 4. after the "use-space" construction of the wrapper

5 different scenarios were tested:

 1. no pointer declared/wrapper not constructed
 2. pointer declared but object not constructed
 3. do-nothing constructor used
 4. use-space constructor used
 5. do-nothing constructor used, object deleted, and use-space constructor used

### Raw Results: ###
Numbers are amount of RAM left, in bytes

    0 Not declared:
     Compiler: 1836
     Initial: 1830
     Do-nothing constructed: N/A
     Use-space constructed: N/A

    1 Declared global, not constructed:
     Compiler: 1836
     Initial: 1830
     Do-nothing constructed: N/A
     Use-space constructed: N/A

    2 Declared global, constructed do-nothing:
     Compiler: 1734
     Initial: 1728
     Do-nothing constructed: 1724
     Use-space constructed: N/A

    3 Declared global, constructed use-space:
     Compiler: 1722
     Initial: 1716
     Do-nothing constructed: N/A
     Use-space constructed: 686

    4 Declared global, constructed both:
     Compiler: 1648
     Initial: 1640
     Do-nothing constructed: 1636
     Use-space constructed: 610
Note: Local pointer instead of global pointer had no change except increase all reported RAM by 2 bytes.

# Discussion #
In the raw results, the GinormousClassWrapper takes 4B when constructed (the pointer it owns) and GinormousClass takes about 1024B when constructed (exactly 1030B, we can assume there's some overhead).  However, one strange thing is of note:

The amount of room stated by the compiler to be available for local variables **decreases significantly** when the wrapper is constructed  versus when it is not (1836B down to 1640B when both constructors are used).  I would **expect** that the amount of RAM used by globals would not change, because technically only the pointer is in global scope.  If it is SUPPOSED to change according to how the pointer is used, then why does it change by 196B, of all numbers?

I am assuming that the RAM given by the compiler is fact, and it's one that I would like to know because my project is running on tight memory restrictions.  **So where is all of this valuable extra RAM going, and what can I do to reduce it?**  Thank you for any help!

title: How do I create global pointers with low memory overhead?

Answers: 3

body:
*I have to confess that I probably doesn't understand what you are asking ...*

Regarding the stats giving by the compiler (tested on a Uno, Arduino IDE 1.8.5), I got

**Global Wrapper (using global ginny)**

    Sketch uses 3304 bytes (10%) of program storage space. Maximum is 32256 bytes.
    Global variables use 400 bytes (19%) of dynamic memory, leaving 1648 bytes for local variables. Maximum is 2048 bytes.

**Execution**

    Initial free RAM: 1640
    Making Ginormous Class (do nothing constructor)...
    Current free RAM: 1636

    Deleting first class...
    Current free RAM: 1640

    Making Ginormous Class (use a ton of RAM constructor)...
    Current free RAM: 610

    Deleting second class...
    Current free RAM: 1640

**Local Wrapper (using local ginny)**

    Sketch uses 3258 bytes (10%) of program storage space. Maximum is 32256 bytes.
    Global variables use 398 bytes (19%) of dynamic memory, leaving 1650 bytes for local variables. Maximum is 2048 bytes.

**Execution**

    Initial free RAM: 1642
    Making Ginormous Class (do nothing constructor)...
    Current free RAM: 1638

    Deleting first class...
    Current free RAM: 1642

    Making Ginormous Class (use a ton of RAM constructor)...
    Current free RAM: 612

    Deleting second class...
    Current free RAM: 1642

Local Wrapper version uses 2 bytes less of global space. That's correct, because space for `local ginny` comes from the stack, while `global ginny` comes from the heap.

No compiler will give you how much space (for variables) will you need during execution. That's unsolvable (from Turing's Halting Problem). Just think what happens when you enter in a non-ending recursion.

Comparing execution results, both version show the same amount of memory, off by two bytes, which is due to `ginny` declared global vs local.

There is a differente between free space declared by compiler (1648, 1650 bytes) and space reported during program execution (1640, 1642 bytes). The difference is 8 bytes in both cases.

Now, `setup` is a function called from `main`. That's means you need stack space for the call (return address and whatever), which explains the 8 bytes difference.

body:
> I am assuming that the RAM given by the compiler is fact ...

That's about the only thing I **wouldn't** assume. The compiler can't really know how much RAM your code is going to use, especially when you do dynamic memory allocation. The compiler can certainly report on how much space your global variables take, as it has to allocate addresses for them.

I have [a post](http://www.gammon.com.au/progmem) about what RAM is used in a minimal sketch, for example this:

    #include "memdebug.h"

    void setup ()
      {
      Serial.begin (115200);
      Serial.println ();
      Serial.print (F("Free memory = "));
      Serial.println (getFreeMemory ());
      }  // end of setup

    void loop () { }

Perhaps surprisingly, that sketch already uses 346 bytes of RAM, and it hasn't got any (visible) variables in it.

---

> what can I do to reduce it?

      Serial.println("Making Ginormous Class (do nothing constructor)...");

You could start by using the `F` macro:

      Serial.println(F("Making Ginormous Class (do nothing constructor)..."));

body:
I compiled a slightly modified version of your code, with some
`#define`s for selecting which objects get constructed or not. I also
printed the available RAM right after entering `setup()`. I found that,
at this point in the program, the version constructing both objects
is using 178 bytes more RAM than the version that constructs none.

I then used the commands `avr-nm` and `avr-objdump` to try to figure out
how the program is using its memory. I found the 178 bytes
difference is as follows:

    157 bytes of string data
      6 bytes of malloc data
      4 bytes of random state
      2 bytes for the ginny variable
      8 bytes of stack
      1 mystery byte

The difference in string data comes from messages such as “Making
Ginormous Class (do nothing constructor)...”, “Deleting first class...”,
etc., which are `#define`d out in the version that does not construct
the objects. The `malloc()` data (heap\_start, heap\_end and margin) is
not used in the version that does not use `new`, so it is not included
in that version. For the same reason, the `random()` state is not
included in the version that does not use `random()`. The `ginny`
variable, although declared in both versions, is optimized-out by the
compiler in the version where it remains unused. The 8 bytes of stack
come from the fact that the largest version of `setup()` needs more
CPU register to do its work, and hence pushes more registers to the
stack. There is only one byte I could not account for, with value 0,
sitting at the end of the .data section, with no associated symbol.

As you can see from this, the difference has little to do with the
objects being constructed. It is mostly due to the string data. A
smaller part of that difference comes from variables (`ginny`, random
state and `malloc()` data) which are used only in one version of the
program. The practical conclusions are:

1. If you want to save RAM, use the `F()` macro when printing constant
   strings.
2. If you want to benchmark memory consumption, beware your benchmarking
   method can have non-obvious effects on the consumption yo are trying
   to measure.


body:
I'll post the whole code if you really need to see it, but my question is pretty simple.

In my sketch I define some parameters:

    #define SSID "Kaywinnet"
    #define PASSWORD "806194edb8"
    #define MQTT_SERVER { 192, 168, 1, 124 }

And, the sketch compiles just fine.
But, rather than putting my net parameters into every sketch, I wanted to just use a .h file so that if something changes, I only have to change it once.

Here's the problem.  When I put these three lines into a .h file, I get an error when the first parameter is used in the sketch:

    expected primary-expression before '.' token

Here is the code where I use the value:

    //Initialize ESPHelper
    netInfo homeNet = {
      .mqttHost = mqtt_server,
      .mqttUser = "",
      .mqttPass = "",
      .mqttPort = 1883,
      .ssid = SSID,
      .pass = password
    };
    ESPHelper myESP(&homeNet);

The error is on the .ssid= line.

So, why does it compile when I define the parameters in the sketch, and gives an error when I put them into a .h file??

Here's the ino file:

        /*****

      Projects/esp8266/MQTT nodes/light2.ino
      10/3/2017- Clone of studio.ino

      IDE settings:
      Board: "Generic 8266 Module"
      Flash Mode: "DOUT"

    *****/

    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    #include <ESPHelper.h>

    //#include <Kaywinnet.h>
    #define SSID "Kaywinnet"
    #define password "806194edb8"
    #define mqtt_server "192.168.1.124"

    //#define toggle   //Using toggle switch.
    #define pushbutton    //Using pushbutton switch

    #define NODENAME "light2"
    const char *cmdTopic =  NODENAME "/light";
    const char *statusTopic = NODENAME "/light/status";
    const char *connectName =  NODENAME "lights";
    #define OTAPASSWORD "xxxx"

    //Defaults to DHCP, if you want a static IP, configure below
    //#define STATIC_IP
    #ifdef STATIC_IP
    IPAddress ip(192, 168, 1, 50);
    IPAddress gateway(192, 168, 1, 1);
    IPAddress subnet(255, 255, 255, 0);
    #endif

    //Initialize ESPHelper
    netInfo homeNet = {
      .mqttHost = mqtt_server,
      .mqttUser = "",
      .mqttPass = "",
      .mqttPort = 1883,
      .ssid = SSID,
      .pass = password
    };
    ESPHelper myESP(&homeNet);

    //Declare an object of class WiFiClient
    WiFiClient esplight2;
    PubSubClient client(esplight2);

    #define esp8266-01    //Either sonoff or esp8266-01

    //Define the GPIO pins on the 8266-01
    #ifdef esp8266-01
    const int buttonPin = 0;    //GPIO0
    const int relayPin = 2;    //GPIO2
    #endif

    #ifdef Sonoff
    const int buttonPin = 0;     //GPIO0
    const int extraPin = 14;
    const int ledPin = 13;
    const int relayPin = 12;
    const bool ledOFF = HIGH;
    const bool ledON = LOW;
    #endif

    int switchVal = 0;
    int currentVal = 0;
    bool relayState;
    String payLoad;

    // * *************** RelayControl, remember the state ***************
    //
    void RelayControl(bool state) {
      //Serial.print("relayState: ");
      //Serial.println(relayState);

      digitalWrite(relayPin, state ? HIGH : LOW);
      relayState = state;

      //Feedback over MQTT
      if (relayState) {
        client.publish(statusTopic, "on");    //Tell Node Red about the current status
        Serial.println(String(statusTopic) + "= on.");
      } else {
        client.publish(statusTopic, "off");
        Serial.println(String(statusTopic) + "= off.");
      }
      Serial.println();
    }

    void timeLoop (long int startMillis, long int interval) { // the delay function
      while (millis() - startMillis < interval) {}
    }

    /*
     * ************** blink the LED ************************
       We assume the LED is on after connecting.
    */
    void blinkLED() {
    #ifdef esp8266-01
      return;   //No led on the esp to blink..
    #endif
    #ifdef Sonoff
      digitalWrite(ledPin, ledOFF);
      delay(500);
      digitalWrite(ledPin, ledON);
    #endif
    }

    /*
     * ******************** set up WiFi ****************
    */
    void setup_wifi() {
      delay(10);
      // We start by connecting to a WiFi network
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(SSID);

      //Connect to WiFi network so we can reach the MQTT broker and publish messages to topics.
      WiFi.mode(WIFI_STA);
      WiFi.begin(SSID, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.print("WiFi connected - ESP IP address: ");
      Serial.println(WiFi.localIP());
    }

    /*
     * *************** MQTT callback ********************
    */
    void callback(String topic, byte* message, unsigned int length) {
      Serial.print("Message arrived on topic: ");
      Serial.print(topic);
      Serial.print(". Message: ");

      String messageTemp;
      for (int i = 0; i < length; i++) {
        //Serial.print((char)message[i]);
        messageTemp += (char)message[i];
      }
      messageTemp.trim();            // trim the white space off the string

      Serial.println(messageTemp);

      // If a message is received with the topic 'cmdTopic', check if the message is either on or off.
      if (topic == cmdTopic) {
        if (messageTemp == "on") {
          Serial.println("Light2 is ON");
          RelayControl(HIGH);
          blinkLED();

        }
        else if (messageTemp == "off") {
          Serial.println("Light2 is OFF");
          RelayControl(LOW);
          blinkLED();

        }
      }
    }

    /*
     * **************** Connect to MQTT broker **************
       This functions reconnects your ESP8266 to the MQTT broker and subscribes to topics.
    */
    void reconnect() {
      // Loop until we're reconnected
      while (!client.connected()) {
        Serial.print("Attempting MQTT connection...");

        // Attempt to connect
        if (client.connect(connectName)) {
          Serial.println("connected");
    #ifdef Sonoff
          digitalWrite(ledPin, ledON);
    #endif
          // Subscribe or resubscribe to a topic
          client.subscribe(cmdTopic);
        } else {
          Serial.print("failed, rc=");
          Serial.print(client.state());
          Serial.println(" try again in 5 seconds");
          delay(5000);
        }
      }
    }

    /*
     * *************** SETUP ********************
    */
    void setup() {

      //espHelper
      myESP.OTA_enable();
      myESP.OTA_setPassword(OTAPASSWORD);
      myESP.OTA_setHostname(NODENAME);
      myESP.begin();

    #ifdef Sonoff
      pinMode(ledPin, OUTPUT);
      digitalWrite(ledPin, ledOFF);     //The Sonoff LED is low-true.  This starts with it off.
    #endif

      pinMode(relayPin, OUTPUT);
      RelayControl(LOW);  //Start with the heat off

      pinMode(buttonPin, INPUT_PULLUP);

      Serial.begin(115200);
      setup_wifi();
      client.setServer(mqtt_server, 1883);
      client.setCallback(callback);

      //Save the initial switch position.
      currentVal = digitalRead(buttonPin);

      Serial.print("cmdTopic= ");
      Serial.println((String(cmdTopic)));
      Serial.print("statusTopic= ");
      Serial.println((String(statusTopic)));
      Serial.print("connectName= ");
      Serial.println((String(connectName)));
      Serial.println("...............");
    }

    /*
     * *************** LOOP ***********
       The loop function begins with making sure that your ESP is connected to the broker.
    */
    void loop() {
      myESP.loop();  //run the loop() method - this keeps the network services running

      if (!client.connected()) {
        reconnect();
      }
      if (!client.loop())
        client.connect(connectName);

    #ifdef toggle
      /*
       * ******** Toggle switch attached **********
      */
      //Has the switch position changed from the last loop?
      //If yes, the save the new setting and toggle the heat.
      switchVal = digitalRead(buttonPin);
      if (switchVal != currentVal) {
        delay(500);
        switchVal = digitalRead(buttonPin);
        if (switchVal != currentVal) {   //debounce
          currentVal = switchVal;
          relayState = !relayState;
          RelayControl(relayState);

          /*    //For simultaneous control over MQTT
                if(relayState){
                    client.publish("studio/heat","on");
                  }else{
                    client.publish("worksgop/light","off");
                  }
          */

        }
      }
    #endif

    #ifdef pushbutton
      /*
       * ***** Momentary pushbuttom switch attached *******
      */
      //When the switch input goes low, toggle the light.
      switchVal = digitalRead(buttonPin);
      if (switchVal == LOW) {
        delay(500);
        switchVal = digitalRead(buttonPin);
        if (switchVal == LOW) {   //debounce
          relayState = !relayState;
          RelayControl(relayState);
          delay(1000);            //Delay if the button is held too long.
        }
      }
    #endif

      yield();
    }

And here is Kaywinnet.h

    #define ssid "Kaywinnet"
    #define password "806194edb8"
    #define mqtt_server "192.168.1.124"

title: I put some defines into a .h file, and get errors

Answers: 2

body:
> why does it compile when I define the parameters in the sketch, and gives an error when I put them into a .h file??

easy:

1) go back to the non-fancy version where you put the strings back into the code.

2) get it to compile.

3) then extract the strings to macros.

by going through that, you will know precisely the mistakes you made.

body:
>Here's the ino file:
...
>
    #define SSID "Kaywinnet"
...
>
      .ssid = SSID,
...
>And here is Kaywinnet.h
>
    #define ssid "Kaywinnet"
...
The error is on the .ssid= line.

C++ is case sensitive. You changed the macro name from `SSID` to `ssid` when you moved the defines to the .h file.


body:
I'm developing a project that requires save data from a sensor that is connected in a LCD keypad shield, the information should be save in a file into SD card.

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

    #include <LiquidCrystal.h>
    #include <SD.h>

    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

    int buttons;
    File myFile;
    //name of the file
    char nombrefichero[12];
    int i = 1;
    int exist = LOW ;

    void setup() {
    Serial.begin(9600);
    //check the sd card adapter
      Serial.print("Iniciando SD ...");
      if (!SD.begin(53)) {
        Serial.println("No se pudo inicializar");
        return;
      }
      Serial.println("inicializacion exitosa");
    }

    void loop() {
    // use the buttons of the lcd keypand shield in analog 0
    buttons = analogRead(0);

    //button right
    if(buttons < 50){
      count ++;
      nuevo();
    }

    //button select
    if(buttons < 790){
      capturar();
    }

    }

    void capturar(){
      myFile = SD.open(nombrefichero, FILE_WRITE);//abrimos  el archivo

      if (myFile) {
            Serial.print("Escribiendo SD: ");
            int sensor1 = analogRead(0);
            int sensor2 = analogRead(1);
            int sensor3 = analogRead(2);
            myFile.print(millis());
            myFile.print(",");
            myFile.print(sensor1);
            myFile.print(",");
            myFile.print(sensor2);
            myFile.print(",");
            myFile.println(sensor3);

            myFile.close(); //cerramos el archivo

            Serial.print("Tiempo(ms)=");
            Serial.print(millis());
            Serial.print(",sensor1=");
            Serial.print(sensor1);
            Serial.print(",sensor2=");
            Serial.print(sensor2);
            Serial.print(",sensor3=");
            Serial.println(sensor3);

      } else {
        // if the file didn't open, print an error:
        Serial.println("Error al abrir el archivo");
      }
      delay(1000);
    }

    void nuevo(){

    while (exist == LOW)
      {
        sprintf(nombrefichero, "M%d.txt",i); //generate autoincrement number of
    file

        if(SD.exists(nombrefichero))
        {
           i = i+1;
          myFile = SD.open(nombrefichero, FILE_WRITE);
          if (myFile) {
            Serial.println("Archivo nuevo, Escribiendo encabezado(fila 1)");
            myFile.println("Tiempo(ms),Sensor1,Sensor2,Sensor3");

            myFile.close();

          } else {
            exist = HIGH;
            Serial.println("Error creando el archivo");
          }
      }

      }
    }

I need capture the information of the sensor when I pressed the select button and when the right button is press create a new file in this method, in this line if(SD.exists(nombrefichero)) if I put the ! before SD.exist the files are created infinite but if I leave it as is without the ! the button does nothing

    void nuevo(){

    while (exist == LOW)
      {
        sprintf(nombrefichero, "M%d.txt",i);
        if(SD.exists(nombrefichero))
        {
           i = i+1;
          myFile = SD.open(nombrefichero, FILE_WRITE);
          if (myFile) {
            Serial.println("Archivo nuevo, Escribiendo encabezado(fila 1)");
            myFile.println("Tiempo(ms),Sensor1,Sensor2,Sensor3");

            myFile.close();

          } else {
            exist = HIGH;
            Serial.println("Error creando el archivo");
          }
      }

      }
    }

I'm use arduino mega 2560 and SD card Adapter

title: Save data from an LCD KeyPad Shield to an sd card

Answers: 0


body:
I want to use the 3.3v on a cheap Arduino Nano clone as my ADC analog reference voltage. The 3.3v comes from a regulator inside the CH340 USB serial chip.

I've measured the voltages (My DMM is NOT calibrated) on seven different Nanos and the voltages vary (2.96-3.38v).

I'm happy to calibrate each board to this voltage, but are there any figures available on how stable this 3.3v supply is? Long term and temperature wise?

title: CH340 3.3v stability

Answers: 1

body:
Using the VCC as voltage reference is ok only if

 1. you accept poor performances or
 2. you need to measure a ratiometric output.

Case 2 is because the output depends on VCC (so you compensate). For instance, if you want to get the value of position in a potentiometer, you have that the voltage you see is `Vo = Vcc * X` (where 0<=X<=1 is the position), then the result you have on your ADC is `Y = Vi / Vcc * k = X * k` (where k is the maximum value of the ADC reading - e.g. 1023). So you actually compensate the Vcc deviation.

If you want to measure an absolute voltage, however (case 1) you will have a lot of uncertainties. For instance, if your current varies during the time (for instance you turn on the LED), the Vcc voltage can vary quite a lot. This is why for precise measurements you always must use a voltage reference.

In your case, you can

 1. Use the internal reference - for the Atmega328 it is nominally 1.1V, but it can range from 1.0V to 1.2V
 2. Use an external reference

You have to keep in mind that the voltage reference is the maximum value you can read. For instance, if you use the internal reference and then try to measure a 2.3V, you will not be able to do it (you will read the maximum value of 1.1V)

In order to fix this, you can use a trick: use Vcc as reference, and then use a voltage reference to get a precise calibration every time you need to measure something. For instance, if you have to read values from ADC1 and ADC3, you can

 1. Read the value of the internal/external reference
 2. Read ADC1
 3. Read ADC3
 4. Use the reading in point 1 to be able to guess what ADC1 and ADC3 readings were

This way you compensate for variations in the supply.

Just note that, even if the internal reference is not very precise (it has a 10% deviation from the standard value), it is indeed stable, while the VCC varies (a lot) during time. So if you have to calibrate, calibrate against the internal reference and not the Vcc.

If you can afford an external voltage reference, these are usually very stable and have very little deviation from sample to sample, so you may assume their value is "fixed"


body:
I am trying to compile the function in http://playground.arduino.cc/Code/PwmFrequency

This produces a couple of errors

    sketch/setPwmFrequency.c:34:3: error: unknown type name 'byte'
       byte mode;
       ^
    sketch/setPwmFrequency.c:45:7: error: 'TCCR0B' undeclared (first use in this function)
           TCCR0B = TCCR0B & 0b11111000 | mode;

`byte` is trivial, but I can't seem to find `TCCR0B` et al I assume it should be defined somewhere.

title: 'TCCR0B' undeclared

Answers: 1

body:
Both errors can be solved by adding the following line to your setPwmFrequency.c:

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

    #include <Arduino.h>

This will include the files that contain the `byte` typedef and also the register definitions.

You may notice that is not necessary in an .ino file. The reason is that the Arduino IDE automatically adds the Arduino.h include to .ino files during sketch preprocessing before compilation.


body:
I am currently learning pointers. I am following a book (Says Teach Yourself "Arduino Programming") in which there is an exemple about pointer and array.

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

      Serial.begin(9600);

      char string1[] = "This is my test string";
      char string2[]="This is another string test";
      char *ptr2 = string2;
      char *ptr1 = string1;

      while (*ptr1 != '\0') { // not "\0"
        *prt2 = *prt1;
        ptr1++;
        prt2++;
      }
      Serial.println(string1);
      Serial.println(string2);
    }

    void loop() {
      // put your main code here, to run repeatedly:

    }

I get an error "ptr2 was not declare in this scope."

I don't know what is wrong...

That for your help.

title: Error with pointer in array

Answers: 1

body:
"ptr2" != "prt2"

You have a typo there.


body:
im quite new to Arduino coding. Currently im trying to create an alarm and when the alarm ring, the user will just need to remove the door sensor once to stop the alarm and listen for the next alarm. What i have is Real Time clock module to keep track of the time.

So i have tried to code on my own but failed and here's the outcome:
After the alarm ring, and i remove the door sensor from each other, it stopped buzzing (Which is correct partly) but once i put it back together, it continued to ring for the alarm duration (Which was set as 1 min)

Here's the code i had:

    #include <DS3231.h>
    #include <Wire.h>
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
    DS3231  rtc(SDA, SCL);
    Time  t;
    #define buz 11      //This is Buzzer that is plug into pin 11 (Change it accordingly to what you will be putting it in the arduino)
    int Hor;            // This is declaring the alarm in Hours
    int Min;            // This is declaring the alarm in Minutes
    int Sec;            // This is declaring the alarm in Seconds
    const int sensor = 10;    // Door sensor connected to Pin 10
    int state; // 0 close - 1 open switch

    void setup()
    {
      Wire.begin();
      rtc.begin();
      Serial.begin(9600);
      pinMode(buz, OUTPUT);
      lcd.begin(16,2);
      lcd.setCursor(0,0);
      lcd.print("Alarm");
      lcd.setCursor(0,1);
      lcd.print("Test");
      // The following lines can be uncommented to set the date and time
      //rtc.setDOW(WEDNESDAY);     // Set Day-of-Week to SUNDAY
      //rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
      //rtc.setDate(1, 1, 2014);   // Set the date to January 1st, 2014
      delay(2000);
      pinMode(sensor, INPUT_PULLUP);
    }

    void loop()
    {
      t = rtc.getTime();
      Hor = t.hour;
      Min = t.min;
      Sec = t.sec;
      lcd.setCursor(0,0);
      lcd.print("Time: ");
      lcd.print(rtc.getTimeStr());
      lcd.setCursor(0,1);
      lcd.print("Date: ");
      lcd.print(rtc.getDateStr());

      alarm1();
      alarm2();
      delay(1000);
    }

    void Buzzer()
    {
      digitalWrite(buz,HIGH);
      delay(500);
      digitalWrite(buz, LOW);
      delay(500);
    }

    void alarm1() //E.g. This is the first alarm for the medicine
    {
      state = digitalRead(sensor);
      if( Hor == 20 && (Min == 11 || Min == 12) && state == 0) //Comparing the current time with the Alarm time
      {
          Buzzer();
          lcd.clear();
          lcd.print("1st Alarm ON");
          lcd.setCursor(0,1);
          lcd.print("Morning Medicine");
         }
      else if ( Hor == 20 && (Min == 11 || Min == 12) && state == 1)
      {
        noTone(buz);
      }
      delay(200);
    }

    void alarm2()
    {
      if( Hor == 19 && (Min == 48 || Min == 49) && state == 0) //Comparing the current time with the Alarm time
      {
          Buzzer();
          lcd.clear();
          lcd.print("1st Alarm ON");
          lcd.setCursor(0,1);
          lcd.print("Morning Medicine");
         }
      else
      {         //Once user open the door sensor, the alarm will stop buzzing
        noTone(buz);
        alarm1();
      }
      delay(200);
    }

Just to clarify that the variable state i took from

http://www.instructables.com/id/How-to-Use-a-Magnetic-Door-Switch-Sensor-With-Ardu/

So to summarised my problem, i am trying to get the system to read the opening of the door sensor **once** so that the alarm will stop and listen to the next alarm regardless if i put it back the door sensor or not
Really hope someone can help me thanks for you kind attention

title: How to only detect the opening and closing of door sensor once

Answers: 1

body:
As often, the answer to this question is “[Implement a ‘Finite State
Machine.’][FSM]”. In this instance, you need at least three distinct
states:

* `ARMED`: the buzzer is not active, but it is only a matter of time...
* `ON`: bzzzz... bzzzz... bzzzz...
* `STOPPED`: the user has stopped the alarm.

Each of your alarms should have a start time and a stop time (say, two
minutes after the start time). Then, the possible state transitions are:

* `ARMED` → `ON`: when we hit the `start` time of an alarm
* `ON` → `STOPPED`: when the user stops the alarm
* `ON` → `ARMED`: when we hit the `stop` time of the alarm
* `STOPPED` → `ARMED`: when we hit the `stop` time of the alarm

Notice that, once the user stops the alarm, the only way for the buzzer
to start buzzing again is by going through the transitions `STOPPED` →
`ARMED` → `ON`. The first transition happens at the alarm's stop time,
whereas the second one happens at the next alarm's start time.

You did use a kind of state variable in your code, but the problem is
you failed to realize that `ARMED` and `STOPPED` should be distinct
states. If you fuse these states together then, when the user stops
actively “stopping” the alarm, and if it's still `start` time, the
system transitions immediately back to the `ON` state.

[FSM]: https://hackingmajenkoblog.wordpress.com/2016/02/01/the-finite-state-machine/


body:
I have Arduino which is programmed to do something. Is it possible that I could allow it to change behaviour by changing program on-the-fly without the need to reprogram Arduino via the computer.

What I need is to send the message via MQTT which will Arduino receive and change its behaviour by it. I managed to change the frequency of messages published or to add some new data, but what if I want to change how decisions are made. What if I want to change some Arduino code, to add some if or another state, can that be done on the fly?

Update: Changing device behaviour on the fly or after restart is acceptable. I am not strict with using arduino, nodemcu is and option. I just need a way to add new functionality to device if I need.

title: Can I change Arduino program on-the-fly?

Answers: 5

body:
 - Code that writes to flash has to reside in the bootloader section.
   The only way I know how to execute code in the bootloader section is
   after a reset. However, even if you could transfer execution to the bootloader section and get something to work, it would
   have to contend with the fact that flash has limited write cycles and
   will reduce the life of the device. Possibly to the point of being
   useless for a practical application.
 - Executing code from RAM. Self explanatory, modify code all you want.
   There is an [application note][1] for AVR that discusses this.
 - Write an interpreter for your needs. yuk!

EDIT: There is some GCC code example [here][2].

  [1]: http://www.atmel.com/zh/cn/Images/Atmel-42249-Executing-code-from-RAM_Application-Note_AT07347.pdf
  [2]: https://www.embeddedrelated.com/showthread/AT91SAM/1358-1.php

body:
You can change the behaviour of Arduino on-the-fly but it's not necessary to reprogram, just design your code to change behaviour with some variables you get form outsite e.g. a server, but this new changes must be defined previously in your code.

If you have a list of states and want to add more, use a dynamic array or use an array with enough space and when send a MQTT message that Arduino parses adding tha new state or even deleting a state.

body:
Replacing or modifying the existing code during run-time will require some form of uploading and over-writing the old code. This is deliberately not made straightforward or easy for these kinds of micro-controllers.

But you can change the program's strategy on the fly, *if* you anticipate the potential changes and include the code for each of the possibilities.

For example, write a set of functions that each embody one of the various ways of operating, and, at run-time, select which function the program should use. You can change the selection by setting a value from the keyboard or the program could sense some external trigger such as a button-press, or a temperature reading and respond by changing the selection - the value of an int, perhaps. A `switch` statement can use that value to call the appropriate function at the appropriate time:

    uint8_t strategy = 0;           // init to the default strategy

    switch( selector ){
    case(1):                // has event 1 happened?
       func1();
       break;

    case(2):                // has event 2 happened?
       func2();
       break;

    case(3):                // has event 3 happened?
       func3();
       break;

    default:                // none of the above or undefined selector value
       funcDefault();
       break;
    }

This does mean that all of the code for the possible operating strategies must be included at upload-time and share the program-memory space, but unless your job is very complex, even an Uno should be capable enough.

Update:

>  I need to be able to update the device with some new functionality.

There is another approach which may or may not fit in an Uno but would be doable with a Mega 2560 or other larger-RAMmed machine: interpreted code.

 - Define a set of operations that includes whatever you'll need to operate your external device(s): the necessary I/O operations to read your sensors and control your hardware; to make logical and/or arithmetic tests and conditionally branch or call a function based on the test result; to listen for a user-signal from the terminal (for example) and return to the arduino program. This will be the "language" in which you write your control program.

 - Define a concise coding scheme to specify each operation and whatever data it needs, such as reading a temperature sensor and storing the result in a named place. If your control programs won't be too complex, you can get away with pre-defining A, B, ..., Z to be data registers of some appropriate type.

 - In C++, write an interpreter for this new language. It's program will consist of the codes you just defined. But this code will be seen as data by the interpreter. This is the key - this pseudo-code will live in RAM, where your interpreter - a collection of C++ functions - can read and execute it, and the Arduino program can download a new one, over-write the old one, and run the interpreter again.

Caveat: Like the Greek mythological Hydra, this is a job that can grow new challenges as you address the current ones, but it is doable if you keep it simple as possible and include only what you must have to make it work.

Run-time-interpreted code can take 10 - 50 times as long to execute as a natively coded application, so anything that can be pre-coded in C++ should be. The finer and more flexible your interpreted instructions, the more expressive you can be when writing the control program, but the interpreter will be more complex to write, slower to execute, and harder to debug. Design your language to be only as flexible as it must be to allow you to write new control algorithms.

If you try to invent an entire pseudo-computer, completely flexible and capable of being programmed for any and all purposes, you'll drive yourself crazy. Whole businesses have folded after sinking money and time into inventing a new and better computer and got so bogged down they couldn't recover. Don't go that route.

Start with the grossest, least flexible operations you can live with and get that much working. Discover its limitations and address those, and only those, one at a time, until you have a sufficiently flexible system in which to control your device.

body:
> Is it possible that I could allow it to change behaviour by changing program on-the-fly without the need to reprogram Arduino *via the computer*.

(emphasis added by me).

As some answers pointed out, you can change the behaviour if you allow for it in advance. For example, store in EEPROM some setting (like how often something happens) and have a method of changing that setting.

---

## Different bootloader

However if you want to change the behaviour *completely* then you need to upload new code (whether the code is in RAM or program memory doesn't really change this part).

The bootloader installed as a standard on the Arduinos allows for code to be uploaded via a protocol which arrives at the serial port shortly after reset. There is nothing to stop you writing your own protocol (eg. using MQTT) and make your own bootloader which uses that - assuming it is small enough to fit into bootloader space (the largest bootloader the Atmega328P can hold is 4096 bytes).

---

## Stand-alone programmer

Since you asked about uploading new code without needing to have the computer, an alternative is to program it in the field using a stand-alone programmer. There are various ones around, including [one developed by user Crossroads](http://www.crossroadsfencing.com/BobuinoRev17/Programmer.html) from the Arduino Forum:

[![Stand-alone programmer][1]][1]

I wrote the [code for that one](http://www.gammon.com.au/uploader). The basic approach is to write your new code using the IDE (something you would have to do anyway) and then copy the .hex file to a SD or micro-SD card which is then inserted into the programmer as you can see in the photo. The programmer then connects to the target board via a ICSP interface using a 6-core cable as shown. This reprograms the target in about a second. This makes it practical to reprogram a device "in the field" without having to return it to your base, or carry a laptop around with you.

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

body:
What you need is not a “one trick pony” (arduino) but an actual “horse” - Raspberry Pi. You have no reason not to such as:

1. Price - RPi Zero - $10
2. Size - ditto -about the size of a Nano
3. Functionality::

     Pi . . . . . . . . . . . . . . . .  Arduino

wifi           . . . . . . . . . . . . . . . .  no (wifly /Zigbee now you violate #2)

bluetooth   . . . . . . . . . . . . . . . .  no

web server . . . . . . . . . . . . . . . .  no

mysql database . . . . . . . . . . . ..  no

any linux multithreaded
  apps. . . . . . . .. . . . . . . . . . . . .  no

etc etc etc

Did i miss anything? being a technology architect begins with knowing what hardware and software to apply in any given situation. I. E. avoid square pegs in round holes.