message:
Sampling/transmission limits for USB and Arduino UNO R3

I'm very new at this and I need some help. This is a college project that I must do and not even the professor knows for certain if it is possible.

I have to sample two signals at a fixed sampling rate so there is no aliasing effect and it must be done at the same time (switching the ADC from one analog input to another)..

The signal would be then transmitted via USB to my computer. I guess that the transmission rate would be too slow to do this in real time. I will have to store this somewhere in the Arduino board so it can be transmitted afterwards.

Requirements:

- It could be done with 8 bit resolution.
- Sampling rate of at least 4.8kHz.
- Record both signals for at least 0.1 second.

Is this even possible to do with my Arduino UNO R3? If it isn't, it would be with a sampling rate of 1.2kHz?

PS: I could try to lower the sampling frequency necessary by changing the aliasing filter that I built. The theoretical limit would be at about 1.2kHz for the best filter possible.

body:
The Arduino Uno uses a slow 8-bit microcontroller ATmega328P. The Due, Zero, M0 boards use a faster processor.

However, the ATmega328P microcontroller has many option for sampling analog data. It can easily do what you want. It's all in the [datasheet][1].

The Arduino functions are often slow. For example the analogRead uses 112µs. For two channels you might get near the 4kHz with some luck.

I suggest to write a sketch that reads two channels and stores the data, and see how fast it will be. Note that the Timer0 interrupt will happen during that time. Arduino uses Timer0 for millis. You could disable the interrupts with [noInterrupts][2].
After that, try the prescaler option as mentioned by @frurigi87. It seems to be an easy way to get a higher sample rate.
The next option is to write your own code and use the registers directly. There is code to make a simple oscilloscope with a high sample rate that you can use as an example. For example at [avrfreaks.net][3], click on "projects" and search for "oscilloscope".

  [1]: http://www.microchip.com/wwwproducts/en/ATmega328P
  [2]: https://www.arduino.cc/en/Reference/NoInterrupts
  [3]: http://www.avrfreaks.net/


sender: user

sender: assistant

body:
It is not possible to sample two signals at the exact same time with an
Arduino Uno. The Arduino has only one ADC, so you have to sample one
signal, switch channels, sample the other, switch channels again, etc.
If this is acceptable for your project, then yes, it is perfectly
feasible with an Arduino Uno. But you will have to dig into the
datasheet and program the ATmega328P low-level.

Regarding the sampling rate, you want the ADC to take 9600 samples
per second (4.8 kS/s × 2 channels). This means one sample
every 104 µs. You are lucky: in the default Arduino configuration,
the ADC conversions take exactly 104 µs. frarugi87 and Jot suggest
you reconfigure the ADC for faster sampling. _This is useless_: the
default sampling speed is already optimal for you application. Leave it
as is.

You also require a _fixed sampling rate_. This is _not possible_ to do
with software. Configuring the ADC in _auto trigger mode_ is the only
way to get a really steady rate. The ADC can be triggered by a timer,
but in your particular case, it is just simpler to have it trigger
itself. This is called _free running mode_ and it gives a sampling rate
of exactly one sample every 104 µs. Perfect for your application.

Jot also suggests disabling interrupts. _Do not do that!_ Interrupts are
harmless because the ADC manages its own timing. And they are actually
useful: I would use the ADC interrupt to retrieve the conversion result,
send it through the serial port and switch channels in the multiplexer.

If you are happy with 8-bit resolution, I recommend you enable the _left
adjust result_ mode. This way you can retrieve the 8-bit result from the
ADCH register and you won't need to do bit shifts.

> I guess that the transmission rate would be too slow to do this in
> real time. I will have to store this somewhere in the Arduino board so
> it can be transmitted afterwards.

Both options are possible. If you send the data in binary, you will need
a baud rate of at least 9600 bytes/s × 10 bits/byte
= 96 kb/s. You can opt for 115.2 kb/s, which is standard
and widely supported. If you want to store the data, then you will need
9600 bytes/s × 0.1 s = 960 bytes, or about half
the Arduino RAM. This is fine, as the program can be quite simple, so it
won't need more than half the available RAM.

Just to give you some inspiration, I suggest you take a look at this
[sound-meter
sketch](https://gist.github.com/edgar-bonet/e693799f58a545ca89a2) of
mine. It configures the ADC in free-running mode at 9.6 kS/s and
retrieves the result using the ADC interrupt. I would use the same ADC
configuration for your project, only with left-adjust and with channel
switching performed by the interrupt handler.

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

**Edit**: I just wrote a “dual channel oscilloscope” program along the
lines of this answer: [dual-scope.c][]. It's written in plain C, but it
can also be compiled as a regular .ino file. I only tested it with
constant voltage inputs though.

The program ended up being tiny: it uses about 1% of the flash, 1.4% of
the RAM and 3.4% of the CPU power on an Arduino Uno. Meaning you could
add stuff to it if you feel so inclined.

[dual-scope.c]: https://gist.github.com/edgar-bonet/dbe7ce3be4fa8a8d04b93e70d5f7e552


message:
Partially clean a LCDScreen

I have connected an 16x2 LCD to my Arduino. It shows my Room Temperature and Behind that variable is the string "Celcius". Everytime the temp is diffrent than shown on the screen it updates the screen by clearing the screen.
Is there a way I could clear just a part of the screen? or is this technically impossible. Or is it a waste of code? :D

Thanks in Advance!

Anton

body:
The easiest is to clear the entire screen (I'm sure there is a function for that).

What you also can do:

- Create lines which are 16 characters wide and print them, so the old text is overwritten
- More complicated: store the text that is written in two strings (one per line) and check where are not spaces, to overwrite it with spaces to clear.

You would have to do a performance/time check to see what works best.

If performance is not an issue (which I doubt), keep it simple and just overwrite the two lines (without a clear, assuming you call the clear function yourself).

Another solution is to keep the word Celcius always on the same location... this means you might have to change formatting:

- _28.6 Celcius
- __3.8 Celcius
- _-12.3 Celcius

Where _ are spaces (so the word Celcius is always on the same location)


body:
There is only a function to clear the entire LCD display, and that is in most cases visible.

Clearing only a few characters is done by writing spaces to it. After that you can write the new temperature to that part of the display.

You could also create a fixed length format of the temperature and use spaces to fill the unused characters. Then you can use just one write to the display.

It begins by designing the layout of the text on the display. Then you know where everything will be and how many characters are needed for each value.

@MichelKeijzers, I'm aware that my answer is almost the same as yours, but your answer seems to be for clearing an entire line. I would write the word "Celsius" or "°C" to the screen just once, and only update the value of the temperature.


message:
How to connect a 5V submersible motor to Node MCU?

I connected the D1,D2 pins of the the Node MCU to the positive and negative of a 5V submersible motor. I wrote the following code, its getting uploaded without any errors but the motor is not working. I tested the condition of the motor by connecting to a battery,it does work.the code:

    void setup() {
      // put your setup code here, to run once:
        pinMode(D1,OUTPUT);
    pinMode(D2,OUTPUT);
    }

    void loop() {
      // put your main code here, to run repeatedly:
    digitalWrite(D1,HIGH);
    digitalWrite(D2,HIGH);
    }

body:
I think you have got two issues here.

Firstly, as mentioned in the comments, you are driving the motor off the data pins so it will be getting less than 20mA which is almost certainly not enough to break the stall.  You need to use the digital pins to switch a MOSFET, transistor or relay (Electrical switch) and then that will switch on a larger supply directly from a "battery pack".  Have a Google for 'transistors' or 'relays' and see how they work, then you should get what I mean.

Secondly you seem to be using the pin names D1 and D2. There are a number of Node MCU boards out there but they all seem to have one thing in common and that is the pins labelled D1 and D2 on the board are generally not D1 and D2 in the code.

https://pradeepsinghblog.files.wordpress.com/2016/04/nodemcu_pins.png?w=924

If this is you board then unless you have a header file that does this for you, you should be using GPIO_5 and GPIO_4 for D1 and D2 (respectively).

Oh and the last thing, make sure you sub is leak proof :)


message:
If any kind of character gets loaded into a string, what do I use for an end-of-line character?

I have an Arduino project that is converting floats to characters and then transferring those characters via the serial to a Python program. This is a portion of the Arduino code:

    #define MEM_LEN (16 * 4 * 4) + 1
    uint8_t dataBuf[MEM_LEN];

    typedef union {
      float f;
      uint8_t b[4];
    } cvt_t;

    cvt_t cvt1;

    // set up sensor stuff
    MLX90621 sensor;
     .
     .
     .

    void loop() {
        sensor.measure(); //get new readings from the sensor
        count = 0;
        for(uint8_t y=0;y<4;y++){ //go through all the rows
          for(uint8_t x=0;x<16;x++){ //go through all the columns
         cvt1.f = sensor.getTemperature(y+x*4); // data at position x/y
         dataBuf[count + 0] = cvt1.b[0];
         dataBuf[count + 1] = cvt1.b[1];
         dataBuf[count + 2] = cvt1.b[2];
         dataBuf[count + 3] = cvt1.b[3];
         count += 4;
          }
        }
        dataBuf[MEM_LEN - 1] = '\n'; // not a good delimeter
        Serial.write(dataBuf, MEM_LEN);
    }

The problem is that float conversion loads any and all characters into dataBuf, so I don't have a good delimiter or "end-of-line". When the Python program ingests the incoming string, there's nothing to use to know it's received a complete frame. I don't want the Python to just count characters to know when it's received a frame. No good delimiter - what should I do?

body:
Using a version of Pascal strings could work: the first byte of the buffer is the number of characters, the rest of the sequence the bytes.

Or convert the numbers to ASCII strings. Inefficient but you'll have your `'\0'` delimiter.


body:
Framing binary messages is not as simple as choosing a delimiter.
Counting the characters could be an option, but you need some way to
check that your reception has not gotten out of sync. You could for
example send messages that looks like:

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

    struct Message {
        uint32_t magic;
        uint8_t data[MEM_LEN];
        uint16_t crc;
    };

Where `magic` in a [magic number][], i.e. a random but fixed value that
is very unlikely to happen by accident, and you end the message with a
[CRC][]. On the Python side, you check that both the magic number and
the CRC are OK. If they are not, you have a communication error, but you
can re-synchronize by looking for the next occurrence of the magic
number.

Another option is to choose both a delimiter (say, ASCII 10 = LF =
`'\n'`) and an escape character (say, ASCII 92 = backslash = `'\\'`). On
the sending side, you prefix by the escape character every accidental
occurrence of either the escape character or the delimiter:

    void send_byte(uint8_t c)
    {
        if (c == '\\' || c == '\n')
            Serial.write('\\');  // prefix by escape character
        Serial.write(c);
    }

and on the Python side you do the reverse operation. The only issue with
this approach is that your messages are not constant size anymore.

[magic number]: https://en.wikipedia.org/wiki/Magic_number_(programming)

[CRC]: https://en.wikipedia.org/wiki/Cyclic_redundancy_check


body:
Generally the method to ensure binary data is correctly decoded is to have some form of header and then a checksum. While the header may appear in the data the chances of the correct checksum also being randomly in the data at the correct point is fairly slim. The longer the header and checksum the lower the probability of invalid data somehow getting accepted.

The header could be as simple as a 1 or 2 byte fixed pattern or could be a fixed pattern followed by a message ID and a length.

The checksum is normally 16 bits, that means that if the system got out of sync somehow and then header happened to appear in the data before the next real header the invalid data has a 1 in 65,000 chance of being accepted.

Exact probabilities of invalid data being accepted depend upon the packet lengths but assuming random data then for a 16 bit header with a 16 bit checksum and 32 bits of data it's in the region of a 1 in 4 billion chance of allowing incorrect data in. A 32 bit header + 16 bit checksum increases that something like 1 in 100 trillion. At that point you've got more chance of winning every lottery in the world while being simultaneously struck by lightning and a meteor.

Data is rarely truly random, if you can use a header that is less likely to appear in the data then you can improve things further.

Since you only have 4 bytes of data I'll assuming you want to keep things simple and don't want to add a dozen bytes of overhead to each value. A header of 0xff is a good bet, if that was the first byte of a float the value will be in the -10E38 region.
If you use a two byte header the 0xffc0 is a good choice, that would be NaN, an invalid floating point value. Since this means the first two bytes of your data aren't going to match the header this greatly reduces the chance of the header appearing in the data. Your checksum could then be a simple xor of the next for bytes.
So your data packet ends up being:

`0x ff c0 <d1> <d2> <d3> <d4> <d1^d2^d3^d4>`

One other alternative approach is through the use of escape codes/characters. This is a special value that never appears on it's own in the data. For example let's define our escape character as being 0xFF and the header value as being 0xC0 C0.

In that situation 0xC0 C0 is always the start of a data packet.

If 0xC0 happens to appear in the data we insert the escape character in front of it. Similarly if the escape character happens to appear in the data we insert an extra escape character in front of it.

e.g. for a data value of `0x11 0xC0 22 FF` we would send `0xC0 C0 11 FF C0 22 FF FF` or `<header> <d1> <escape> <d2> <d3> <escape> <d4>`

For hopefully obvious reasons whenever possible the header and escape characters should be values that rarely occur in the data.

This approach has the advantage that if designed correctly there is no risk no matter how small of invalid data getting through and (on average) it has a lower overhead in terms of bytes sent, most of the time all you need to add is the 2 byte header. The down side is that inserting and removing the escape characters can get complex and messages are no longer a fixed size, the length depends on the data content. This indeterminacy in message length can potentially cause problems depending upon the application.

To be honest for a single floating point number text may be easier. Binary is more efficient, it's less CPU load and less data to send, but for something as short as a single number the savings aren't normally worth the extra complexity.


message:
Powering relay module with 5v external supply

The relay module consists of two sets of pins:

Set1: GND, VCC, Int1, Int2
Set2: JDVcc, VCC, GND

In set 2, VCC and JDVcc are jumpered together normally, which is removed to power the relay coil with external supply.

However, can I supply 5v directly from external source to the VCC pin of Set 1 and connect the GND pin to common ground, leaving the VCC and JDVcc pin jumpered together as they are? It's because I am running out of pins in my Uno.

Will that work?

body:
> can I supply 5v directly from external source to the VCC pin of Set 1
> and connect the GND pin to common ground, leaving the VCC and JDVcc
> pin jumpered together as they are?

Probably you're using this relay module, which is fairly common:

[![Relay module schematic][1]][1]

If that's the case, then the answer is **YES as long as you keep all grounds tied together and the 5V external supply deliveries a voltage reasonably close to the Arduino 5V**.

Why?

 1. When IN is high and VCC is close to 5V, there isn't enough voltage difference for forward biasing the diodes. They won't conduct and no current will flow from or into your Arduino data pin.

 2. When IN is low, the diodes are forward biased and current will sink into the Arduino data pin. As long as VCC is close to 5V, the current limiting resistor will keep current within specification of what the Arduino data pin can tolerate.

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


message:
Arduino UNO hangs without visible reason

I'm having trouble with Arduino UNO. I bought a cheap clone (what obviously *may* be the reason) along with [display+keypad shield][1] (site in Polish). For my project I wrote a menu library, which (along with simple demo project) may be downloaded or cloned from my [Bitbucket repository][2].

My problem is, that when I push "up" or "down" button and hold it, program behaves as it should for couple of seconds and then board freezes. This is definitely not a case of program hang, because when I used serial debugging, and when such freeze happened, message sent from board was cut in half and no new messages were comming. After such hang I can only reset the board.

I investigated my code a lot, but couldn't find a problem. My questions are:

* In what circumstances board may freeze in such way?
* If someone owns similar hardware (display, 5-button keypad) and original UNO, could you try running my program and check, if the hang happens as well?

Edit: Complete sources of the project, as requested (_now fixed_), *though the newest version is on repository*:

Arduinomenu.ino:

 #include "Display.h"
 #include "Keypad.h"
 #include "Menu.h"

 LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
 Display display(lcd, 16, 2);
 Keypad keypad;

 BaseMenuItem * subItems[] =
 {
   new ActionMenuItem("Subaction 1", 4),
   new ActionMenuItem("Subaction 2", 5),
   new ActionMenuItem("Subaction 3", 6),
   new IntMenuItem("Int item", 0, 10, 5),
   new BoolMenuItem("Bool item", true)
 };

 BaseMenuItem * mainItems[] =
 {
   new ActionMenuItem("Action 1", 1),
   new ActionMenuItem("Action 2", 2),
   new ActionMenuItem("Action 3", 3),
   new SubMenuItem("Submenu", subItems, sizeof(subItems) / sizeof(BaseMenuItem *))
 };

 MainMenu mainMenu(display, mainItems, sizeof(mainItems) / sizeof(BaseMenuItem *));

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

   mainMenu.Show();
 }

 void loop()
 {
   int key = keypad.ReadKey();
   int result = mainMenu.Action(key);
 }

Display.h:

 #ifndef DISPLAY_H__
 #define DISPLAY_H__

 #include <LiquidCrystal.h>

 struct Display
 {
   LiquidCrystal & lcd;
   unsigned char cols, rows;

   Display(LiquidCrystal & lcd, unsigned char cols, unsigned char rows);
   void Print(unsigned char col, unsigned char row, char * text);
 };

 #endif

Display.cpp:

 #include "Display.h"

 Display::Display(LiquidCrystal & lcd, unsigned char cols, unsigned char rows)
   : lcd(lcd)
 {
   this->cols = cols;
   this->rows = rows;
   lcd.begin(cols, rows);
 }

 void Display::Print(unsigned char col, unsigned char row, char * text)
 {
   this->lcd.setCursor(col, row);
   this->lcd.print(text);
 }

Keypad.h:

 #ifndef KEYPAD_H__
 #define KEYPAD_H__

 #define USE_KEYPAD

 #define KEY_RIGHT  0
 #define KEY_UP     1
 #define KEY_DOWN   2
 #define KEY_LEFT   3
 #define KEY_SELECT 4
 #define KEY_NONE   5

 #define LAST_READ_DELAY 250

 #define keypadPort 0

 class Keypad
 {
 private:
   unsigned long lastRead;
   unsigned char lastKey;
 public:
   Keypad();
   unsigned char ReadKey();
 };

 #endif

Keypad.cpp:

 #include "Keypad.h"
 #include "Arduino.h"

 Keypad::Keypad()
 {
   this->lastRead = millis();
   this->lastKey = KEY_NONE;
 }

 // Button values (approximate):
 // Right    0
 // Up       144
 // Down     329
 // Left     504
 // Select   741
 unsigned char Keypad::ReadKey()
 {
   unsigned long now = millis();
   if (this->lastKey != KEY_NONE && (now - this->lastRead < LAST_READ_DELAY) && (now > this->lastRead))
   {
  return KEY_NONE;
   }

   int key = analogRead(keypadPort);

   if (key > 1000)
  this->lastKey = KEY_NONE;
   else if (key < 50)
  this->lastKey = KEY_RIGHT;
   else if (key < 250)
  this->lastKey = KEY_UP;
   else if (key < 450)
  this->lastKey = KEY_DOWN;
   else if (key < 650)
  this->lastKey = KEY_LEFT;
   else if (key < 850)
  this->lastKey = KEY_SELECT;
   else
  this->lastKey = KEY_NONE;

   this->lastRead = now;

   return this->lastKey;
 }

Menu.h:

 #ifndef MENU_H__
 #define MENU_H__

 #include <stdio.h>
 #include <stdlib.h>
 #include "Display.h"
 #include "Arduino.h"

 #ifdef USE_KEYPAD
   #define MENU_ACTION_RIGHT KEY_RIGHT
   #define MENU_ACTION_UP KEY_UP
   #define MENU_ACTION_DOWN KEY_DOWN
   #define MENU_ACTION_LEFT KEY_LEFT
   #define MENU_ACTION_SELECT KEY_SELECT
 #else
   #define MENU_ACTION_RIGHT 0
   #define MENU_ACTION_UP 1
   #define MENU_ACTION_DOWN 2
   #define MENU_ACTION_LEFT 3
   #define MENU_ACTION_SELECT 4
 #endif

 #define TEXT_BACK "Back"
 #define TEXT_BACK_LEN 4

 #ifndef SELECTION_CHAR
 #define SELECTION_CHAR '>'
 #endif

 #define MENU_TYPE_INT 0
 #define MENU_TYPE_BOOL 1
 #define MENU_TYPE_SUB 2
 #define MENU_TYPE_ACTION 3

 #ifndef MAX_MENU_LEVELS
 #define MAX_MENU_LEVELS 5
 #endif

 // Forward declarations -------------------------------------------------------

 class MainMenu;

 // BaseMenuItem ---------------------------------------------------------------

 class BaseMenuItem
 {
 protected:
   const char * name;
   unsigned char len;

 public:
   BaseMenuItem(const char * name);
   void ShowListItem(Display & display, int row, bool selected);
   const char * GetName();
   virtual int GetType() = 0;
 };

 // MenuItem -------------------------------------------------------------------

 class MenuItem : public BaseMenuItem
 {
 friend class MainMenu;

 private:
   void ShowEditMode(Display & display);

 protected:
   void ShowEditHeader(Display & display);
   virtual void ShowEditValue(Display & display) = 0;
   virtual void HandleAction(int key) = 0;

 public:
   MenuItem(const char * name);
 };

 // IntMenuItem ----------------------------------------------------------------

 class IntMenuItem : public MenuItem
 {
 friend class MainMenu;

 private:
   int value;
   int min;
   int max;

 protected:
   void ShowEditValue(Display & display);
   void HandleAction(int key);

 public:
   IntMenuItem(const char * name, int min, int max, int defaultValue);
   int GetType();
 };

 // BoolMenuItem ---------------------------------------------------------------

 class BoolMenuItem : public MenuItem
 {
 friend class MainMenu;

 private:
   bool value;

 protected:
   void ShowEditValue(Display & display);
   void HandleAction(int key);

 public:
   BoolMenuItem(const char * name, bool defaultValue);
   int GetType();
 };

 // SubMenuItem ----------------------------------------------------------------

 class SubMenuItem : public BaseMenuItem
 {
 friend class MainMenu;

 private:
   BaseMenuItem ** items;
   int count;

 public:
   SubMenuItem(const char * name, BaseMenuItem ** items, int count);
   int GetCount();
   BaseMenuItem * GetItem(int index);
   int GetType();
 };

 // ActionMenuItem -------------------------------------------------------------

 class ActionMenuItem : public BaseMenuItem
 {
 private:
   int actionId;

 public:
   ActionMenuItem(const char * name, int actionId);
   int GetActionId();
   int GetType();
 };

 // MainMenu -------------------------------------------------------------------

 class MainMenu : public SubMenuItem
 {
 private:
   SubMenuItem ** itemStack;
   short * positionStack;
   unsigned char stackTop;
   short selectedItem;
   short firstItem;
   Display & display;
   MenuItem * editedItem;

   void ShowBack(int row, bool isSelected);

 public:
   MainMenu(Display & display, BaseMenuItem ** items, int count);
   ~MainMenu();
   int Action(int keyAction);
   void Show();
 };

 #endif

Menu.cpp:

 #include "Menu.h"

 char * NewEmptyLine(int width)
 {
   char * line = new char[width + 1];

   memset(line, 32, width);
   line[width] = 0;
   return line;
 }

 void DeleteLine(char * line)
 {
   delete line;
 }

 // BaseMenuItem ---------------------------------------------------------------

 void BaseMenuItem::ShowListItem(Display & display, int row, bool selected)
 {
   char * line = NewEmptyLine(display.cols);

   if (selected)
  line[0] = SELECTION_CHAR;

   strncpy(line + 2, this->name, min(display.cols - 2, this->len));
   display.Print(0, row, line);

   DeleteLine(line);
 }

 BaseMenuItem::BaseMenuItem(const char * name)
 {
   this->name = name;
   this->len = strlen(this->name);
 }

 const char * BaseMenuItem::GetName()
 {
   return this->name;
 }

 // MenuItem -------------------------------------------------------------------

 void MenuItem::ShowEditHeader(Display & display)
 {
   char * line = NewEmptyLine(display.cols);

   strncpy(line, this->name, min(display.cols, this->len));
   display.Print(0, 0, line);

   DeleteLine(line);
 }

 void MenuItem::ShowEditMode(Display & display)
 {
   this->ShowEditHeader(display);
   this->ShowEditValue(display);
 }

 MenuItem::MenuItem(const char * name) : BaseMenuItem(name)
 {

 }

 // IntMenuItem ----------------------------------------------------------------

 IntMenuItem::IntMenuItem(const char * name, int min, int max, int defaultValue)
   : MenuItem(name)
 {
   this->min = min;
   this->max = max;
   this->value = defaultValue < this->min ? this->min : (defaultValue > this->max ? this->max : defaultValue);
 }

 void IntMenuItem::ShowEditValue(Display & display)
 {
   char * line = NewEmptyLine(display.cols);

   line[0] = 127;
   line[display.cols - 1] = 126;

   int i = display.cols - 3;
   int temp = abs(this->value);
   do
   {
  line[i] = temp % 10 + 48;
  temp /= 10;
  i--;
   }
   while (temp > 0);

   if (this->value < 0)
  line[i] = '-';

   display.Print(0, 1, line);

   DeleteLine(line);
 }

 int IntMenuItem::GetType()
 {
   return MENU_TYPE_INT;
 }

 void IntMenuItem::HandleAction(int key)
 {
   if (key == MENU_ACTION_LEFT)
   {
  if (this->value - 1 >= this->min)
    this->value--;
   }
   else if (key == MENU_ACTION_RIGHT)
   {
  if (this->value + 1 <= this->max)
    this->value++;
   }
 }

 // BoolMenuItem ---------------------------------------------------------------

 BoolMenuItem::BoolMenuItem(const char * name, bool defaultValue)
   : MenuItem(name)
 {
   value = defaultValue;
 }

 void BoolMenuItem::ShowEditValue(Display & display)
 {
   char * line = NewEmptyLine(display.cols);

   line[0] = 127;
   line[display.cols - 1] = 126;

   if (this->value)
   {
  strncpy(line + display.cols - 4, "On", 2);
   }
   else
   {
  strncpy(line + display.cols - 5, "Off", 3);
   }

   display.Print(0, 1, line);

   DeleteLine(line);
 }

 int BoolMenuItem::GetType()
 {
   return MENU_TYPE_BOOL;
 }

 void BoolMenuItem::HandleAction(int key)
 {
   if (key == MENU_ACTION_LEFT || key == MENU_ACTION_RIGHT)
   {
  value = !value;
   }
 }

 // SubMenuItem ----------------------------------------------------------------

 SubMenuItem::SubMenuItem(const char * name, BaseMenuItem ** items, int count) : BaseMenuItem(name)
 {
   this->items = items;
   this->count = count;
 }

 int SubMenuItem::GetCount()
 {
   return this->count;
 }

 BaseMenuItem * SubMenuItem::GetItem(int index)
 {
   return this->items[index];
 }

 int SubMenuItem::GetType()
 {
   return MENU_TYPE_SUB;
 }

 // ActionMenuItem -------------------------------------------------------------

 ActionMenuItem::ActionMenuItem(const char * name, int actionId) : BaseMenuItem(name)
 {
   this->actionId = actionId;
 }

 int ActionMenuItem::GetActionId()
 {
   return this->actionId;
 }

 int ActionMenuItem::GetType()
 {
   return MENU_TYPE_ACTION;
 }

 // MainMenu -------------------------------------------------------------------

 void MainMenu::ShowBack(int row, bool isSelected)
 {
   char * line = NewEmptyLine(display.cols);
   if (isSelected)
   {
  line[0] = SELECTION_CHAR;
   }
   strncpy(line + 2, TEXT_BACK, TEXT_BACK_LEN);
   display.Print(0, row, line);

   DeleteLine(line);
 }

 void MainMenu::Show()
 {
   if (editedItem == NULL)
   {
  bool isSubMenu = stackTop > 0;

  for (int i = 0; i < display.rows; i++)
  {
    if (isSubMenu && i + firstItem == itemStack[stackTop]->GetCount())
    {
   ShowBack(i, i + firstItem == selectedItem);
    }
    else
    {
   itemStack[stackTop]->GetItem(i + firstItem)->ShowListItem(display, i, i + firstItem == selectedItem);
    }
  }
   }
   else
   {
  editedItem->ShowEditMode(display);
   }
 }

 MainMenu::MainMenu(Display & display, BaseMenuItem ** items, int count) :
   SubMenuItem(NULL, items, count),
   display(display)
 {
   // Assuming initially 5 levels of menu max
   itemStack = new SubMenuItem * [MAX_MENU_LEVELS];
   positionStack = new short[MAX_MENU_LEVELS * 2];
   stackTop = 0;
   itemStack[stackTop] = this;
 }

 MainMenu::~MainMenu()
 {
   delete itemStack;
   delete positionStack;
 }

 int MainMenu::Action(int keyAction)
 {
   int lastItemId = stackTop > 0 ? itemStack[stackTop]->GetCount() : itemStack[stackTop]->GetCount() - 1;

   if (editedItem == NULL)
   {
  if (keyAction == MENU_ACTION_UP || keyAction == MENU_ACTION_DOWN)
  {
    if (keyAction == MENU_ACTION_UP)
   this->selectedItem--;
    else
   this->selectedItem++;

    if (selectedItem < 0)
   selectedItem = lastItemId;
    if (selectedItem > lastItemId)
   selectedItem = 0;

    // Adjust items in view

    while (firstItem > selectedItem)
   firstItem--;
    while (firstItem + display.rows - 1 < selectedItem)
   firstItem++;

    Show();
    return -1;
  }
  else if (keyAction == MENU_ACTION_SELECT)
  {
    if (selectedItem == lastItemId && stackTop > 0)
    {
   // Chosen Back

   stackTop--;
   selectedItem = positionStack[stackTop * 2];
   firstItem = positionStack[stackTop * 2 + 1];

   Serial.print("Restored sel/first: ");
   Serial.print(selectedItem);
   Serial.print("/");
   Serial.print(firstItem);
   Serial.print("\n");

   Show();
    }
    else
    {
   int type = itemStack[stackTop]->GetItem(selectedItem)->GetType();
   switch (type)
   {
     case MENU_TYPE_INT:
     {
    editedItem = (MenuItem *)itemStack[stackTop]->GetItem(selectedItem);
    Show();
    break;
     }
     case MENU_TYPE_BOOL:
     {
    editedItem = (MenuItem *)itemStack[stackTop]->GetItem(selectedItem);
    Show();
    break;
     }
     case MENU_TYPE_SUB:
     {
    Serial.print("Entering ");
    Serial.print(((SubMenuItem *)(itemStack[stackTop]->GetItem(selectedItem)))->GetName());
    Serial.print("\n");

    if (stackTop >= MAX_MENU_LEVELS - 1)
      return -1;

    Serial.print("Storing sel/first: ");
    Serial.print(selectedItem);
    Serial.print("/");
    Serial.print(firstItem);
    Serial.print("\n");

    positionStack[stackTop * 2] = selectedItem;
    positionStack[stackTop * 2 + 1] = firstItem;

    itemStack[stackTop + 1] = ((SubMenuItem *)(itemStack[stackTop]->GetItem(selectedItem)));
    stackTop++;
    selectedItem = 0;
    firstItem = 0;

    Show();

    break;
     }
     case MENU_TYPE_ACTION:
     {
    int actionId = ((ActionMenuItem *)(itemStack[stackTop]->GetItem(selectedItem)))->GetActionId();
    return actionId;
     }
   }
    }
  }
   }
   else
   {
  if (keyAction == MENU_ACTION_LEFT || keyAction == MENU_ACTION_RIGHT || keyAction == MENU_ACTION_UP || keyAction == MENU_ACTION_DOWN)
  {
    Serial.print("Item action\n");
    editedItem->HandleAction(keyAction);
    Show();
  }
  else if (keyAction == MENU_ACTION_SELECT)
  {
    editedItem = NULL;
    Show();
  }
   }
   return -1;
 }

[1]: https://nettigo.pl/products/shield-lcd-2x16-z-klawiatura-do-arduino
[2]: https://bitbucket.org/wojciechsura/arduinomenu/

body:
I wouldn't assume by default that it's a hardware problem.

It seems like a software problem, and there can be many reasons that the Arduino hangs, e.g.:

- Too little stack space
- Too little heap space
- Pointer problems

The Arduino does not have safety against too little memory, that means it will overwrite memory -- causing lots of problems -- and hanging is a normal symptom.

What I suggest is:

- Check how many global / local variables you have (and their size), especially arrays and instances of objects; strings can be memory consuming
- Check that you don't have an overly deep stack trace
- To check, you can print out the available memory in several places

For debugging statements, keep in mind that the debug strings can be cut in half just when the microprocessor hangs; maybe the print statements are still in the buffer but will not be sent, so minimize the (length of the) debug statements in such cases.


body:
@Michel Keijzers provided overall answer.

And now probable cause:

    char * GetEmptyLine(int width)
    {
      char * line = new char[width + 1];

In the `Menu.cpp`. There is no single `delete` in the code at all. But so many calls of `GetEmptyLine`.

Using the Arduino String might have done less evil than this kind of memory leak.


body:
Using string literals wastes precious RAM. To avoid this you can use the F macro. That way the string is stored in flash memory only. If by freeing up that extra RAM your program doesn't crash or works better you most likely have the answer.

for example:

    Serial.print(F("RAM "));          // F() macro frees up 4 bytes of RAM
    Serial.println(2048 - freeRam());

a freeRam function:

    int freeRam()
    {
     extern int __heap_start, *__brkval;
     int v;
     return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
    }

On a project I'm working on I noticed that my Arduino Nano with 2K RAM starts crashing when my free RAM goes below 150 bytes. That free RAM is where the stack is and needs to be accounted for.


message:
How can I find and specify the address of my adafruit MMA8451 accelerometer in arduino code?

I am trying to use four of the same accelerometer on the same bus and acquire data from each of them using an SD card. Because I am using four of the same accelerometer I need to be able to differentiate between them and I dont know how to find their specific address. I need the specific address so I can tell my arduino which accelerometer to pull data from. essentially it would pull data from 1 then 2 then 3 then 4 and loop back to 1.

body:
You can't have 4 of those on one bus. The maximum is 2.

The pin `SA0` defines the least significant bit of the I2C address. From [the datasheet](http://www.nxp.com/assets/documents/data/en/data-sheets/MMA8451Q.pdf):

> 7 | SA0 | I2C least significant bit of the device I2C address, I2C 7-bit address = 0x1C (SA0 = 0), 0x1D (SA0 = 1).

In fact, as it states on the [Adafruit website](https://learn.adafruit.com/adafruit-mma8451-accelerometer-breakout/pinouts) (if you'd care to read it sometime):

> A is the I2C Address select pin. By default this is pulled down to ground with a 10K resistor, for an I2C address of 0x1C. You can also connect it to the 3Vo pin for an address of 0x1D

If you want more than 2 you will either have to have multiple I2C busses or use an I2C multiplexer (such as [this one](https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout/overview)) to select different branches on the same bus.


body: Power them on one at a time. They don't take much current to run so a GPIO pin would be more than sufficient.


message:
Conflict between UART serial transmission and timer interrupt Arduino MEGA

I have a small problem with collision between handling serial transmission and executing things in timer interrupt.

I'm doing program which communicates with PC. It transmits and receives as well and received values are computed in timer interrupt and then transmitted to PC. I have also a LCD for simple debugging state of variables.

My question is generally about influancing uart transmision and timer interrupts each other, but I paste part of my code to  better discribing my issue:

    float Kr;
    float Tp=0.05;
    float Ti;
    float Td;
    float yref;

    void setup() {
    lcd.begin(16,2);
     Serial.begin(115200);
    lcd.clear();

     analogReference(DEFAULT);

       Timer1.initialize(50000);
       Timer1.attachInterrupt(Myfunction);

     }

      void loop() {

      while(1)
      {

    if(Serial.available() > 0)
    {
     received = (char)Serial.read();
      if(received== 'a')
      {
        Serial.print(y);  // Here uC transmits to PC
        Serial.print('b');
      }
      if(received == 'w')
      {
        yref_str = Serial.readStringUntil(';');  //uC receives datas from PC
       // yref = yref_str.toFloat();
      }
      if(received == 'x')
      {
        Kr_str = Serial.readStringUntil(';');  //uC receives datas from PC
        //Kr = Kr_str.toFloat();
      }
      if(received == 'y')
      {
        Ti_str = Serial.readStringUntil(';');  //uC receives datas from PC
        //Ti = Ti_str.toFloat();
      }
      if(received == 'z')
      {
        Td_str = Serial.readStringUntil(';');  //uC receives datas from PC
        //Td = Td_str.toFloat();
      }

    }

     //Conversion string to float
     yref = yref_str.toFloat();
     Kr = Kr_str.toFloat();
     Ti = Ti_str.toFloat();
     Td = Td_str.toFloat();

    //Simple displaying some of  variables values
      lcd.home();
      lcd.print("Process ");
     lcd.setCursor(0,1);
     lcd.print("yref=");
     lcd.print(yref);
     lcd.setCursor(9,1);
     lcd.print(" ");
     lcd.setCursor(10,1);
     lcd.print("Kr=");
     lcd.print("    ");
     lcd.setCursor(12,1);
     lcd.print(Kr);
     }
     }

      void Myfunction()
      {
         //here the datas are computed
      }

Transmition bases on kind of frame. When it gets from PC proper char sign it sends datas or receives datas. The frame has ';' sign at the end.

The main thing is that when I set values of variables: float Kr, Ti, Td at the beginning of program, in declaration section (not by serial port) it works perfectly. problem appears when I don't set value at the beginning (just declare likes above) and try to set it via serial port the situation is following:
I can see correct values of those variables on LCD (exactly what I send from PC to arduino) but they don't get to Myfunction (function which is executed within timer interrupt) so actually they are 0 continually.

I don't give whole code for "Myfunction" because this function works properly, for sure. I don't change anything since good working program version. Change is only adding serial transmission.

I tried to declare variables as volatile but it didn't solve the problem.

Anyone did have any experience with such problems??

***Update:***

I paste code of whole program, as you asked me for:
It looks like below

    #include<LiquidCrystal.h>
    #include<TimerOne.h>

    LiquidCrystal lcd(52, 50, 48, 46, 44, 42, 40);

    #define Max 127
    #define Min -128

    /*float Kr;
    float Tp=0.05;
    float Ti;
    float Td; */
    /*float Kr = 0.19;
    float Tp=0.05;
    float Ti = 0.91;
    float Td = 0.19;*/
    volatile float Kr;
    volatile float Tp=0.05;
    volatile float Ti;
    volatile float Td;
    float yref= -50;
    float y;
    float ep_p, ep_i, ep_d, u_b;
    float U_pr, U_int, U_intp, U_ip;
    float U_d, Ui_d, Ui_d_pop, U_d_pop;
    int Upwm;
    float u_b_OGR;
    float b=1;
    float c=0;
    float Tdf;

    float ep_a;
    float Tt;
    float U_a;
    int out=11;
    int inp=A7;
    int x;
    boolean state;

     String Kr_str, Ti_str, Td_str, yref_str;
     char received;

    void setup() {
    lcd.begin(16,2);
    Serial.begin(115200);
    lcd.clear();
    pinMode(out,OUTPUT);
    pinMode(inp,INPUT);

    analogReference(DEFAULT);
    Timer1.initialize(50000);
    Timer1.attachInterrupt(Myfunction);

    U_int=0;
    U_intp=0;
    Ui_d_pop=0;
    U_d_pop=0;
    y=0;
    U_a=0;

     state=0;

    }

    void loop() {

    if(Serial.available() > 0)
    {
      received = (char)Serial.read();
      if(received == 'a')
      {
        Serial.print(y);
        Serial.print('b');
      }
      if(received == 'w')
      {
        yref_str = Serial.readStringUntil(';');
       // yref = yref_str.toFloat();
      }
      if(received == 'x')
      {
        Kr_str = Serial.readStringUntil(';');
        //Kr = Kr_str.toFloat();
      }
      if(received == 'y')
      {
        Ti_str = Serial.readStringUntil(';');
        //Ti = Ti_str.toFloat();
      }
      if(received == 'z')
      {
        Td_str = Serial.readStringUntil(';');
        //Td = Td_str.toFloat();
      }

    }
    yref = yref_str.toFloat();
    Kr = Kr_str.toFloat();
    Ti = Ti_str.toFloat();
    Td = Td_str.toFloat();

    lcd.home();
    lcd.print("Process");
    lcd.setCursor(0,1);
    lcd.print("yref=");
    lcd.print(yref);
    lcd.setCursor(9,1);
    lcd.print(" ");
    lcd.setCursor(10,1);
    lcd.print("y=");
    lcd.print("    ");
    lcd.setCursor(12,1);
    lcd.print(y);

    }

    void Myfunction()
    {

    Tt=0.3*Ti;
    Tdf=Td/10;

    y=analogRead(inp);
    y=y/4;
    y=y-128;

    ep_p=b*yref-y;
    ep_i=yref-y;
    ep_d=c*yref-y;
    U_pr=Kr*ep_p;
    U_int=U_ip*Tp+U_intp;
    U_ip=ep_i*(Kr/Ti)+U_a;
    U_intp=U_int;
    Ui_d=ep_d*Kr;
    U_d=(Td/Tdf)*Ui_d-(Td/Tdf)*Ui_d_pop-U_d_pop*exp(-Td/Tdf);
    Ui_d_pop=Ui_d;
    U_d_pop=U_d;
    u_b=U_pr+U_int+U_d;

    if (u_b > Max)
     {
     u_b_OGR=Max;
    }
    else if (u_b < Min)
    {
      u_b_OGR=Min;
    }
    else if (u_b>=Min && u_b<=Max)
    {
    u_b_OGR=u_b;
    }

    ep_a=u_b-u_b_OGR;
    U_a=ep_a*(1/Tt);

    Upwm=(int)u_b_OGR+128;
    analogWrite(out,Upwm);

    }

body:
When you say that something is working for sure, then there is a big chance that the problem is in that part. If the problem was somewhere else, then perhaps you could find the problem yourself.

Interrupts are executed one after another (with a few exceptions). Things run smooth when all interrupt routines are as short and as fast as possible. You have no control over the interrupt routine of the serial communication in the Serial library, but at least your own interrupt function should be as short as possible.

Please show us a sketch that has the problem. You have removed the most important part.
If for example your interrupt function calls a Serial function, then it can go wrong because the Serial library uses interrupts itself. If your interrupt function takes longer than the interrupts from receiving data at 115200 baud, then characters could be missed. The keyword 'volatile' should be used in a proper way. The Arduino Mega has a 8-bit microcontroller, that means that when handling an 16-bit or 32-bit variable an interrupt could occur while that variable is read or writting only halfway. And so on, and so on.

**Update**
You have shown the complete sketch, and the interrupt function 'myFunction'  takes a very long time to do all those calculations.

The 'Kr', 'Ti' and 'Td' are written in the loop, and used in 'Myfunction' which is an interrupt routine. They are float variables that are 4 bytes long. That means that 'Myfunction' could be executed when one of those variables are written only halfway. It is better to disable interrupts when writing those variables. To keep disabling the interrupts short, don't disable interrupts when calling .toFloat(). Use temperary variables.

    float yref_temporary = yref_str.toFloat();
    float Kr_temporary = Kr_str.toFloat();
    float Ti_temporary = Ti_str.toFloat();
    float Td_temporary = Td_str.toFloat();

    noInterrupts();
    yref = yref_temporary;
    Kr = Kr_temporary;
    Ti = Ti_temporary;
    Td = Td_temporary;
    interrupts();

I think you have to make 'yref' volatile as well.

The Serial input is 115200 baud, that can be an interrupt every 87µs.
The Timer1 Myfunction runs every 50ms.
The Myfunction takes more than 600µs.

I did not measure the timing of 'Myfunction'. I calculated it for a rough number. 5 float divisions = 5*70µs. 11 float multiply = 11*7µs. 10 float substractions or additions = 10*7µs. Plus analogRead of 112µs. Plus a few more, that adds up to at least 600µs. It could be about 1ms.

There might be more conflicts.
The baudrate is high, and the Serial.readStringUntil is slow because it uses a String object.
There is no error checking for the received values.
The four .toFloat are always called, even when there was no serial data received.
Printing to the lcd display is also done every time the loop runs. There is no need to update the slow LCD display hundreds of times per second. That could be slowed down with millis.

Conclusion: Your 'Myfunction' is a real interrupt routine. When that is busy, the other interrupts have to wait. Since it takes more than 600µs, the Serial interrupts could be missed.
Perhaps a software timer with millis is accurate enough for the calculations. To be able to use millis, the Serial.readStringUntil can no longer be used.


message:
How to fix: Invalid conversion from 'const char*' to 'char*' [-fpermissive]

I'm trying to upload the code from [here][1] to work with an ESP8266. So I copy/pasted the code to the Arduino IDE and I get this error:

> C:\Program Files (x86)\Arduino\libraries\WiFi\src/WiFi.h:79:9: error:   initializing argument 1 of 'int WiFiClass::begin(char*, const char*)' [-fpermissive]

>int begin(char* ssid, const char *passphrase);
>        ^

>exit status 1
>invalid conversion from 'const char*' to 'char*' [-fpermissive]

Can anyone help me with this?

  [1]: https://raw.githubusercontent.com/RuiSantosdotme/Random-Nerd-Tutorials/master/Projects/ESP32/web_server_outputs.ino

body:
The location where you are calling the function begin, has as first parameter a parameter of type const char* instead of char* ... remove the const from this argument type.

Probably you have something like

    const char* s = ....

    ...

    ...begin(s, ...)

Change class s to

    char* s = ...


body:
This `begin()` method expects a modifiable character array as its first argument. That's what you should provide:

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

    char ssid[]           = "YOUR_SSID";      // this is changed
    const char* password  = "YOUR_PASSWORD";  // this is fine
    [...]
    WiFi.begin(ssid, password);


message:
How can I get Serial.print to print a variable thats a char?

I'm trying to write a function as part of my code, and the function basically has to write the name of a parameter, but I can't get it to print properly to the screen. Here is what I've got:

    void dataprint(char parameterName, float dataNum, char unitName);
    {
     Serial.print(",");
     Serial.print(parameterName);
     Serial.print(",");
     Serial.print(dataNum);
     Serial.print(",");
     Serial.print(unitName);
    }
In the actual program part I have something like this:

    char temp = "temperature";
    float t = tempsensor.readTempC(); // just some number that comes from sensor
    char unit = "C";
    dataprint(temp,t,unit);

Right now in the serial monitor I get a question mark or something like that instead of the name I have saved in parameterName or unitName. I want this function to print the same way something like this would show up:

    Serial.print(",");
    Serial.print("temperature");
    Serial.print(",");
    Serial.print(c);
    Serial.print(",");
    Serial.print("C");

Thanks in advance for any help.

body:
To make your code work, you must use character array pointers. A "char" holds only one character, while "char*" can point to a string.

    char foo = 'a';
    char *bar = "string with lots of stuff.";

So the full code to implement your example is:

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

    void dataprint(char *parameterName, float dataNum, char *unitName)
    {
      Serial.print(parameterName);
      Serial.print(",");
      Serial.print(dataNum);
      Serial.print(",");
      Serial.println(unitName);
    }

    void loop() {
      char *temp = "temperature";
      float t = 123.4;
      char *unit = "C";
      dataprint(temp,t,unit);

      while(1)
      {
        //do nothing
      }
    }
Which prints the following to the serial port:

    temperature,123.40,C


message:
Unable to compare char from radio (RF24)

The code below is receiver code using nRF24L01. In the loop section I'm comparing the char that was being sent from the Arduino transmitter. In this case the char array says "I'm off" just like the char array `compare` below. Even though the text is the same, it does not do what it is supposed to do.

Basically the if function below does not seem to work for some reason, both are char arrays (the text[32] and compare[32]) and both will have the same value which is "I'm off" yet it is not registered as the same thing. I cannot figure out what is wrong with the code, please help.

This is the receiver code. The question is about the if function in the loop below.

    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>

    RF24 radio(7, 8); // CNS, CE
    const byte address[6] = "00001";

    void setup() {
      Serial.begin(9600);
      radio.begin();
      radio.openReadingPipe(0, address);
      radio.setPALevel(RF24_PA_MIN);
      radio.startListening();
    }

    void loop() {
      if (radio.available()) {
        char text[32] = "";
        char compare[32] = "I'm off";
        radio.read(&text, sizeof(text));
        Serial.println(text);
        Serial.println(compare);
        // this is the problem  -->
        if (text == compare) {
          // it is supposed to print this but it does not -->
          Serial.println("not on");
        }
      }
    }

This is the transmitter code

    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    RF24 radio(7, 8); // CNS, CE
    const byte address[6] = "00001";
    const int button = 5;

    void setup() {
      radio.begin();
      radio.openWritingPipe(address);
      radio.setPALevel(RF24_PA_MIN);
      radio.stopListening();
      pinMode(button,INPUT);
    }

    void loop() {
      int reading = digitalRead(button);
      if(reading == HIGH) {
        // send a message to the radio
        const char text[] = "I'm on";
        radio.write(&text, sizeof(text));
        delay(1000);
      }
      if(reading == LOW) {
        // send a message to the radio
        const char text[] = "I'm off";
        radio.write(&text, sizeof(text));
        delay(1000);
      }
    }

body:
Finally i found a solution, turns out the problem was that Arduino will not comparison between char == char like this if (char == char). then i decided to CONVERT char to string. this is the example code for Receiver.

    void loop() {

      if (radio.available()) {
        char text[32] = "";
        char compare[32] = "im off";
        radio.read(&text, sizeof(text));
        // you must convert char to String for it to work
        test1 = String(text);
        test2 = String(compare);

        Serial.println(text);
        //Serial.println(compare);

        if (test1 == test2)
        {
        delay(500);
        Serial.println("not on");
        }

      }
i have convert char to String then i compare the value of it, and it works like a charm. if any of you have the same problem with me and solve it after this please give me thumbs up


body:
That is not a good way to solve it.  That is a hack.  The String class does bad things on microcontrollers and it is something you should try to stay away from.  What you need to compare two char arrays is the strcmp function.

    if(strcmp(someCharArray, anotherCharArray) == 0){
        // the strings are the same
    }

Use google to find out more about strcmp.


message:
Convert my if loop code into a switch/case statement

I have made a project where in photosensors constantly read value and if laser is cut by external object, then it beeps the buzzer.

A switch case would make it easy, as suggested by some people.
I have written my short code below, can you kindly help me change it?

Converting all `if` loops into a switch/`case` statement.

     int sensorPin = A0;
     int sensorPin1 = A1;
     int sensorPin2 = A2;
     int sensorPin3 =  A3;
     int sensorValue0 = 0;
     int sensorValue1 = 0;
     int sensorValue2 = 0;
     int sensorValue3 = 0;
     const int BUZZER = 9;
     const int BUZZER1 = 7;
     const int BUZZER2 = 8;
     const int BUZZER3 = 5;

    void setup() {
     Serial.begin(9600);
     pinMode(BUZZER, OUTPUT);
     pinMode(BUZZER1, OUTPUT);
     pinMode(BUZZER2, OUTPUT);
     pinMode(BUZZER3, OUTPUT);
     // put your setup code here, to run once:
    }

    void loop() {
      sensorValue0 = analogRead(sensorPin);
      sensorValue1 = analogRead(sensorPin1);
      sensorValue2 = analogRead(sensorPin2);
      sensorValue3 = analogRead(sensorPin3);
      Serial.println(sensorValue0);
      delay(100);

      if (sensorValue0>920)
       noTone(BUZZER);
      else
       tone(BUZZER, 500);

      if (sensorValue1>850)
       noTone(BUZZER1);
      else
       tone(BUZZER1, 300);

      if (sensorValue2>850)
       noTone(BUZZER2);
      else
       tone(BUZZER2, 700);
    }

body: A switch can only select different discrete values from a single variable. Since you have multiple variables and aren't looking for discrete values you have to use if not switch.


body:
A switch statement wouldn't be appropriate in this case.

You could optimise the code by adding a function that did the work for you and made the main loop look nicer.

    void readValue (const int& sensorPin, const int& limit, const int& buzzerPin, const int& frequency)
    {
      const int value = sensorValue0 = analogRead(sensorPin);
      if (value > limit)
      {
        noTone(buzzerPin);
      }
      else
      {
        tone(buzzerPin, frequency);
      }
    }

That way you could add as many buzzer and sensors as pins allowed.


body:
Actually, you cannot really rewrite this, due to the `>` operator instead of the `==` operator.

Also you are checking three different variables, and only one variable can be used to check in a switch statement.

However, what you can do is to create a function with parameters like:

    void set(int sensorValue, int value, int buzzer, int frequency)
    {
      if (sensorValue > value)
      {
           noTone(buzzer);
      }
      else
      {
           tone(buzzer, frequency);
      }
    }

and call:

     set(sensorValue0, 920, BUZZER, 500);
     set(sensorValue1, 850, BUZZER1, 300);
     set(sensorValue2, 850, BUZZER2, 700);
     set(sensorValue3, ...); // I think you miss this one


body:
Since your conditions looks like :

    bool condition = variable > someValue;

The value of your variable (i.e. *sensorValue*) should therefore be continuous.

However, the *switch* statement is used when the value of our variable is discrete.

You can't consequently use *switch* statements in your code.


body:
" Switch case would make it easy, as suggested by some people."

That's a great example of why free advice can be quite expensive, :)

Unless you are doing something unique, you are better off with your current approach.

edit: with that said, I can see cases where a switch / case structure can be helpful. For example if you need to compare multiple variables through a consistent set of thresholds, one way to do it without making the code too difficult to read would be something like this:

    THRESHOLD_TypeDef threshold(uint16_t val) {
      if (val < VAL1) return THRESHOLD1;
      if (val < VAL2) return THRESHOLD2;
      ...
      if (val < VALn) return THRESHOLDn;
    }

where THRESHOLD_TypeDef is an enumerated type.

and in your code you can write something like this:

       switch (threshold(myval)) {
       case THRESHOLD1: do_something1(); break;
       case THRESHOLD2: do_something2(); break;
       ...

Its advantage is obviously better readability and consistency: you can apply the same function on different variables to generate a consistent set of "classification".

Its disadvantage is also obvious: for each threshold(), you can only test one set of classification. But you can always create multiple functions to be applied to different variables.


body:
Just for fun, here yet another way to handle the issue: Create a C++ class. This code might seem a bit longer than your original code, but the advantage is if you want to add more functionality, you only have to modify the class.

    class Sensor {
    public:
        Sensor(uint8_t analog_pin, uint8_t buzzer_pin, uint16_t threshold, uint16_t tone_duration)
            : analog_pin(analog_pin), buzzer_pin(buzzer_pin), threshold(threshold), tone_duration(tone_duration)
        {
        }
        void setup() {
            pinMode(buzzer_pin, OUTPUT);
        }
        void loop() {
            sensor_value= analogRead(analog_pin);
            delay(100);
            if (sensor_value> threshold)
                noTone(buzzer_pin);
           else
               tone(buzzer_pin, tone_duration);
        }
    protected:
        uint8_t analog_pin, buzzer_pin;
        uint16_t threshold, sensor_value, tone_duration;
    };

Then, just create an array of `Sensor` objects:

    Sensor sensors[] = {
        Sensor(A0, BUZZER1, 920, 500),
        Sensor(A1, BUZZER2, 850, 300),
        Sensor(A2, BUZZER3, 850, 700)
    };
    const uint8_t num_sensors = sizeof(sensors) / sizeof(sensors[0]);

    void setup() {
        for (int i = 0; i < num_sensors; i++) {
            sensors[i].setup();
        }
    }
    void loop() {
        for (int i = 0; i < num_sensors; i++) {
            sensors[i].loop();
        }
    }


message:
Certain String Characters To Int

I have a char* array which looks like this "T 20" and I'd like to extract the "20" and convert it in to an integer. I was thinking of using atoi() but it seems that function will operate on the entire string, not just the bits I want. Memory is a bit tight so is there a function similar to atoi() which allows you to specify which charters to operate on?

body:
How about

    char array[5] = "T 20";
    int num = atoi(array+2);
This obviously assumes that all your strings are of the same format `"A NN"`. If not, you can try parsing it using `strtok()`. See this [excellent answer](https://arduino.stackexchange.com/a/1033/17164).


message:
Compatibility between shields

Despite that I am new to Arduino, I am tasked to invent a serious alarm system and I chose Arduino.
I study electronics, but virtually I am a software programmer and C is my area of expertise.

I ordered the parts I think I will need and the time is immensely pushing me.
The delivery goes slow and it needs to happen before our planned vacation, because
we've been robbed several times so far.
I need to know if I will need another gadgets to deal with a problem I've discovered suddenly.

>>

I plan to stack up these 3 shields

 1. [Arducam-F Shield V2 Camera module shield /w OV2640][1]
 3. [3.5" TFT LCD Display Touch Screen Module][2]
 4. [SIM900 Quad-band GSM/GPRS Shield][3]

From what I've learned the shields 1 and 3 are compatible, as the arducam uses
CS/SD, ICSP, VCC, GND, SDA and SCL
or according to standard pin out table:
I2C_SCL, I2C_SDA, SPI_SCLK, SPI_MISO,
SPI_MOSI, 9, 10, Reset, 5V, GND
and the GPRS shield uses D7 and D0/D1(or D2/D3), 3 I/O ports. For D7.

The arducam however seems to be not stackable and as far as I can not see it is impossible
to make it stackable (Maybe even if I drill holes and solder stackable shield headers)
So it must be the topmost shield.

What about the LCD shield? I also learned that such shields use a lot of pins, so it is possible that there will be no free pins. I also ordered lots of jumper wires of any kind, if that can help.
Maybe I don't need to wire each of the pins in order to make it work or do some extra coding to get it work? I also don't necessarily need the other shields to work while I operate with the screen, so maybe there is a way I can connect/disconnect shields separately with a program or something else I can buy. I have a feeling that this LCD shield will leave no pins for the other shields and I should connect the arducam on another way since it is not stackable.

  [1]: http://www.ebay.com/itm/Arducam-F-Shield-V2-Camera-module-shield-w-OV2640-for-Arduino-UNO-MEGA2560-DUE-/281157392054?hash=item41764956b6:g:MsAAAOSwKtlWnxhS
  [2]: http://www.ebay.com/itm/3-5-TFT-LCD-Display-Touch-Screen-Module-480x320-Arduino-UNO-R3-Board-Plug-Play-/172714215640?hash=item283691c8d8:g:MpcAAOSw~y9ZFCoV
  [3]: http://www.ebay.com/itm/SIM900-Quad-band-GSM-GPRS-Shield-for-Arduino-UNO-MEGA-Leonardo-/321418410538?hash=item4ad607ba2a:g:YikAAOxyRNJSjs3T

body:
Its not just a question of the stackability of the shields and the clash of pins you also need to consider what the shields do.

Stacking the GSM shield under the LCD is going to restrict is tx/rx power unless you have an external aerial.

The LCD will require a large amount of memory and processing power, a 3.5" inch display is really going to push an Uno to the edge, you aren't going to get much time for servicing the GSM and camera.

The camera is also going to require a large amount of RAM and processing time to handle still images.  If you are processing video then I really doubt you will be able use the other shields.

You don't say if you are experienced in Embedded development.  Its different to Linux or Windows dev where resources are almost limitless.  If you don't have experience then you might find the transition quite hard.

Your question was are they compatible, I don't have the evidence but I would say no because of the resources they consume.  Sorry I can't see this project going anywhere fast. :(


message:
Can you charge and use a LiPo battery at the same time?

I have a system that uses an Arduino Uno board as a "brain". All the elements in the system are powered by a single LiPo battery (3cell, 11.1V, 1800mAh). I made a circuit so the arduino can check the battery voltage and decide when it needs to recharge. I also have a circuit that controls the battery charge sequence and interrupts the power when the battery is charged, sending a signal to the arduino interrupting it's power saving mode. The arduino enters the power saving mode when the charging sequence is initiated. The charging circuit uses 12V and 450mA which I plan to supply with a 12V 6W solar panel.

My question is: can I charge the battery while the arduino is still on, but on power savig mode?

If not, how can I make this system self charging while keeping the arduino continuously on?

body:
> can I charge the battery while the arduino is still on, but on power savig mode?

You can draw power from a Li-Ion battery whilst charging it, but it isn't recommended. This is because the load on the battery affects the ability to detect the different phases of charging, and determine the end-of-charge condition.

Instead you should provide a *bypass* facility so that if external power is applied the external power is routed to the Arduino to power it, but when the power is removed the battery provides the power to the Arduino.

The circuit I usually use is:

<!-- 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/hA5Yg.png)

<!-- End schematic -->

When 5V is applied the battery charges up. Q1 is held off. The 3.3V regulator is then powered through D1. When the 5V is removed Q1 is turned on by R1 pulling the gate low and the battery powers the 3.3V regulator.


body: If you need to charge it and rum at the same time, I would recommend getting a Poweboost module from Adafruit. They can handle both, and they also have a low battery indicator.


body:
[Application Note AN1149][1] by Microchip Inc:

> **It is NOT encouraged to attach the system load directly to Li-Ion
> batteries when using a stand-alone Li-Ion battery charge management
> controller with automatic termination feature.**

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

## Why not?

> **1. The charge may never end.**

>Most Li-Ion battery chargers are based on
> Constant Current and Constant Voltage (CC-CV) modes. The termination
> is based on the ratio of charge current and preset constant current
> (Fast Charge). If the system draws current from the battery, the
> charge current will never meet the termination value. This causes the
> non-termination of the charge management circuit.

> **2.  The total system current is limited by the charge
current.**

> It is because the charger will deliver total
system and battery charging current through the
output pin. This solution may be feasible for
some applications that run on constant current,
but it is not recommended.

----------

## So what's the alternative?

A load-sharing switch with a P-MOSFET:

[![Plugged in][3]][3]
> Q1 is OFF When Gate is High
and No Current Flows from the Battery Cell to the
System Load

[![Battery-powered][4]][4]
> Q1 is ON When the Gate is
Low and Current Flows from the Battery Cell to
the System Load.

The App Note contains some really good practival advice on component selection, I highly recommend it.

  [1]: http://ww1.microchip.com/downloads/en/appnotes/01149c.pdf
  [2]: https://i.stack.imgur.com/EEVtp.png
  [3]: https://i.stack.imgur.com/wv3FD.png
  [4]: https://i.stack.imgur.com/WAkg1.png


message:
High Precision Temperature Sensor LMT70 connection to arduino mega

How can I connect an LMT70 temperature sensor (4Pins) to Arduino Mega board for atmospheric temperature measurement. LM35 sensor has got only 3 pins and connections are known. But LMT70 high precision sensor got 4 pins. How to connect it to arduino mega board
Please help.
Thank you.

body:
Every electronics component has a document that describes it. It is called a "datasheet".

This is the page for the LMT70: [ti.com LMT70][1]
The red text is for the datasheet as pdf document, or else you can use the tab "Online datasheet", and the datasheet can also be found under the tab "Technical documents".

According to the datasheet it works with 5V, you can use it with the Arduino Mega (which is a 5V Arduino board). Connect the analog output of the sensor to an analog input of the Arduino Mega.

If you don't use the T_ON, then the datasheets says: "Tie this pin to VDD if not used". That means you can connect T_ON to 5V.

Do you have the chip (the sensor) only, or do you have a module with the sensor on it ?

Since the sensor has an anlog output, the accuracy depends not only on the sensor but also on the Arduino and the Arduino voltage reference. If you need a highly accurate temperature measurement, then you better buy a digital temperature sensor. For example the [Si7051][2].

I suggest to use the 2.56V Internal [Analog Voltage Reference][3].
The sensor has 1375.2mV output at -55°C and 302.8mV at 150°C.

    const float aref = 2.56;  // adjust it to the actual AREF voltage
    int adc_value = analogRead(A0);
    float voltage = float(adc_value) * aref / 1024.0;

    float t1 = voltage - 302.8;  // get rid of voltage offset
    float t2 = t1 * (150.0 + 55.0) / (1375.2 - 302.8); // match range
    float temperature = 150 - t2;  // negate and offset.

When you measure the AREF pin with a good multimeter and fill in the correct voltage in the calculation in the sketch, then you can get 1°C accuracy for the temperature. Perhaps you can get near 0.5°C accuracy, but no more. The sensor is more accurate than the Arduino Mega.

  [1]: http://www.ti.com/product/LMT70/description
  [2]: http://www.silabs.com/products/sensors/si705x-temperature-sensors
  [3]: https://www.arduino.cc/en/Reference/AnalogReference


body:
In situations like this, you always start with reading the device datasheet, understand how it works, how to communicate with the device, and then write your code to implement that communications protocol.

That strategy always works, regardless of the specifics of a given device.


message:
Do AVR delay functions (_delay_us() and _delay_ms()) use timers?

I'm trying to determine if the AVR delay functions `_delay_us()` and `_delay_ms()` use timers in such a way that I can't use those timers for other functionality in my code. If so, what timer does it use?

For reference I'm using an Arduino Uno with ATmega328, but I imagine if it's an AVR function it must work similarly on other devices.

body:
No, these macros expand to calls to `__builtin_avr_delay_cycles()`,
which are compiled into delay loops. It should be noted that:

* the arguments to these macros should be compile-time constants, they
  can be floating point
* the macros are cycle-accurate, e.g. `_delay_us(0.125)` will take
  exactly two CPU cycles on an Uno
* whereas the _CPU time_ used by the call is exactly what you ask for,
  the _physical time_ will be larger if the call gets interrupted.


body:
No.

The long answer is that you can delay via timers, a little bit more painfully within the Arduino framework, or much more efficiently if you are willing to move outside of the arduino framework.

I wrote a set of systick clones for many of the popular 8bit mcus precisely for that.


message:
Strange behaviour on splitting char array and converting the chunks to int

I have this function:

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

    void changeColor(char control[16])
    {
      char _red[3], _green[3], _blue[3], _brightness[3], _white[3];
      int red, green, blue, brightness, white, offset;

      offset = 1;
      for (int i = 0; i < 3; i++) {
        _red[i] = control[i + offset];
      }
      offset = 4;
      for (int i = 0; i < sizeof(green); i++) {
        _green[i] = control[i + offset];
      }
      // strncpy(_green,control+offset,3); // same result
      offset = 7;
      for (int i = 0; i < sizeof(_blue); i++) {
        _blue[i] = control[i + offset];
      }
      offset = 10;
      for (int i = 0; i < sizeof(_white); i++) {
        _white[i] = control[i + offset];
      }
      offset = 13;
      for (int i = 0; i < sizeof(_brightness); i++) {
        _brightness[i] = control[i + offset];
      }

      red = atoi(_red);
      green = atoi(_green);
      //sscanf(_green, "%d", &green); //same result
      blue = atoi(_blue);
      white = atoi(_white);
      brightness = atoi(_brightness);

      Serial.print(" control ");
      Serial.println(control);
      Serial.print(" _red ");
      Serial.println(_red);
      Serial.print(" _green ");
      Serial.println(_green);
      Serial.print(" _blue ");
      Serial.println(_blue);
      Serial.print(" _white ");
      Serial.println(_white);
      Serial.print(" _brightness ");
      Serial.println(_brightness);
      Serial.print(" red ");
      Serial.println(red);
      Serial.print(" green ");
      Serial.println(green);
      Serial.print(" blue ");
      Serial.println(blue);
      Serial.print(" white ");
      Serial.println(white);
      Serial.print(" brightness ");
      Serial.println(brightness);
      //... do something with ints
    }

And by calling from the setup:

     char _control[16]={'6','2','5','5','0','0','0','0','0','0','0','0','0','0','5','0'};
     //6255000000000050

     void setup() {
       Serial.begin(9600);
       // ... do something
       while (!Serial) {
         ; // wait for serial port to connect. Needed for native USB
       }
      changeColor(_control);
    }

I get from console this output:

<!-- language: lang-none -->

       control 6255000000000050
       _red 255ÿ
       _green 000255ÿ
       _blue 000000255ÿ
       _white 000050000000255ÿ
       _brightness 050000000255ÿ
       red 255
       green 255
       blue 255
       white 29951
       brightness 29951

Basically, the char array are filled with more elements than the actual dimension (3), but I don't get error or warnings from the compiler

I also tried with `strncpy`, `strcpy`, `strncat`, and by using the pointer in the for loops

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

    for(int i=0;i<sizeof(_green);i++){
      _green[i]=control+i*sizeof(char)+offset*sizeof(char);
    } // also without the sizeof()

And I got the same result in the console (with nl&cr), any hints?

EDIT:

Added NULL char

      ...
      char _red[4], _green[4], _blue[4], _brightness[4], _white[4];
      int red, green, blue, brightness, white, offset;
      _red[4]='\0';
      _green[4]='\0';
      _blue[4]='\0';
      _white[4]='\0';
      _brightness[4]='\0';
      offset=1;
      for(int i=0;i<3;i++){
        _red[i]=control[i+ offset];
      }
      // same as above

Output:

<!-- language: lang-none -->

    control 6255000000000050
    _red 255
    _green 100255
    _blue 000100255
    _white 0000050
    _brightness 050
    red 255
    green 100
    blue 0
    white 50
    brightness 50

body:
In this piece of code you have a strange mix of upper bounds:

      for(int i=0;i<3;i++){
        _red[i]=control[i+offset];
      }
      offset=4;
      for(int i=0;i<sizeof(green);i++){
        _green[i]=control[i+offset];
      }
     // strncpy(_green,control+offset,3); // same result
     offset=7;
     for(int i=0;i<sizeof(_blue);i++){
       _blue[i]=control[i+offset];
     }
     offset=10;
     for(int i=0;i<sizeof(_white);i++){
       _white[i]=control[i+offset];
     }
     offset=13;
     for(int i=0;i<sizeof(_brightness);i++){
       _brightness[i]=control[i+offset];
     }

The first looks correct at 3.  The second loop has an upper bound of `sizeof(int)` which is 2.  The third loop seems to be `sizeof(char)` which is 1.

Unfortunately non of those values match up with the results you are getting.  What I would try is refactoring whats inside you function to this.

    int Convert (char* buffer, char const* control, const int& offset, char const* name)
    {
        int value = 0;
        for (index = offset; index < offset; ++index)
        {
            buffer[index-offset] = control[index];
        }
        buffer[4] = '\0';
        atoi(buffer);
        Serial.print(name);
        Serial.print(" = ");
        Serial.print(buffer);
        Serial.print("  Value = ");
        Serial.println(value);
        return value;
    }

And then call it to populate your values:

    void changeColor(char control[16])
    {
        char buffer[4]; // You can reuse this buffer, unless you wanted to have separate ones.
        const int red    = Convert (buffer, control, 1, "red");
        const int green  = Convert (buffer, control, 4, "green");
        const int blue   = Convert (buffer, control, 7, "blue");
        const int white  = Convert (buffer, control, 4, "white");
        const int bright = Convert (buffer, control, 4, "bright");
    }


message:
Code flow execution between loop() and timer interrupts

My platform is the Arduino DUE.
I know that the timer counts up to a certain value, then generates an interrupt.
In the Arduino DUE, you can specify the timer value. In other words, you can specify the frequency of the intterupts. You can do this via the `TC_SetRC(tc, channel, rc)` function.

My question is how code flows in general.
Obvisouly the arduino runs the setup function first.
After that it jumps to loop.
But when does tghe timer starts counting down? When you first jump to loop?
Can you figure out how many instructions will be executed in the loop function, before a call to a timer interrupt is performed, for the given frequency you have specified?

After the interrupt is fired, all the code in the interrupt is run.
Then code flow jumps back to loop()?
And when the timer starts counting again? At the same time the code jumps to loop?

If you set up the timer interrupt frequnecy too high, do you run the risk of having code in you loop functin not run at all? (If, for example, you have lots of code inside the loop()).

In that case, would it be wise to put code that you would generally put inside the loop(), inside a timer interrupt?

body:
The timers starts when it is enabled. Either explicitly or via one of The calls to timer functionality.

Once the interrupt fires, current execution is preserved and the isr execution starts. Once you exit the isr, the loop execution resumes from where it pauses

Yes, if your use fires too frequently or takes too long to execute your loop may never gets executed.


message:
Is the ShiftOut tutorial on the official Arduino website really wrong regarding the capacitor?

I'm talking about this tutorial "[Serial to Parallel Shifting-Out with a 74HC595][1]" from the official Arduino website. It provides the following schematic:

[![maybe wrong version][2]][2]

I've read a couple of times now, that the placement of the capacitor is wrong:

> This is a well known shit tutorial which for some unknown reason they refuse to fix.
That capacitor should be connected between the Vcc pin and ground, NOT the latch pin.

Source: [forum.arduino cc/index.php?topic=408135.0][3]

They recommend this placement:

[![maybe better version][4]][4]

Who's right? Please explain where to place the capacitor. Can the arduino even be damaged?

  [1]: https://www.arduino.cc/en/Tutorial/ShiftOut
  [2]: https://i.stack.imgur.com/R2q9b.gif
  [3]: https://forum.arduino.cc/index.php?topic=408135.0
  [4]: https://i.stack.imgur.com/ciAFJ.gif

body:
You can figure out the impedance of that capacitor for high frequency signal....

What they have there is really a low pass filter.

Terrible ideal to out that big of a capacitor there.


body:
You do not need a capacitor to use the 74HC595 in conjunction with `shiftOut()`. I found [this YouTube video][1] to be very useful in explaining how to wire up and code the shift-register for a 7-segment display.

  [1]: https://www.youtube.com/watch?v=cHA-fwiA4Qo


body:
That tutorial, as with a number on the Arduino site, is wrong.

Yes, the capacitor should be across Vcc/GND - it is a decoupling capacitor used to absorb the current surges when you turn LEDs on and off.

Not to mention that with that circuit if you turn on all the LEDs you are overloading the 74HC595. That has a maximum 70mA through Vcc/GND pins. Each LED there (assuming red LEDs at 2V forward voltage) will be drawing about 13.6mA. 8 LEDs would be 8*13.6 = 109mA.

Ouch.

The problem with many of the Arduino tutorials is they were written in the early days of Arduino when they didn't have much knowledge and experience. Since then the arduinosphere has grown and there are people now with far more knowledge and experience than Arduino had at the time the tutorials were written. We come here.


body:
Indeed, it seems like the Arduino tutorial is wrong. I just found the following schematic in [Datasheet SN74HC595 - Texas Instruments](http://www.ti.com/lit/ds/symlink/sn74hc595.pdf) from `10.2 Typical Application`, `Figure 5`:

[![Typical Application schematic TI datasheet][1]][1]

The capacitor connects VCC to GND. Nothing to do with the latch pin.

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


message:
Cannot find solution to "variable out of scope"

First C program. Spent a lot of time looking for a solution. KeyPad produces 'char' instead on 'int'.  Plus I want to display 'End', thus I wrote the 'main' to to support 'char' and thus had to adapt a 'char' to 'int' conversion work around, line 89  Certainly there are other errors.

    extern "C"
    // Microwave ccp

      #include <Arduino.h>
      #include <stdlib.h>
      #include <string.h>
      #include <inttypes.h>
      #include <Keypad.h>
      #include "TM1637.h"
      #include <TimerOne.h>
    class TimingISR
    {
    public:
        TimingISR();
        bool Enable_interrupts, Disable_interrupts;

      char lead_char, unit_sec, tens_sec, num_min;
      int int_unit_sec, int_tens_sec, int_num_min;
      int Count_Seconds, Remainder, brightness = 4, PowerLevel;   //BRIGHT_TYPICAL = 4, BRIGHT_DARKEST = 0, BRIGHTEST = 7
      bool Colon, PointFlag, Points_enable;
      char data_char;
    };

    // these are all Clobal Variables
      int pin_Clk = 2; //  or 3 for IC2
      int pin_DIO = 3; //  or 2 for IC2
      int PIN_RELAY = 4;  // controls power on/off to 'cook'
      int PIN_Beeper = 5; // PWM beeps when finished

      int  pos, Remainder, num;
        // Timer variables
      char tempchar;

      // Read Key Pad, continuously
    const byte ROWS = 4; // Four rows
    const byte COLS = 3; // Three columns
    char lastkey;
    char keys[ROWS][COLS] = {
      {'1','2','3'},
      {'4','5','6'},
      {'7','8','9'},
      {'#','0','*'} };// Define the Keymap
    byte rowPins[ROWS] = { 9, 8, 7, 6 };  // Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
    byte colPins[COLS] = { 12, 11, 10 };  // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
    Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );  // Create the Keypad
    #define ledpin 13
    void setup()
    //        Colon = OFF;   PointFlag, Points_enable   ***************************not coded yet
    {
      pinMode(ledpin,OUTPUT);
      digitalWrite(ledpin, HIGH);
      Serial.begin(9600);
    }
    void loop()
    {    // run repeatedly

       char key = kpd.getKey();
       // if ((key = NO_KEY) || (lastkey = key)); delay(100); exit(0);    }

     {  if (key)  // Check for a valid key.
          switch (key) {

          case ('0'): case ('1' - '0'): case ('2' - '0'): case ('3'-'0'): case ('4' - '0'):  case ('5' - '0'): case ('6' - '0'): case ('7' - '0'): case ('8' - '0'): case ('9' - '0'): //all key integers
     { if ( Count_Seconds > 0 ) // Cooking in progress, thus SHUT DOWN, any numeric key shuts down the power
      {  lead_char = 'C';
         num_min=    'n';
         tens_sec=   'C';
         unit_sec=   'l';
    goto CancelPower;
      } //  Short Delay, then Display “A000”
        else
      {     num_min = tens_sec;  // integers: update the 'time' 'stack' as integers
            tens_sec = unit_sec;
            unit_sec =  (key-'0');  // '0' = 30 base 10 etc
            lastkey = key;
            Colon = ON;
    goto DisplayAll;   // accumulate time value  // any old num_min_segment fall off
      } }     //
      break;  //---------------------------------------

          case ('#'-'0'):  // Start Heating
          if (lead_char != 'A')
    goto OOPS ;
           else  // convert time parts to Count_Seconds
            (  Count_Seconds = int(unit_sec) + int(tens_sec) * 10 + int(num_min) * 60  );
      {       if  (  Count_Seconds > 0 )
    TimingISR(  ) ;
              lead_char = 'c'; //  ’c’ooking
              Colon = ON;
              pinMode(PIN_RELAY, OUTPUT);
              digitalWrite(PIN_RELAY, HIGH);  // turn on the heat
              PowerLevel = 10;
      }
       break;  //---------------------------------------

          case  ('*'-'0'):  // Set Power level or default DEFROST Power level
         //unit_sec_segment = a number as a 'segment' value    // a power level manually inserted
    {   if ( lead_char ==  'A'  &&   num_min == '0' &&  tens_sec == '0' )
    {    if ( unit_sec =  !('0') )         // &&  unit_sec > '0' && unit_sec <= '9' )
     {      int PowerLevel = aoti(unit_sec);
            lead_char = 'P';    //Display "P=n0", n = percent power via duty cycle
            num_min =   '=';
            tens_sec = unit_sec;  //display 'char' as 10's 'percent' value, move number left one place
            unit_sec =  '0';  // insert a zero
     }   else  // power not manually set
     {      PowerLevel = 2;     // 'defrost' = 20 %
            lead_char = 'd';
            num_min =   'E';
            tens_sec =  'F';
            unit_sec =  '_';
     }
    goto DisplayAll;
    }
       else
    //    if ( lead_char != 'A'  ||  num_min != '0' ||  tens_sec != '0' || unit_sec !=  '0' )
    goto OOPS ;
    }     //end if, of Case “*"
          break;  //---------------------------------------

       lastkey = key;
    delay(100);  //100 millisec
    }   // End Of Switch Key
    }  //  End of If (Key)
    //return

    // Beginning of GOTO's--------------------------------------
    {
    OOPS:
         lead_char = 'o';   //Display "ooPS"
         num_min =   'o';
         tens_sec=   'P';
         unit_sec =  'S';   // then Short Delay, then Display “A000”
    CancelPower:
          pinMode(PIN_RELAY,OUTPUT);
          digitalWrite(PIN_RELAY, LOW);  // turn off the heat
    goto DisplayAll;  //ready to accumulate 'heating' time input
        delay (3000);     //let it display for 3 Count_Seconds, then clear the display
        lead_char = 'A';        //ready to accumulate 'heating' time input
        num_min =   '0';
        tens_sec =  '0';
        unit_sec =  '0';
        Disable_interrupts;
        int Count_Seconds = 0 ;
    DisplayAll:

    // DisplayAll:  //Would like to put this into the 7 segment display
     // Address each 7 segent unit, one after the other; left to right
    {    for ( pos = 0 ; 3 < 4; pos++);
          if ( pos = 0 )
            char_data = lead_char
          if ( pos = 1 )
            char_data = num_min
          if ( pos = 2 )
            char_data = tens_sec
          if ( pos = 3 )
            char_data = unit_sec

    if ( char_data='0') ; num = 1; // the 7 segment display 'h' only allows for integers 0 through 15, i.e. HEX characters
    if ( char_data='1') ; num = 2;
    if ( char_data='2') ; num = 3;
    if ( char_data='3') ; num = 4;
    if ( char_data='4') ; num = 5;
    if ( char_data='5') ; num = 6;
    if ( char_data='6') ; num = 7;
    if ( char_data='7') ; num = 8;
    if ( char_data='8') ; num = 9;
    if ( char_data='9') ; num = 10;
    if ( char_data='A') ; num = 11;
    if ( char_data='B') ; num = 12;
    if ( char_data='C') ; num = 13;
    if ( char_data='d') ; num = 14;
    if ( char_data='E') ; num = 15;
    if ( char_data='F') ; num = 16;
    if ( char_data='c') ; num = 17;
    if ( char_data='H') ; num = 18;
    if ( char_data='h') ; num = 19;
    if ( char_data='I') ; num = 20; //left vertical 2 segments
    if ( char_data='i') ; num = 21;
    if ( char_data='L') ; num = 22;
    if ( char_data='l') ; num = 23; /right /vertical 2 segments
    if ( char_data='n') ; num = 24;
    if ( char_data='O') ; num = 25;
    if ( char_data='o') ; num = 26;
    if ( char_data='P') ; num = 27;
    if ( char_data='r') ; num = 28;
    if ( char_data='S') ; num = 29; //same as a five
    if ( char_data='U') ; num = 30;
    if ( char_data='u') ; num = 31;
    if ( char_data=' ') ; num = 32;
    if ( char_data='=') ; num = 33;
    if ( char_data='-') ; num = 34; //dash / minus
    if ( char_data='_') ; num = 35; //under score
    if ( char_data='[') ; num = 36; /left /bracket
    if ( char_data=']') ; num = 37; //right bracket
    // there are other usefull, such as "top score", "middle score... "top minus", "bottom Minus",
    // which yoou could assign some other othervise unprintable character as a proxy, e.g  the ampersant to display a "top position minus sign"

    }
    Disable_Interrupts;
      TM1637DisplayAll(uint8_t num, uint8_t pos);
    Enable_Interrupts;
    }
    return(0)
    }
    }  //  End of void LOOP()

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

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

body:
 1. The first line says `extern "C"` but you haven't scoped it, I'm really not sure what you are trying to achieve or if it will work.  Personally I would remove that line.
 2. "Microwave ccp" come compilers complain if the filename is not right.  As far as I know it should be either .cc or .cpp, but its proably just a typo in the comment, because I doubt you would get this far if it was wrong.
 3. Pins 2 and 3 for I2C, its normally A4 and A5.
 4. Line 58 The reason your commented out code didn't work is `(lastkey = delay)` you should have used equivalence (==) rather than assignment (=).
 5. Use function calls rather than goto statements, it isn't the 1970s anymore! :)
 6. `int(variable)` is not casting it is creating an integer from variable and then its disposed of when it goes out of scope.  `(int)variable` is casting.
 7. `for (pos = 0; 3 < 4; pos++);` This will cause you problems, because its an empty loop, does nothing, which means `pos` doesn't have the value you think it does.

Please don't take any of this the wrong way, I'm not a teacher but I need to explain what has gone wrong with you code and how you can fix it.  It is not personal criticism, I bet my first program was ten times worse.

You seem to have a misunderstanding of "variable scopes".  Put simply a variable can only be 'seen' after the point you declare it and within the immediate curly braces {} and all child braces. e.g.:

    int GlobalVariable = 1; // Visible through-out the code
    void loop ()
    {
        int LoopVariable = 2;
        for (int ForVariable = 0 ForVariable < LoopVariable; ++ForVariable)
        {
           ++GlobalVariable;
        }
        Serial.println (ForVariable);  // ERROR
    }
    void AFunction()
    {
        Serial.println(LoopVariable);//ERROR
    }

You immediate error is you have defined the variable `unit_sec` inside class TimingISR and you are accessing it like a local variable.

Now The way you have defined `class TimingISR` is like designing a car, its fine on paper but you can't drive it until you build one.  As far as I can see you haven't instantiated an instance of TimingISR.  It sounds complex but you have been doing it for int and char (They aren't classes, but its very similar)

    int pin_clk = 2;
    TimingISR aTimingISR;

If a value should change define it as const.

    const int pin_clk = 2;

If it does change you will get a compilation error rather than suddenly sending the I2C clock signal to the on board LED.

goto is evil.

    case ('0'): case ('1' - '0'): case ('2' - '0'): case ('3' - '0'): case ('4' - '0'):  case ('5' - '0'): case ('6' - '0'): case ('7' - '0'): case ('8' - '0'): case ('9' - '0'): //all key integers
      { if (Count_Seconds > 0) // Cooking in progress, thus SHUT DOWN, any numeric key shuts down the power
      {
       lead_char = 'C';
       num_min = 'n';
       tens_sec = 'C';
       unit_sec = 'l';
       goto CancelPower;

    CancelPower:
      pinMode(PIN_RELAY, OUTPUT);
      digitalWrite(PIN_RELAY, LOW);  // turn off the heat
      goto DisplayAll;  //ready to accumulate 'heating' time input
      delay(3000);         /// NEVER EXECUTED
      lead_char = 'A';     /// NEVER EXECUTED
      num_min = '0';       /// NEVER EXECUTED
      tens_sec = '0';      /// NEVER EXECUTED
      unit_sec = '0';      /// NEVER EXECUTED
      Disable_interrupts;  /// NEVER EXECUTED
      int Count_Seconds = 0;/// NEVER EXECUTED
     DisplayAll:

      // DisplayAll:  //Would like to put this into the 7 segment display
      // Address each 7 segent unit, one after the other; left to right
    // Code cut (but it should be == not =)
      Disable_Interrupts;
      TM1637DisplayAll(uint8_t num, uint8_t pos);
      Enable_Interrupts;

Code isn't being executed because gotos never return to the call, they just carry on from the label.  Try this instead:

    // TimingISR& theISR means you can change the values in theISR
    // TimingISR  theISR means you copy theISR and all changes are lost when the function exits.
    // TimingISR const& theISR means you can't change the values in theISR
    void CancelPower (TimingISR& theISR)
    {
      pinMode(PIN_RELAY, OUTPUT);
      digitalWrite(PIN_RELAY, LOW);  // turn off the heat
      DisplayAll(theISR);  //ready to accumulate 'heating' time input
      delay(3000);     //let it display for 3 Count_Seconds,
      ClearDisplay();
      theISR.lead_char = 'A';        //ready to accumulate 'heating' time input
      theISR.num_min = '0';
      theISR.tens_sec = '0';
      theISR.unit_sec = '0';
      theISR.Disable_interrupts(); // This should be a function that does something, not a bool
      theISR.Count_Seconds = 0;
    }

I'm afraid that's just some of the things you need to change, ***BUT*** that's one hell of a program for a first attempts and that's the only reason I raised so many issues.  Try again and post it again, I'd love to  see the differences.


message:
Use MQ2 Sensor with Arduino Uno without breadboard?

I want to make a small and compact gas sensor using the Arduino Uno and MQ2 sensor. However all sites list a breadboard as a requirement.

Now, the MQ2 has A0, D0, GND, VCC, pins and the Uno also has A0, GND, 3.3V and 5V connectors.

So can I use Male to Female Jumper Wires to directly connect these? I am not using anything else like LEDs or speakers.

My code keeps the inbuilt LED ON when smoke level is LOW and blinks when the Level is HIGH. Also will I need any resistor for it?

body:
Usually I don't think at the UNO as "small and compact"; I usually prefer to use a barebone atmega or an arduino pro mini / nano as alternatives (nano has inbuilt usb, pro mini doesn't). But anyway...

The [SeeedStudio MQ2][1] has four pins, but no D0 pin; it has Vcc, GND and A0 and a NC pin (which means do not connect this pin).

So... Yes, The sensor is 5V powered and has an analog out interface, so you should connect the A0 pin to any analog input on the arduino (A0..A7); you are not forced to use A0.

Be careful that the sensor uses 800mW of power (160mA at 5V) in the pre-heating, so you are not advised to use it form a battery source

  [1]: http://wiki.seeed.cc/Grove-Gas_Sensor-MQ2/


body: Yes, you can use male to female jumper wires to directly connect them. Breadboard is not a requirement. Also, you don't need any resistors.


body:
This is point-to-point wiring, a technique loved by high-end audio amplifier fans:

[![point-to-point][1]][1]

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


body:
You can connect it exactly like this.
I'm using female-female jumper wires and have soldered pins onto the UNO clone to enable me to do this.

[![MQ2 Connected to Uno R3 Clone close-up showing pins soldered onto board][2]][2]

Pins on sensor from left to right A0 - D0 - GND - VCC

You can also find the wiring diagram on-line for a barebones sensor
if you've not got the sensor module.

here [MQ2- Sensor Information][4]

  [2]: https://i.stack.imgur.com/HGb3T.jpg

  [4]: https://playground.arduino.cc/Main/MQGasSensors

You can either use the D0 output pin to turn on an LED in the presence of gas / smoke or you can use the A0 to report a gas / smoke level.

The code in my other reply is for the analogue reporting of the sensor value.
The Digital output is either on or off and the potentiometer on the back of the sensor will adjust the point at which the D0 pin report a High output level, if it's not set right then the D0 pin won't actually output a voltage.


body:
MQ2 flammable gas and smoke sensor detects the concentrations of combustible gas in the air and ouputs its reading as an analog voltage.
The sensor can measure concentrations of flammable gas of 300 to 10,000 ppm.

The sensor can operate at temperatures from -20 to 50°C and consumes less than 150 mA at 5 V.

Connecting five volts across the heating (H) pins keeps the sensor hot enough to function correctly. Connecting five volts at either the A or B pins causes the sensor to emit an analog voltage on the other pins.

A resistive load between the output pins and ground sets the sensitivity of the detector. Please note that the picture in the datasheet for the top configuration is wrong. Both configurations have the same pinout consistent with the bottom configuration.

The resistive load should be calibrated for your particular application using the equations in the datasheet, but a good starting value for the resistor is 20 kΩ.

[DataSheet PDF Here][1]

        * Smoke/Gas Sensor Module project
         * tutorial url: http://osoyoo.com/?p=671
         */
        void setup()
        {
            Serial.begin(9600);
        }

        void loop()
        {
            int val;
            val=analogRead(0);
            Serial.println(val,DEC);
            delay(100);

    }

[![MQ2 - Wiring Diagram][2]][2]

  [1]: https://www.pololu.com/file/0J309/MQ2.pdf
  [2]: https://i.stack.imgur.com/H9otg.jpg


message:
Function pointer or abstract class?

I need to implement callback in my C++ library. The "proper" C++ way of doing it would be to create an interface (or pure abstract class) and pass it to interested party. I'm wondering though, would that be optimal?

My analysis:

* Function pointer - occupies 2 bytes in memory (+code of function)
* Class derived from abstract one - occupies 2 bytes in memory PLUS 2 bytes for VMT (since we have derived method) PLUS size of VMT table (if any) (+code of method).

Is optimizer smart enough to compile abstract class with single method as method pointer? Which solution is more optimal in regard of memory and speed? Is my analysis correct?

body:
The best way is to find out yourself, there are memory 'debug'  functions to show the amount of free memory, so if you do some tests you know for sure what the compiler optimizes.

See e.g. [AvailableMemory][1] library.

It might be quite hard to exactly calculate and predict the optimizer. However, is it really needed to optimize? Mostly it is best to not optimize before knowing it is really necessary.

  [1]: https://playground.arduino.cc/Code/AvailableMemory


body:
Sometimes you want your callback to be fed some data that you provide
when you register that callback. Here is a very common callback pattern
in plain C that does that:

    // The API:

    typedef void (*callback_t)(void *data);
    void register_callback(callback_t callback, void* data);

    // Usage:

    typedef struct {
        // stuff only the user of the API knows about.
    } my_data_t;

    void my_callback(void *in_data)
    {
        my_data_t *data = (my_data_t *) in_data;
        // do something with data->foo, data->bar...
    }

    // ...somewhere else:
    my_data_t my_data = { stuff... };
    register_callback(my_callback, (void *)&my_data);

The problem is: it's clumsy. C++ classes allow you to pack together the
code (the callback function) and the data it needs. Thus, if in your use
case you need to pass data to the callback, by all means use a C++
class. It will make your life easier and you are unlikely to even notice
the memory overhead.

However, if you only need to pass a function, with no attached data,
then a plain function pointer would be both easier for the API user and
optimal memory-wise.