text:
How can I add a potentiometer and more buttons to my custom game controller?
I'm new to using Arduino, and know next to nothing about programming. I'm currently trying to add a potentiometer, and possibly a few more button inputs to my 3D-printed guitar controller project
It uses an Arduino Pro Micro, the code is just an example file from this joystick library that I mostly just played around with using trial and error, and this pinout diagram from Sparkfun, with this being what I ended up with:
#include <Joystick.h>

Joystick_ Joystick;

void setup() {
  // Initialize Button Pins
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);

  // Initialize Joystick Library
  Joystick.begin();
}

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 0;

// Last state of the button
int lastButtonState[11] = {0,0,0,0,0,0,0,0,0,0,0};

void loop() {

  // Read pin values
  for (int index = 0; index <= 10; index++)
  {
    int currentButtonState = !digitalRead(index + pinToButtonMap);
    if (currentButtonState != lastButtonState[index])
    {
      Joystick.setButton(index, currentButtonState);
      lastButtonState[index] = currentButtonState;
    }
  }

  delay(10);
}

This is the original example code that I used:
// Simple example application that shows how to read four Arduino
// digital pins and map them to the USB Joystick library.
//
// Ground digital pins 9, 10, 11, and 12 to press the joystick
// buttons 0, 1, 2, and 3.
//
// NOTE: This sketch file is for use with Arduino Leonardo and
//       Arduino Micro only.
//
// by Matthew Heironimus
// 2015-11-20
//--------------------------------------------------------------------

#include <Joystick.h>

Joystick_ Joystick;

void setup() {
  // Initialize Button Pins
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);

  // Initialize Joystick Library
  Joystick.begin();
}

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 9;

// Last state of the button
int lastButtonState[4] = {0,0,0,0};

void loop() {

  // Read pin values
  for (int index = 0; index < 4; index++)
  {
    int currentButtonState = !digitalRead(index + pinToButtonMap);
    if (currentButtonState != lastButtonState[index])
    {
      Joystick.setButton(index, currentButtonState);
      lastButtonState[index] = currentButtonState;
    }
  }

  delay(50);
}

I started this project in late February/early March, but only got to the Arduino part recently. I've had my v1 working for a little over a month using this code, and I've been working on the v2 design (adding a whammy bar and repositioning the start and select buttons) since then. I only just got to the point where I need to change the code last week.
From the comments in the example and some trial and error, I figured out that "const int pinToButtonMap = 9" is the lowest-numbered pin that it will use, and "for (int index = 0; index < 4; index++)" seems to determine the rest of the pins, so I changed 9 to 0, and "< 4" to "< 18" (the number of usable pins), and it kind of worked. Pins 0-10 and 14-16 now worked as button inputs, but button 14 (which would've been on pin 13, which doesn't exist on the Pro Micro) reads as constantly pressed, and pins A0-A3 (digital pins 18-21) don't read anything. If instead, I change it to "< 19", "< 20", etc. It just stops working completely, and if I change it to "< 11" or "<= 10" (my current code), all the pins from 0-10 work, and there are no phantom button presses
Also, I'm honestly not planning on learning any kind of real programming anytime soon. Maybe in the future, but for now, I just need enough to get this working with a 10k potentiometer (the same type that official Guitar Hero controllers use for their whammy bars) and possibly a few more button inputs (I might add a tilt sensor and maybe a D-pad in a future version)

Beautiful work with the 3D-printed guitar!  You have already spent a lot of time and effort with the physical design and construction of the controller, so I recommend you plan on spending some quality time with basic Arduino programming, including the basic pin layout for the Pro Micro and the basics of programming in the Arduino language (basically C++)
You can find all you need to know in the example programs that come with the Arduino IDE (File -> Examples - 01.Basics) and with the many available tutorials (search for Arduino tutorial).  Here's one that seems to be pretty clear https://www.youtube.com/watch?v=QO_Jlz1qpDw
You'll also need to look at one of the many Arduino pinout diagrams for the Pro Micro, like this one https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/hardware-overview-pro-micro
From the diagram, it appears you can use pins 2-10 and 16-21 for digital I/0 (for your buttons), but you'll need to use one of 10, 18-21 for your potentiometer input.  So, as one other poster already noted, you should use an array of pin numbers and then read each pin by indexing into the array.
For the potentiometer interface, one of the supplied examples in '01.Basics' is the 'AnalogReadSerial' program, which should get you started.  To use this program, connect the center pin of a potientiometer to pin 18(A0), and the other two to VCC & GND. Upload the program to the Pro Micro, and you should get some console printouts that vary when you change the potientiometer setting.
Make your programs very small to start with - think of them as disposable snippets that will later be incorporated into the final program.  One snippet just for the potentiometer, and another snippet just for, say, 4 buttons that connect to pins 2, 9, 16 & 21 just to make sure your array indexing scheme works.  Then when all is working, the snippets can be combined into a 'final' (nothing is ever really final in the Arduino world).
And lastly, use serial 'print' statements liberally for test & debug; they will save you no end of trouble & frustration.  You can comment them out after all testing has been done, or just leave them in.  In most projects the Serial.print statements don't take up enough time or memory to matter.
Welcome to the Arduino world!  You'll love it!
Frank

It seems pins 11, 12 and 13 do not exist as input pins and pins 0 and 1 are used for RX/TX which you don't want to use neither probably.
So instead of using a for loop iterating over indices, you should create an array with pin numbers and use that instead, something like:
Create globally:
int input_pins = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 14, 15, 16, ... };

Use in loop:
for (int index = 0; index < sizeof(input_pins) / sizeof(int); index++)
{
    int currentButtonState = digitalRead(input_pins[index]);

You can use the same for to set the pin modes in the setup:
for (int index = 0; index < sizeof(input_pins) / sizeof(int); index++)
{
    pinMode(input_pins[index], INPUT_PULLUP);
}

sizeof(input_pins) / sizeof(int) will give the amount of items within the array. You can now easily change it depending on the pin numbers.
I suggest you learn a bit of coding to at least understand what you change, it will make your life much easier as you progress.
In case you want more pins beyond the actual existing pins, you need to use a multiplexer like 74HC595; there are plenty examples how to use this.

Don't you mean digitalRead(input_pins[index]) instead of just digitalRead(index)?

@chrisl Of course, thanks for the fix (I updated my answer).

I suggest you learn a bit of coding to at least understand what you change, it will make your life much easier as you progress

I do eventually want to learn to code, but that's just not something I'm interested in doing (or have time for) in the immediate future. For now, I just want to get this working, so I have more time for other 3D printing projects I'm working on

In case you want more pins beyond the actual existing pins

That won't be a problem for this project. At the absolute most, I need 15 input pins out of the 18 available

@taj1994 Ok clear for both. About the number of pins, of course you shouldn't add something complicated when you know beforehand it will be never needed. Good luck with your project.


text:
Can I control LED brightness with potentiometer without any code, as well as reading the potentiometer value?
I am just getting back into electronics and have started to play around with making my own button box.
I am trying to control an LED's brightness using a potentiometer, while also reading the potentiometer's value with the Arduino's analogue pin. I want to limit the number of pins I am using for things because I have lots of buttons that will need to be hooked up, so I am trying to control the LED without any code.
I have put together the following circuit (sorry, not my tidiest diagram. I am also using a Pro Micro rather than a Leonardo, but I didn't think that would make any difference :) ).

This works to a degree. I am able to adjust the LED brightness using the pot, and I do get a reading on the Arduino from the pot, however, the reading does not go up linearly as I would expect. It seems to get to about 500 out of 1023 at 4/5 of the rotation and then jumps up to 1023 within the last 1/5.
Could someone explain why this happens, and if it is even possible to do what I am attempting?
Thanks in advance!

the resistor and the LED are in parallel with the pot .. just having a resistor in paralel causes non-linearity ... furthermore, the LED is not linear, so its "resistance" varies with the amount of current flowing through it

if you want linear response in the reading, then use two ganged pots

why are you doing this anyway?

You could try driving the LED through a MOSFET. If you get the parameters right, so that the MOSFET stays in it's linear realm, that should work I think. The gate of the MOSFET draws nearly no current, thus the measurement through A0 should not be disturbed by it.

@jsotola Thanks for explaining this. I have ordered a few dual gang pots to try this out.

Thanks for all the suggestions.
In the end, I ordered some dual-gang potentiometers as jsotola suggested and Mejenko confirmed would work. These are working perfectly in my circuit now.
Thanks again!

You need to "buffer" the potentiometer to separate it from the LED and resistor. The simplest circuit for that is a unity-gain voltage follower with an op-amp:

simulate this circuit – Schematic created using CircuitLab
You want to choose a "Rail to Rail I/O" op-amp so that it can get right down to 0V and right up to 5V, otherwise you will clip the top and bottom of the range of the potentiometer.

So you're using an op-amp to create a "stiff" variable voltage from the voltage divider so the load of the LED doesn't affect the ADC reading? I wish my analog electronics chops were stronger.

It's worth noting that you want to be sure to use a linear pot. A log pot would give very squirrelly results.

Basically, yes. The potentiometer is just a reference for the opamp to create it's own output with lower impedance.

And then the current limiting resistor lets more or less current though based on the input voltage, thus varying the brightness of the LED. I like it.

The resistor basically converts the voltage into a predictable current through ohms law.

Yeah, that part I get.

@Majenko Thanks for this explanation, I will read up on op-amps as I have not come across them before. Does this mean jsotola's suggestion of using dual gang pots not work? I am not all that familiar with analogue electronics, so forgive me if I have misunderstood something.

A dual gang pot will work fine, but if you don't want to use one (or can't get hold of one of the right type) then a buffer is the way to go.

@Majenko Thanks, I have ordered a few of them so I will report back here once I get it working.

I am surprised that the pot has survived so far. LEDs are current devices not voltage devices. The above circuits will work to some extent but not very well. You need to vary the current either using an adjustable current source/sink or PWM.

Some good remarks have already been made by jsotola.
Potentiometer types
(updated because of Majenko's comment):
Note there are three types of pots:

Logarithmic (with name A<value>K, e.g. A50K for a logarithmic 50K pot)
Linear (with name B<value>K, e.g. B50K for a linear 50K pot)
Reserve logarithmic/Exponential (with name C<value>K, e.g. C50K for a rserve logarithmic 50K pot)

Mapping values
However, in code you can map a value from a pot to any other value, even from logarithmic/linear to anything you want, using logarithmic or other functions available in C/C++.
Shift Registers
Also, to reduce the number of pins you need for buttons you can use shift registers. The most known is 74HC595 for output and in your case you need an input shift register, which is 74HC165, see e.g. https://dronebotworkshop.com/shift-registers/ or https://playground.arduino.cc/Code/ShiftRegSN74HC165N/

Actually, to be pedantic, there are three types of pot: linear, logarithmic, and inverse logarithmic. Audio pots are actually inverse logarithmic. Exponential, if you like.

@Majenko Thanks for the comment, however, I everywhere read that audio pots/tapers are A type.

Yes, a for audio. Log tapers are rare. Inverse log audio are more common.

@Majenko, thanks for the clarification. I never heard of C types before, I used A for a guitar pedal (never finished, but learned a lot).

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Error: invalid application of 'sizeof' to incomplete type 'int []' when trying to compute the size of an array in a library
I have created a library that contains an array. This is the .h file:
class Lib {
  public:
    static int arr[];
};

And this is the .cpp file:
#include "Lib.h"

int Lib::arr[] = {0, 1, 2, 3};

When trying to compute the size of this array from within the library, it works just fine. When trying to do this from a sketch, I get the error mentioned in the title. This is the sketch I'm using:
#include <Lib.h>

void setup() {
  sizeof(Lib::arr);
}

void loop() {}

What is the problem here?

Maybe you can try to add a constant integer inside your library containing the sizeof of the array and in your sketch use that integer.

@LukasFin I added an answer.

It seems as if the static initializer has not been executed when the sketch is started.  That seems strange to me. Did you tried to access the first array element (for example) from within the sketch? I would also use some uncommon values to initialize the array e.g. 53, 33, 4, 12 to be sure you do not access the 0 initialized memory at Lib:arr[0].  If you find the correct value, then at least the initialization  works. But then, I have no better explanation. Btw: the correct C++ initialization aof static vars is int Lib::arr[4] = {0, 1, 2, 3};. Perhaps that matters.

Sorry, my former comment is nonsense. As this is a compiler error and 'sizeof' is a compiler function that works on declared types, the error is of cause explainable. In the header file the array is not initialized and its size is not specified. The header file is the only thing the compiler knows when compiling the sketch. The cpp file is compiled to an object file in another step. The object file is linked after the compile runs.  So all things that happen in the cpp File are unknown to the compiler when it compiles the sketch. If you declare the array with a size it will work. I'm so ...

The reason is that in your sketch you import only the header file (which is good). However, there it is an array (int[]), not the initialized array.
For that you would need to include the cpp but that is bad practice (if even possible).
So instead, create a new (constant) variable, and assign it.
(more or less pseudo code, due to lack of a compiler):
Lib.h:
class Lib {
  public:
    static int arr[];
    static int arr_length;
};

Lib.cpp:
#include "Lib.h"

int Lib::arr[] = {0, 1, 2, 3};
int Lib::arr_length = sizeof(Lib::arr);

Sketch:
#include <Lib.h>

void setup() {
  Lib::arr_length;
}

void loop() {}

See also the comment of LukasFun below. It is also possible to set the size of the array in the header file.
My advice though is keeping all assignments in the implementation (cpp) file. The header file is for defining items, the implementation file for initializing/assigning. But it works too, to initialize items in the header file.

I just tried setting the size of the array directly in the .h file. If I do this, the sketch compiles without any errors. Maybe you could add this to your answer.

@LukasFun True, I added the comment, however, it's still better to do initializations in the implementation file.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
cant figure out how to fix this compile error
evrything worked for a bit and changed to much to get it working again. dont really understand the error.
[![C:\Users\bavob\AppData\Local\Temp\ccyfrkaL.ltrans0.ltrans.o: In function `loop':
C:\Users\bavob\Documents\Arduino\counte_up/counte_up.ino:96: undefined reference to `num_Write(int)'
collect2.exe: error: ld returned 1 exit status
exit status 1
Fout bij het compileren voor board Arduino/Genuino Uno]1]1
  { 1, 1, 1, 1, 1, 0, 1 }, // 0
  { 0, 1, 1, 0, 0, 0, 0 }, // 1
  { 1, 1, 0, 1, 1, 1, 0 }, // 2
  { 1, 1, 1, 1, 0, 1, 0 }, // 3
  { 0, 1, 1, 0, 0, 1, 1 }, // 4
  { 1, 0, 1, 1, 0, 1, 1 }, // 5
  { 1, 0, 1, 1, 1, 1, 1 }, // 6
  { 1, 1, 1, 0, 0, 0, 0 }, // 7
  { 1, 1, 1, 1, 1, 1, 1 }, // 8
  { 1, 1, 1, 0, 0, 1, 1 }  // 9
};

int pin = 2;
int buttonState = 0;
const int button = 12;
int led = 13;
int randVal;
bool pressVal;
void num_Write(int);
void setup() {
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  pinMode(button, INPUT);
}

void loop() {
  buttonState = digitalRead(button);
  if (buttonState == LOW) {
    turnOff();
    pressVal = false;
  }
  else
  {
    if (pressVal == false)
    {
      randVal = rand() % 10;
      pressVal = true;
    }
    Serial.println(randVal);
    if (randVal == 0)
    {
      void zero(int number);
      num_Write(0);
    }
    else if (randVal == 1)
    {
      void one(int number);
      num_Write(1);
    }
    else if (randVal == 2)
    {
      void two(int number);
      num_Write(2);
    }
    else if (randVal == 3)
    {
      void three(int number);
      num_Write(3);
    }
    else if (randVal == 4)
    {
      void four(int number);
      num_Write(4);
    }
    else if (randVal == 5)
    {
      void five(int number);
      num_Write(5);
    }
    else if (randVal == 6)
    {
      void six(int number);
      num_Write(6);
    }
    else if (randVal == 7)
    {
      void seven(int number);
      num_Write(7);
    }
    else if (randVal == 8)
    {
      void eight(int number);
      num_Write(8);
    }
    else
    {
      void nine(int number);
      num_Write(9);
    }
  }
}

void zero(int number)
{
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[number][j]);
    pin++;
  }
}

void one(int number)
{
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[number][j]);
    pin++;
  }
}

void two(int number)
{
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[number][j]);
    pin++;
  }
}
void three(int number)
{
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[number][j]);
    pin++;
  }
}
void four(int number)
{
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[number][j]);
    pin++;
  }
}
void five(int number)
{
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[number][j]);
    pin++;
  }
}
void six(int number)
{
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[number][j]);
    pin++;
  }
}
void seven(int number)
{
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[number][j]);
    pin++;
  }
}
void eight(int number)
{
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[number][j]);
    pin++;
  }
}
void nine(int number)
{
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[number][j]);
    pin++;
  }
}
void turnOff()
{

}

You call function num_Write a lot, you create a forward declaration:
void num_Write(int);
But you forgot to create the implementation.
If you would have forgot the forward declaration the function would not be known at all (and you would get a compiler error). But with the forward declaration you let the compiler know the signature of num_write (so the return value and argument types).
When the linker wants to link all object (.o) files together it cannot find an implementation of the function num_write and you get this error. Hence ld is the linker.

So what should I need to do to fix it?

create an implementation for num_Write … so write void num_Write(int value) { … } where … contains the implementation (what the function should do).


text:
Still getting "stk500_recv(): programmer is not responding" while uploading to bare ATmega328P
SOLVED! See bottom.
I know this question has been asked a lot (believe me, I've been Googling for solutions for 3 days, and have come across many posts on SE), but none of the posts I've found have solved my issue. Much of the problem, I think, is many of the solutions are several years old and discuss options either no longer available in the IDE, or no longer valid for the hardware.
I have an ATmega328P-PU on a breadboard. Largely following this guide, I hooked it up like this in order to burn the bootloader.

I uploaded the "Arduino ISP" sketch from Examples to my Uno, and selected "Arduino as ISP" as the programmer. I tried selecting "Arduino Duemilanove or Nano w/ ATmega328" from the boards menu (per the guide), but the option no longer exists in standard install of IDE v.1.8.13. I tried "Arduino Duemilanove or Diecimila", as well as "Arduino Nano" as boards, both with "ATmega328P" as the processor (and, in the case of Arduino Nano, also tried "ATmega328P (Old bootloader)", as mentioned several times). All failed.
I finally found a reference to the MiniCore board library, installed it, selected "ATmega328", with "External 16 MHz" for the clock, and was finally able to burn the bootloader.
C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude -CC:\Users\<username>\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.8/avrdude.conf -v -patmega328p -cstk500v1 -PCOM3 -b19200 -e -Ulock:w:0x3f:m -Uefuse:w:0b11111101:m -Uhfuse:w:0b11011110:m -Ulfuse:w:0b11110111:m

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\<username>\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.8/avrdude.conf"

         Using Port                    : COM3
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.04s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: erasing chip
avrdude: reading input file "0x3f"
avrdude: writing lock (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x3f:
avrdude: load data lock data from input file 0x3f:
avrdude: input file 0x3f contains 1 bytes
avrdude: reading on-chip lock data:

Reading | ################################################## | 100% 0.02s

avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude: reading input file "0b11111101"
avrdude: writing efuse (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0b11111101:
avrdude: load data efuse data from input file 0b11111101:
avrdude: input file 0b11111101 contains 1 bytes
avrdude: reading on-chip efuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of efuse verified
avrdude: reading input file "0b11011110"
avrdude: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.05s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0b11011110:
avrdude: load data hfuse data from input file 0b11011110:
avrdude: input file 0b11011110 contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.02s

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0b11110111"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.05s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0b11110111:
avrdude: load data lfuse data from input file 0b11110111:
avrdude: input file 0b11110111 contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.02s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified

avrdude done.  Thank you.

C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude -CC:\Users\<username>\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.8/avrdude.conf -v -patmega328p -cstk500v1 -PCOM3 -b19200 -Uflash:w:C:\Users\<username>\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.8/bootloaders/optiboot_flash/bootloaders/atmega328p/16000000L/optiboot_flash_atmega328p_UART0_115200_16000000L_B5.hex:i -Ulock:w:0x0f:m

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\<username>\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.8/avrdude.conf"

         Using Port                    : COM3
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.04s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "C:\Users\<username>\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.8/bootloaders/optiboot_flash/bootloaders/atmega328p/16000000L/optiboot_flash_atmega328p_UART0_115200_16000000L_B5.hex"
avrdude: writing flash (32768 bytes):

Writing | ################################################## | 100% -0.00s

avrdude: 32768 bytes of flash written
avrdude: verifying flash memory against C:\Users\<username>\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.8/bootloaders/optiboot_flash/bootloaders/atmega328p/16000000L/optiboot_flash_atmega328p_UART0_115200_16000000L_B5.hex:
avrdude: load data flash data from input file C:\Users\<username>\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.8/bootloaders/optiboot_flash/bootloaders/atmega328p/16000000L/optiboot_flash_atmega328p_UART0_115200_16000000L_B5.hex:
avrdude: input file C:\Users\<username>\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.8/bootloaders/optiboot_flash/bootloaders/atmega328p/16000000L/optiboot_flash_atmega328p_UART0_115200_16000000L_B5.hex contains 32768 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% -0.00s

avrdude: verifying ...
avrdude: 32768 bytes of flash verified
avrdude: reading input file "0x0f"
avrdude: writing lock (1 bytes):

Writing | ################################################## | 100% 0.05s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x0f:
avrdude: load data lock data from input file 0x0f:
avrdude: input file 0x0f contains 1 bytes
avrdude: reading on-chip lock data:

Reading | ################################################## | 100% 0.02s

avrdude: verifying ...
avrdude: 1 bytes of lock verified

avrdude done.  Thank you.

So I then reconfigured the breadboard. I do not have an Uno with a removable ATmega, so I am using an FTDI break-out board instead, wiring like so

Selected the same "ATmega328" from the MiniCore library (actually, I tried nearly every board on the list in desperation), and still get the "programmer is not responding" error until the IDE gives up.
Sketch uses 1030 bytes (3%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude -CC:\Users\<username>\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.8/avrdude.conf -v -patmega328p -carduino -PCOM7 -b115200 -D -Uflash:w:C:\Users\<username>\AppData\Local\Temp\arduino_build_929593/Blink.ino.hex:i

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\<username>\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.8/avrdude.conf"

         Using Port                    : COM7
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x30
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x30
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x30
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x30
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x30
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x30
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x30
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x30
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x30
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x30

avrdude done.  Thank you.

Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

I've uninstalled and reinstalled the USB/FTDI drivers, I've tried two different FTDI boards, I've even tried the "Minimal Circuit" described in the guide (removing the oscillator, capacitors, and the pull-up resistor, and installed/selected the "ATmega328 on a breadboard" board), nothing seems to work. It also seemed odd that TX pin on the Arduino/FTDI was going the the TX pin on the ATmega, so I even tried switching TX and RX. Same error.
Also scrapped everything and tried following this video (and subsequent webpage guide), which makes it look so simple, with a 100nF capacitor in place of the pull-up resistor on the Mega's reset pin. Same error.
I'm truly at wit's end. Does anyone have any additional pointers that are current?
T(LOADS!)IA
EDIT: include photo of breadboard as requested.

EDIT #2: deleted resistor, added 100nF cap on DTR pin.

EDIT #3: updated wiring including cap and resistor on DTR

UPDATE: I solved the issue with lots of help from timemage.
I had pulled the ATmega from another project that had already set the chip to use the 8MHz internal clock. So I had to rewire the board as the first schematic, with the 16MHz external crystal still installed, then re-burn the bootloader making sure to select "Internal 8MHz" from the Clock options of the
MiniCore board. Once the bootloader was re-flashed, I could then re-wire the board according to the second schematic only with the 16MHz crystal and the 20nF caps removed, and the FTDI board was then able to upload sketches.
BIG shout out to timemage, who sat in chat with me for over an hour trying to figure it out.
UPDATE #2: the FTDI board I was using - the DFRobot USB2Serial Light (DFR0164) - actually has the pins mislabelled (or, rather, not labelled as expected). The TX pin actually does get wired to the TX pin of the ATMega, and the RX pin goes to the RX pin of the ATmega.

Added photo of breadboard, in the TX -> RX / RX -> TX configuration.

Really what should probably happen if you want to salvage this as a question-and-answer is that you should post your own answer to your question.  Keep your question as your initial state.  Put everything you did to get to working order in your answer.  And I'd get rid of my answer since it's only going to be a confusing mess if I leave it.

And if that can't be done, we can just close question.  Because, if no one can follow what happened then it's not really much benefit to anyone else anyway.


text:
SIM7000E 0 voltage at SIM_VDD
I have problem with my SIM7000E. My PCB scheme and design is aveliable here https://easyeda.com/jaka87/new-vetercek While sending AT commands I get error as if sim card is not connected.
I also put oscilloscope on SIM_VDD and did some measurement. To my surprise i always measure 0V even or reset and when changing from AT+CFUN=0 to AT+CFUN=1.
It should at least send some bursts right ?
Any idea why this is happening?
Scheme:

Please edit your question and include your schematic as an image and your code formatted at "code" in this question.

After weeks i finally found the source of the issue. It turns out i mixed two labels on the PCB and therefore had wrong capacitors on VCC and data...


text:
Arduino stuck in PT_WAIT_UNTIL
I am using the Protothread Library from Adam Dunkels.
It is supposed to wait 1 second and then continue. But instead it gets stuck there and everything after that line is not executed.
lastTimeBlink = millis();
PT_WAIT_UNTIL(pt, millis() - lastTimeBlink > 1000);

Why does it get stuck there?
The entire code is uploaded here: https://pastebin.com/jRsuvn54
(The comments are on german)

It's not really all that helpful to include just a short snippet of code for an issue like this.

I've added the entire code

The Protothread library examples seems to use a timer for this.

By best attempt to provide something of an answer.
You have said:

PT_WAIT_UNTIL(pt, millis() - lastTimeBlink > 1000);

That is not literally represented in your code, so I take your question to refer
to:
int dist2 = dist1.toInt();
...
PT_WAIT_UNTIL(pt, millis() - lastTimeBlink > (dist2 * 1710));

or a similar section.
When you execute this PT_WAIT_UNTIL, dist2 contains whatever value you initialized it with in int dist2 = dist1.toInt();   Assuming the condition isn't met, you are exiting runCommand() by way of PT_WAIT_UNTIL's return PT_WAITING;
#define PT_WAIT_UNTIL(pt, condition) \
  do {                               \
    LC_SET((pt)->lc);                \
    if(!(condition)) {               \
      return PT_WAITING;             \
    }                                \
  } while(0)

The LC_SET here in PT_WAIT_UNTIL is being used to generate a label that can be jumped-to later:
#define LC_SET(s)                                \
   do {                                          \
     LC_CONCAT(LC_LABEL, __LINE__):              \
     (s) = &&LC_CONCAT(LC_LABEL, __LINE__);      \
   } while(0)

Later when you later call runCommand to resume the thread, you execute LC_RESUME by way of PT_BEGIN(pt);
#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
...
#define LC_RESUME(s)        \
  do {                      \
    if(s != NULL) {         \
      goto *s;              \
    }                       \
  } while(0)

goto *s here is ultimately jumping to the label created by your use of PT_WAIT_UNTIL.
You are now back in PT_WAIT_UNTIL checking the condition with the line if(!(condition)).  That is, you are checking millis() - lastTimeBlink > (dist2 * 1710)  However, what you are probably (more on that below) doing here is reading junk off the stack.  dist2 was initialized on a previous execution of runCommand and its effective lifetime ended when you returned in PT_WAIT_UNTIL on that prior execution.  On this new execution dist2 is uninitialized because you have jumped over its initialization.  If you turn the warning level up in File/Preferences you should see something for this.
A number of things can happen at this point, most of them not good.  I can't say what the compiler's optimizer will do to this code for certain, but not much would surprised me.  It seems likely, just on familiarity with optimizing compilers and what your code looks like, that it is generating code to read dist2.  That may  sound like a given, but it isn't when you're doing something undefined.  It's possible dist2 has the value from a previous run where you're executing this function in a loop.  But it could also have value that makes dist2 * 1710 evaluate to a duration of up to nearly 50 days, causes PT_WAIT_UNTIL to return from runCommand for so long as you're testing.
Generally, if you're going to use these proto-threads you're going to have to be very careful in thinking about what's actually initialized and what just looks like it is.  If you have a PT_whatever between a non-static local variable initialization or assignment and code where it's used, that's something to examine.

The reason I've put 1000 instead of (dist21710) in the question is simply because it doesn't work either way. The calculation of (dist21710) works perfectly fine. There is no problem with that.

But I think I understood what the reason is. Basically the function is only being run once. It isn't run when the condition is met. If the function would be in a loop, then everything would work, as the program is able to jump to the label and check again, if the condition is met. Then it could also continue.
The thread isn't really paused, it's stopped, and there is a label where to jump back to, when run again. As the function is not run again, you can't jump back to the label.

Thank you anyways, as your answer helped me to understand it.

I appreciate that it helped, but if you find the problem is actually something different you could write your own answer to your problem and mark that as accepted.  I think in two days you can do mark your own answers as accepted.  You can vote this up for being useful without declaring it the answer.


text:
ttyACM0 no such file or directory On Ubunutu 14.04
I have an Arduino Uno which communicated with the computer (Ubunutu 14.04) fine till 6 days ago (I assume some software update is to blame).
Now when trying to upload I get
processing.app.SerialNotFoundException: Serial port '/dev/ttyACM0' not found. Did you select the right one from the Tools > Serial Port menu?   at processing.app.Serial.(Serial.java:191)    at processing.app.Serial.(Serial.java:77)     at processing.app.debug.Uploader.flushSerialBuffer(Uploader.java:77)    at processing.app.debug.AvrdudeUploader.uploadViaBootloader(AvrdudeUploader.java:175)   at processing.app.debug.AvrdudeUploader.uploadUsingPreferences(AvrdudeUploader.java:67)     at processing.app.Sketch.upload(Sketch.java:1671)   at processing.app.Sketch.exportApplet(Sketch.java:1627)     at processing.app.Sketch.exportApplet(Sketch.java:1599)     at processing.app.Editor$DefaultExportHandler.run(Editor.java:2380)     at java.lang.Thread.run(Thread.java:745)
When I sudo ls /dev/ttyA*
I get
ls: cannot access /dev/ttyA*: No such file or directory

So it does not look like a permission issue.
when I lsusb
I get
Bus 001 Device 002: ID 8087:8000 Intel Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 002 Device 003: ID 04f2:b39a Chicony Electronics Co., Ltd
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

So it does not even see the device (which is connected and pulling current).
when I dmesg before and after connecting the Arduino, I don't see anything new.
I tried switching USB cables, and switching USB ports on the machine (both ports work with a mouse), but in vain.
What went wrong and how do I fix it ?
Thanks,
David.

Can you try the Arduino on someone else's computer?

@Majenko I tried on my wife's Mac and it didn't work, but I only installed the software on that machine for the purpose of the troubleshooting, so I still have hope that I did something wrong on it; I say "hope" because currently the leading options I see are: 1) something bad happened to the USB controller, 2) two faulty cables (that one is hard to believe)

Does the power light illuminate?  Does the LED on pin 13 blink a couple of times when you first connect it?

@Majenko even better - there was a program on it (which my kid wrote at the beginning of the week); when we plug the arduino it still runs ...

The next step would be to try to access the USB comm chip out of band. You wouldn't happen to have a AVR ISP programmer or a second, working Arduino, would you?

@IgnacioVazquez-Abrams I'll get my hands on a second arduino on Sunday. What should I do then ?

Follow the ArduinoISP tutorial and hook it up to the 6-pin connector near the small chip (Atmega16U2) closest to the USB connector, then use avrdude to try and communicate with the chip.

Ok, it sounds like there is an issue with the ATMega(8/16)U2 chip or its surroundings.  It might just need its firmware refreshing (which can be done with another Arduino as a programmer) or it might be plain dead.
Another possibility is the USB socket itself.  I have two UNOs, one which is perfectly fine, and one where I need to hold the cable at just the right angle for it to connect properly.  You can try using a fine needle to try and raise the four metal strips in the USB connector a fraction to make better contact.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Read analog port set as output
I have a PWM analog port that is outputting a frequency, is it possible to do an analogRead on the same pin and get a correct value? If so, will reading that port disrupt the freq output on the pin? This is being done on a Teensy 3.2 device. My goal is to output the freq visually on an OLED. Tnx.

Just store the PWM value in a variable every time you call analogWrite. Your oled-display routine can then just read that variable.

You want the voltage that would be read by a voltmeter? If you know what value you set for PWM, you know the voltage that is generated.
But if you are curious,  you can connect the PWM output to ADC pin and read for example a 100 values and calculate the average. You will see that at the same resulution of PWM and ADC, you get as average of ADC values the same value as you set for PWM.
This is for M0:
void setup()
{
  Serial.begin(115200);
  while (!Serial);

  analogWriteResolution(10);

  for (int i = 0; i < 1024; i += 10) {
    analogWrite(7, i);
    delay(100);
    long sum = 0;
    int n = 0;
    unsigned long start_time = millis();
    while (millis() - start_time < 100) {
      sum += analogRead(A1);
      n++;
    }
    Serial.print(i);
    Serial.print(' ');
    Serial.println(sum / n);
  }
}

void loop()
{
}

No, it's not possible.
PWM is not actually analog - it's digital, but switching on and off at a high speed.
If the pin were capable of reading an analog value at the same time as outputting a PWM waveform (which I highly doubt...) all you would get is alternating 0 and 1023 values (or whatever range the Teensy reads in).

You can create a parallel branch from PWM pin with a diode. And put a 0.1uF capacitor and parallel 1k resistor after the diode and connect analog pin between diode and resistor to read pwm avarage output voltage. But becareful it will give 0,6V below.


text:
Using MQTT to send time stamp - to Arduino
In previous question in this forum - I asked about updating clock on an ESP8266, using MQTT broker to send a time stamp on demand, in following manner:
1) ESP8266 sends a publish containing the payload :"sync",
2) broker answers in string format ( this part is python )
def on_message(self, client, obj, msg):
    self.arrived_msg = msg.payload.decode()
    if self.arrived_msg == "sync":
        a = datetime.datetime.now()
        b = "%d,%d,%d,%d,%d,%d,%d" % (a.year, a.month, a.day, a.hour, a.minute, a.second, a.microsecond) .  <------ here a string time format is created
        self.client.publish(topic=self.topics[0], payload=b, qos=self.topic_qos)

3) on a terminal (MAC OS), subscribed to relevant topic- cant see publish results. which are OK:
sync                           <----- ESP sends request
2018,9,18,12,44,18,903242      <----- string answer from broker

4) BUT when Arduino code get this time stamp:
void callback(char* topic, byte* payload, unsigned int length) {
        char incoming_msg[50];
        // ledBlink(30, 5);
        Serial.print("Message arrived [");
        Serial.print(topic);
        Serial.print("] ");
        for (int i = 0; i < length; i++) {
                Serial.print((char)payload[i]);  <----- print #1
                incoming_msg[i] = (char)payload[i];  <----- generate incoming msg
        }
        Serial.println("");

        if (strcmp(topic,clockTopic)==0) {       <------- detect relvant topic for clock sync
                Serial.print(incoming_msg);  <------ Print #2
        }

5) I get this result on serial monitor :
Message arrived [HomePi/Dvir/Clock] 2018,9,18,13,48,5,230009 <---- here time stamp is OK , Print #1
2018,9,18,13,48,5,230009$��?O: @ . <----- Print #2

EDIT1:
6) I tried adding a null termination in time stamp, but it just added \0 to time stamp
Appreciate any help
Guy

You forgot to set the terminating zero of the c-ctring incoming_msg.
add incoming_msg[length] = 0;

please see my comment in Majenko's answer

incoming_msg[length] = 0;

got it the first time :)

OK- it works. Can you please explain why last char does not regarded as a plain 0 ? and regarded as \0 ?

the 0 is valid only in memory as a terminator for the c-string. it is not valid for transport over a network. you get the payload bytes and the length. you convert the payload to a string of length length so you must set the terminating zero at the right position of the char array

In C a string is "null terminated".  That means that the very last character of every string must be character 0 (or NULL).
You need to ensure that you add that NULL character to the end of your incoming_msg string to terminate it, or force the entire string to be cleared to NULLs before you populate it.
The simplest way is to zero the string:
bzero(incoming_string, 50);

Or you can force a 0 to be appended after each byte is added:
incoming_msg[i] = (char)payload[i];
incoming_msg[i+1] = 0;

Or just add one at the end:
incoming_msg[length] = 0;

There's many ways of doing it - as long as you get that NULL in there somehow.

thank you for your answer, as a matter of fct I tried to send time stamp with null termination ( but with no luck ), I did like : ('%d,%d,%d,%d,%d,%d,%d,%s) which last parameter was '\0'. perhaps I didn;t do it right ? or this is impossible ?

It's not the sending. It's the copying into your internal array. You discard the null.

OK, what is the pupose of adding 0 every loop ( as you wrote ) ?

It's just one of the many ways of ensuring that there is a null after the last character.


text:
Can't create a RTC_DATA_ATTR var inside a class
I'm trying to create a deepSleep class for my ESP32 project, but I get this error : section attribute not allowed for 'clock_beforeSleep' The only place it compiles, is outside the class.
How should I declare it ?
EDIT1: Add Code
#include "EEPROM.h"
#include "time.h"
#include "WiFi.h"

RTC_DATA_ATTR long clock_expectedWake = 0;
RTC_DATA_ATTR int bootCounter = 0;
RTC_DATA_ATTR int driftRTC = 0;
RTC_DATA_ATTR long clock_beforeSleep = 0;

class esp32Sleep
{
#define EEPROM_SIZE 16
#define DEV_NAME "ESP32lite"
#define uS_TO_S_FACTOR 1000000ULL /* Conversion micro seconds to seconds */

private:
  char sleepstr[250];
  // RTC_DATA_ATTR long clock_expectedWake = 0;
.
.
.

a class member is only a declaration. it has a space in memory only if an object of that class is created. you could try static keyword. static members are common for all instances of that class

@Juraj but it is a TRV_DATA_ATTR which stores its value and retrieves after awakening.

I know and that is the reason why it can't be a class member. the linker puts it at address in RTC memory

@Juraj - see edit 1. can you please explain about "linker"

linker follows a linker script, which specifies what goes where in memory https://github.com/espressif/arduino-esp32/blob/1977370e6fc069e93ffd8818798fbfda27ae7d99/tools/sdk/ld/esp32.project.ld#L48

You can't put an RTC_DATA_ATTR qualified variable inside a class because the class is stored in normal RAM. The RTC_DATA_ATTR qualified variable is, by definition, stored in RTC RAM.
The definition of RTC_DATA_ATTR includes a section attribute (__attribute__((section(".rtc.data")))) that tells the compiler where abouts in memory the variable should be stored (in this case the 8kiB of "slow" RTC memory). That is mutually exclusive with where the compiler decides to store the class.
It's like you have a diamond necklace which the has to be kept in a safe at all times, but you want to wear it around your neck whilst at the same time storing it in the safe. You can't do it.

I think some explanation about the different allocation schemes could be
useful:

Global variables, as well as static locals and static class members,
are allocated at build time, by the linker, typically in the .data or
.bss section of the program.
Local variables are allocated at run time in the stack. Typically the
compiler issues some instructions to adjust the stack pointer in order
to make room for the variable. As an optimization, the most used
locals can be stored directly in CPU registers, but this optimization
is disabled if you use the address of the variable.
Variables created with new and malloc() are allocated at run time
in the heap. This allocation is handled by a support library.

Note that objects are variables and are allocated in one piece, just
like a C struct. Static class members are not part of the class
instances.
Now, some build chains have extensions that allow you to store
statically allocated variables elsewhere than the RAM. One example is
the PROGMEM storage on AVR. RTC_DATA_ATTR sounds like a similar
extension. You may be able to store a regular class member this way if:

The object is global and stored as RTC_DATA_ATTR as a whole.
It doesn't need a constructor.

Is there a workaround the make such class?


text:
WifiManager and WiFi functionally
I’m considering using wifiManager mostly to have the ability not to hard code WiFi creditntials.
But In my current code I use WiFi’s functions as WiFi.setAutoReconnect(true) and WiFi.status() != WL_CONNECTED
How can it be done using WifiManager?

You don't. WifiManager does all that for you. You don't need anything like that in your code. Just follow the examples and read the documentation.
But if you do want to then you just need to remember that WifiManager is merely a library that configures the WiFi for you. If you want to query or alter the WiFi settings you can - exactly as you are right now. The two aren't mutually exclusive.

I didn’t find any example to check if connected

You don't "check if connected". It connects, or it gives you an AP with a portal. In the latter case it blocks waiting for you to configure it. There is no "check". If your code runs then it's connected. All the examples show that.

I understand what you say, but from time to time there are disconnections, and I do not want that it will automatically go to AP mode. how many retires before entering AP mode/ time to try to reconnect ?

WifiManager is just a library that use the WiFi object. It's not a replacement. If you want to also interact with WiFi there's nothing to stop you. You can set auto reconnect. You can query the status. Just as you are.

OK. Should I define an instance of Wifi as well ?

No, there already is one.

Here's a working example that's on my Wemos D1 Mini. It stands up an AP until you provide credentials for your local LAN, then displays it's DHCP IP address on a 16x2 LCD and stands up a webserver. Once the credentials are stored it won't stand up the AP, it will just reconnect and do the main loop() of the sketch. To force the AP to restart you need to call the ESP.reset(); method to flush the stored credentials and reboot the Wemos.
#include <LiquidCrystal_PCF8574.h>
#include <ESP8266WiFi.h>

#include <WiFiManager.h>
#include <ESP8266WebServer.h>
#include <Wire.h>

WiFiClient wemosCL;

ESP8266WebServer server(80);

const int led = LED_BUILTIN;

LiquidCrystal_PCF8574 lcd(0x38);

void handleRoot() {
  digitalWrite(led, 1);
  server.send(200, "text/html", "<title>ESP8266 Demo</title>
Hello from ESP8266!

IP Addr: " +
          WiFi.localIP().toString() + "
");

  digitalWrite(led, 0);
}

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

void setup(void) {
  Serial.begin(115200);
  WiFiManager wifiManager;
  wifiManager.autoConnect("Wemos", "configuration");
  pinMode(led, OUTPUT);
  digitalWrite(led, 0);

  lcd.begin(16, 2);
  lcd.setBacklight(255);
  lcd.print("I'm alive");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    lcd.setCursor(0, 0);
    lcd.print(".");
  }

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Status:Connected");
  lcd.setCursor(0, 1);
  lcd.print("IP:");
  lcd.print(WiFi.localIP());

  server.on("/", handleRoot);

  server.onNotFound(handleNotFound);

  server.begin();
}

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

Hi Dougi, something I miss is, when line of code reaches wifimanager in setup it only look for stored crediatials ? from what I understood in Mejenko's asnwer, once it passed that line, wifi is connected, so I don't understand why the section called \\wait for connection is relevant. I'm guessing that something I don't understand here :)

The wait for connection is after the credentials for my home WiFi are entered as it switches from AP to STA mode then my router does the DHCP handshake. That takes some time to run.

OK. and at next boot... when credentials were entered boot before, and just being used at current boot ... still when reaching \\ wait for connection- in that excat moment, is Wifi connected ?


text:
SIM800L stays in 1sec-blink-state
I've bought such on Amazon. My main problem is that it stays in 1sec-blink, meaning it can't registrer cellular network.
First I tried with all anntennas possiblities (one of each, both, none) - failed.
Using NodeMCU (for 3.3 TxRx) and SoftwareSerial.h to communicate. It answers all AT command as expected.
I tried several powering possibilities (as noted extensively about 2A on the internet), including 18650 , 2000mAh battery connected only to SIM800L module with no MCU connected, still same state.
What Can be done else?
SEE PELEPHONE:

is the SIM card valid?

@jsotola AT command replies with sim’s serial number, I guess it is ok

Are you connecting to a suitable network? Not all networks will work with SIM800L. GSM/GPRS is obsolete now and being gradually switched off by operators around the globe.

@Majenko See network properties (PelePhone)

You're with PelePhone? Well, 2G says "N/A". So no, simply no.

@Majenko Meaning that only 2G capable networks can apply?

Correct. https://en.wikipedia.org/wiki/2G -- For PelePhone you need an LTE or better modem.

@Majenko Thank you very much! Based on that table, can you point which carrier can I use using SIM800L (since neither are not 800, if it refered to freq).
THNX

The 800 in SIM800L does not refer to the frequency. The SIM800L works on 850/900/1800/1900MHz. So pretty much any 2G network.

Your mobile network provider does not provide a 2G (GPRS / GSM) network.
2G is graduallly being phased out around the globe, so switching to an LTE modem is really the way forward.
If you still want to use the SIM800L then you need a network provider that gives 2G services. Fortunately the SIM800L is a "quad band" modem, so it will work with pretty much any 2G provider (it works on 850/900/1800/1900MHz, hence the "quad" of "quad band").


text:
Pro Mini - Using RAW pin for 3.3v input
I design a PCB that one of its components is a 3.3v Pro Mini. Since I want it versatile regarding powering the PCB (3.3v or 5.0v) I want to know if it is a good practice to supply 3.3v to Pro Mini's RAW pin( rather than to the VCC Pin ).

It is not ideal, no.  The RAW pin first goes into a 3.3V voltage regulator whose dropout voltage is up to 200mV (worst case).  That means that you would get around 3.1V out, and it wouldn't be properly regulated.
Oh, it would work, but the power won't be stable, which means that any analogue readings that you make that don't directly use the (shakily) regulated "3.3V" (now 3.something else V) in the generation of the analog signal (such as a simple potentiometer) will be inaccurate.
Also output logic voltages will be lower than expected which may have an effect if communicating with something whose upper input threshold is at or near the 3.3V mark (such as many 5V devices).

Thank you Majenko, those are the exact reasons I wanted to be sure of. Guy


text:
pointing to array of chars
I'm trying to pass a list of files (located in sketch) to be read using a library I write. List can have different filenames and vary in number of files.
How to pass a this array to my library?
for example:
char *parameterFiles[3] = {"/myIOT_param.json", "/myIOT2_topics.json", "/sketch_param.json"};
EDIT_1
To explain more clearly what are my needs:
Let's say that my library has a class name myIOT2. That class holds an array that contains a list of all filenames (what shown here is not all class). Those names are different from one use of the library to the other, and it might not have all 4 files ( can be also 0 files stored ).
I wish to have the flexibilty not to hard code exact filename in advance, but to pass that array as part of my sketch, as show prior to EDIT_1.
class myIOT2
{
public:
const char *parameter_filenames[4] = {nullptr, nullptr, nullptr, nullptr};

};

You mean a library of your own that you are currently writing?

@EdgarBonet - Sorry, Yes

@EdgarBonet please see my comment for  you answer

I saw the comment. It doesn't seem like something for which you would expect a response.

@EdgarBonet please explain - adding those variables is critical for the answer. Hope it was explained why.

Explain what? If you need to add some variables, I see no problem with that. If you have a question, please formulate it as clearly as you can, by editing the question here. Imagine you are talking to someone quite dumb (I am not very good at extrapolating a valid question from very partial information).

@EdgarBonet please see EDIT_1

You have to pass both a pointer to the list, and the length of the list
as an extra argument. The signature of the function may be something
like:
void processFiles(const char *fileList[], int fileCount);

Note that const char *fileList[] is just a fancy way of writing
const char **fileList. I find the former more readable, but that is
completely subjective.
Here is a small test code showing this in action:
void processFiles(const char *fileList[], int fileCount)
{
    for (int i = 0; i < fileCount; ++i) {
        Serial.print("Processing file ");
        Serial.println(fileList[i]);
    }
}

const char *parameterFiles[3] = {
    "/myIOT_param.json",
    "/myIOT2_topics.json",
    "/sketch_param.json"
};

void setup() {
    Serial.begin(9600);
    processFiles(parameterFiles, 3);
}

void loop() {}

Alternatively, you may put a “sentinel” at the end of the list: a null
pointer that signifies that the list ends there:
void processFiles(const char *fileList[])
{
    for (const char **p = fileList; *p; ++p) {
        Serial.print("Processing file ");
        Serial.println(*p);
    }
}

const char *parameterFiles[] = {
    "/myIOT_param.json",
    "/myIOT2_topics.json",
    "/sketch_param.json",
    nullptr
};

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

void loop() {}

Edit: Answering to EDIT_1.

[My library's] class holds an array that contains a list of all
filenames

First of all, you have to decide who is responsible for storing those
file names: the library or its client. When you write:
const char *parameterFiles[3] = {
    "/myIOT_param.json", "/myIOT2_topics.json", "/sketch_param.json"
};

you are creating 4 arrays: an array of 3 pointers named
parameterFiles, and three arrays of characters holding the file names.
Note that those 3 arrays are anonymous: they are not array
variables. If the client code tries to pass this parameterFiles to
your library, the array identifier will decay to a pointer, and your
library will receive that pointer. What should it do with it?

The library could just keep a copy of the pointer. The client is then
responsible for ensuring that it remains valid for as long as the
library may need it. This practically implies that parameterFiles
should be a global variable, and should not be modified once given to
the library.

The library could make a copy of the array. Then the client is freed
from this responsibility. However, it is still responsible for
ensuring that the pointers that were copied from the array remain
valid, i.e. that the file names stay in the same place in memory.

The library could copy the file names themselves. Then the client
doesn't have any responsibility about keeping pointers valid.

If you choose option 2 or 3, the library will have to hold one or more
arrays. You will then have to choose whether you allocate them
statically, or dynamically with new. Dynamic allocation is more
efficient when the arrays can vary greatly in length, but it can raise
issues of memory fragmentation in RAM-constrained devices.
I cannot tell you which option is best: it depends on your use case. In
any case, whatever you choose, you should document it: the user of the
library should know whether they are responsible for keeping any
pointers valid.
In the following, I will assume option 2 with static allocation. This is
consistent with the code snippets in your question. Also, if the client
provides the file names as string literals, then pointers to these
strings remain always valid.
Here is a toy implementation of the myIOT2 class, where the list of
file names is copied by the constructor into the class:
class myIOT2 : public Printable
{
public:
    static const int maxFileCount = 4;

    myIOT2(const char *fileList[], int count) {
        if (count > maxFileCount)
            count = maxFileCount;  // discard extra files
        fileCount = count;
        for (int i = 0; i < fileCount; i++)
            filenames[i] = fileList[i];
    }

    size_t printTo(Print& p) const {
        size_t count = p.print(F("myIOT2["));
        for (int i = 0; i < fileCount; i++) {
            count += p.print('"');
            count += p.print(filenames[i]);
            count += p.print('"');
            if (i < fileCount - 1)
                count += p.print(", ");
        }
        count += p.print(']');
        return count;
    }

private:
    const char *filenames[maxFileCount];
    int fileCount;
};

Note that, the array of file names being statically allocated, there is
a hard maximum on the number of files that can be stored. I made the
class Printable only for debugging convenience.
And here is an example of this class in use:
const int fileCount = 3;

const char *parameterFiles[fileCount] = {
    "/myIOT_param.json", "/myIOT2_topics.json", "/sketch_param.json"
};

myIOT2 iot(parameterFiles, fileCount);

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

void loop() {}

This test sketch prints:
myIOT2["/myIOT_param.json", "/myIOT2_topics.json", "/sketch_param.json"]

great idea with "sentinel". Never encountered use of such for loop

To complete my original question - lib will contain fileList and fileCount to have a pointer for later uses, and Edgar's function can be:
`void processFiles(const char *_fileList[], int _fileCount)
{
fileCount=_fileCount;
for (int i = 0; i < fileCount; ++i) {
Serial.print("Processing file ");
fileList[i]=_fileList[i];
Serial.println(fileList[i]);
}
}`


text:
ArduinoJSON - How to check if array is empty
Parameters file defines the creation of entities and stored in flash. Its structure is given, and all fields ( keys & values ) are given.
In current phase - those parameters are hard-coded in a const char* cont_params, as shown below.
My goal, is when array is empty, for example RF_2entity - means that current MCU does not uses its RF abilities, and will not init any RF entities. The way RF_2entity is defined below, as empty array, [] , ArduinoJSON's isNull() function return 0 in that case.
How can I keep parameters file's structure and logic, rather that fill its values with 255 for example.
  Serial.begin(115200);
  StaticJsonDocument<1200> doc;
  const char *cont_params = "{\"entityType\": [1,1,1,1],\
                    \"SWname\": [\"SW_0\",\"SW_1\",\"SW_2\",\"SW_3\"],\
                    \"SW_buttonTypes\": [2,1,1,1],\
                    \"SW_timeout\": [10,11,12,13],\
                    \"SWvirtCMD\":[0,0,0,0],\
                    \"Winname\": [],\
                    \"WextInputs\": [],\
                    \"WinvirtCMD\":[],\
                    \"RF_2entity\": [],\
                    \"v_file\": 0.5}";
  DeserializationError err = deserializeJson(doc, cont_params);
  JsonArray array = doc["Winname"].as<JsonArray>();
  serializeJsonPretty(array,Serial);
  Serial.println(array.isNull());

output:
[]0

sorry, but I don't understand the question. what is the problem? isNull() returned 0 (false), not 1 (true)

@Juraj - Question edited. you are right.... isNull() returns that array is not empty.

The method isNull() is not what you want. It tells you whether the instance holds an array at all or not. And of course, your specific instance holds an array, though an empty one. Therefore, the method correctly returns false, aka 0.
As the API documentation shows, there are more methods to use.
What you want is size(), which returns the number of elements in the array. It will even return 0 on an instance without an array.

in that case, doc["Winname"].size() will suffice. I don't really need to use an array.


text:
How to fix "expected ; before ) token" error?
I am in the early stages of writing my program, but I have run into a problem. I am fairly new to Arduino so I'm not sure if there is something I am trying to do that doesn't work, but I am getting an error message

expected ; before ) token

on the line for(count <= 10).
I would really appreciate if someone could let me know why I am getting this error.
#include<EEPROM.h>
const int LED = 12;
const int SWITCH = 4;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  pinMode(LED, OUTPUT);           //LED is always outputting information
  pinMode(LED_BUILTIN, OUTPUT);   //Built in LED is always outputting information
  pinMode(SWITCH, INPUT_PULLUP);  //Switch inputs value when in/out of ground
}

void loop() {
  // put your main code here, to run repeatedly:
  int addr = 0;     //Declaring variables
  int count = 0;
  int seconds;

  if (digitalRead(SWITCH) == LOW) {
Serial.println("----Recording----");

    for (count <= 10) {
      while (digitalRead(SWITCH) == LOW) {
        count = count + 1;
        digitalWrite(LED, LOW);
        delay(50);
      }
      else {
        count = count + 1;
        digitalWrite(LED, HIGH);
        delay(50);
      }
    } else {
      digitalWrite(LED_BUILTIN, HIGH);        //Internal LED blinks
      delay (300);
      digitalWrite(LED_BUILTIN, LOW);
      delay(300);
    }
  }
}

try while (count <= 10) { or for ( ; count<=0; ) { - find some C tutorial to learn about correct syntax

The problem is with the syntax of your for loop.

I switched to a while loop but then I just get an error at the else statement...any other help you could provide?

for and while blocks do not have an else. Only if blocks do. Look at some basic C examples.

@Thomas, you really have to refer to the arduino language refference pages before you  post a question ..... https://www.arduino.cc/reference/en/language/structure/control-structure/for/

Welcome to arduino.stackexchange.
Compiler informs you about the problems with your code. In your case there is a problem with for loop.
Remember, the for loop is one of basic concepts in c/c++ (and many others) programming language.
Syntax is:
for ( init-expression ; cond-expression ; loop-expression )
    statement;

Description of above:
init-expression:
Before any other element of the for statement, init-expression is executed only once. Control then passes to cond-expression.
cond-expression:
Before execution of each iteration of statement, including the first iteration. statement is executed only if cond-expression evaluates to true (nonzero).
loop-expression:
At the end of each iteration of statement. After loop-expression is executed, cond-expression is evaluated.
For example:
for(int count=0; count<10; count++){
    if (count%2) {
        digitalWrite(LED, LOW);
        }
    else{
        digitalWrite(LED, HIGH);
        }
    }

Add some extra code when needed.
To see more description of for loop see here.

Also, only 'if' statements have 'else' clauses; loop statements do not. If you didn't get an error for the 'else' at first, it is because the compiler got lost in the for-loop with only one argument.
'while()' statements have a boolean expression inside the parentheses. Each time the boolean evaluates TRUE, the statement or block following the loop executes once, until the loop evaluates FALSE. Regardless of how many times it executes, even zero, the following code will be executed.
'for()' statements have three expressions. Any of the three may be absent but the places for all three must be shown.

The first expression is executed once at the beginning of the loop. It typically initializes a loop variable, but may do anything, or be absent.
The second expression is a boolean expression that works exactly like the only argument in a 'while()' loop (the loop is only executed if, and for as long as, the expression is TRUE).
The third expression is executed after all of the statements in the loop. It typically advances the loop variable, but may do anything.
Like the 'while()' loop, whatever follows the 'for()' loop will be executed regardless of whether the loop did anything.

Though any of the 'for()' loop's expressions may be left out, both semi-colons must still be present to make it clear which expressions were left out.
Note that 'for(;;)' is an idiom in C that means "forever" - i.e., an infinite loop. Some other construct needs to be executed within the loop to cause it to end, if it not meant to execute perpetually.


text:
Interrupt routine has unexpected execution
An interrupt routine is executing unexpectedly, and I can't figure out why. Can you please have a look?
Hardware is a generic (knock off) Arduino Mega, with an unused Ethernet shield, and a touch screen shield. It looks like so:

I am connecting a flow meter that looks like this:

It has an external pull up resistor, and is wired like so:

and I am using pin 18 as is suggested for the hardware here: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/.
The code is straight forward:
global variable definition:
const byte interruptPin = 18;
volatile unsigned long waterFlowSensorCount= 0;
inside setup():
pinMode(interruptPin, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), incrementWaterSensorCount, FALLING);
handler function:
void incrementWaterSensorCount()
 {
  waterFlowSensorCount = waterFlowSensorCount + 1; }
Everything works as it should... until I activate some specific outputs. The 0V and 5V that are powering the flow meter are also the same power source for the relays I am turning on. The moment the relays are turned on, the interrupt routine runs about 15 times. for the sake of full disclosure, the project has several power supplies and looks like so:

I tried all the arguments when defining the interrupt routine (RISING, FALLING, HIGH, LOW) and the behavior is the same, I mean, the flow meter is just sitting there and the count is incrementing (but it 'should' not). The voltage drop on the 5V power supply is negligible. The voltage on the interrupt pin (18) goes from 5.011 to 5.007 when the relays are running. I tried the internal pullups but it didn't help, and the voltage is OK. The code looks OK. None of the things I tried had any positive effect. Why is the interrupt pin calling the handler function as I turn on some relays when the voltage on the interrupt pin is seemingly stable? any advice? any troubleshooting ideas?
Update
I cycled the power to the power supplies and the arduino USB power maintained power to the system, and the voltage dips did not affect the interrupt. so it's not voltage.
I pulled the electro-mechanical relays, that were being turned on by the 6 relay shield, and when the 6 relays shield relays are cycled without the electro mechanical relays present the interrupt is not called. It's something to do with the electromechanical relays under the relay shield. Any ideas are welcome.
Update 2
For sure it's the electromechanical relays. When they are removed from the socket, the interrupt circuit works as intended. The odd thing is that the Arduino is not really related to the relays. The relays are switching 12V power. There is no relation to 5V inputs or outputs. Any thoughts? any stabs in the dark I can investigate are really appreciated.

An impressive installation there! That looks like a hall effect flow meter. Is it physically distant from the relays and other sources of magnetic interference? With a hall effect sensor, "bouncing" should not be a problem as it would with mechanical contacts. FALLING appears to br the correct  edge to trigger the ISR and the external 10k pullup appears OK. Nothing else is using pin18 via a shield or otherwise?

This looks like an electrical noise issue due to relay chatter. Have a look here for what electrical noise looks like: https://www.youtube.com/watch?v=Nj-Q8FQxHhU I suspect the relay does something to the 12V power supplies, that then do something to the 3.3v and 5V power supplies that cause the issue. Electrical noise and relays... seems like the culprit.

@6v6gt thanks. 100% the issue is relay related, and I don't think it's the magnetism from the relay affecting the hall sensor. It looks like the operation of the relays are causing noise in the system, which is being caught by the interrupt circuit. I think this is a question for electrical stack exchange

OK. If you are also using naked relays (as opposed to modules which would anyway have them) ensure there is a flyback diode across each coil. Also look at snubber circuits on the output side of the relays especially if they are switching main voltage into an inductive load.

@6v6gt if you could please provide your comment as an expanded answer I will gladly try it, and likely accept, as it looks right. Is flyback diode something I buy? what is a snubber circuit? The 12V the relays are switching is powering a motorized ball valve. My electronics is pretty weak...

I won't do it as a formal answer because this is straying outside the bounds of an "Arduino" issue (and I risk losing some Brownie points if it is marked down). It may be that what you have described as electromechanical relays does not have a flyback diode across the coil. This can be a normal 1n4007 diode. See https://en.m.wikipedia.org/wiki/Flyback_diode . Here is an example of a snubber https://www.ebay.co.uk/itm/193580835405 . Otherwise Google for relay snubber.

@6v6gt The internet is great because there are people like you. I happened to have the 1n4007, I put it as a 'flyback' on all my relay coils, and voila! fixed! Everything works! Thank you so much!

Electrical noise strikes again! A really good explanation of electrical noise can be found here: https://www.youtube.com/watch?v=Nj-Q8FQxHhU
Once I narrowed the issue to the electromechanical relays, since they were not connected to any of the Arduino power (3.3v, and 5v) I realized that some sort of electrical interference is happening. Some sort of electrical phenomena was causing the interrupt pin to 'malfunction' aka not behave as expected. I followed the advice for a 'flyback' relay (https://en.m.wikipedia.org/wiki/Flyback_diode) where I simply put a 1n4007 diode across the relay coil, and BOOM! no more issue on the interrupt pin.
This may seem inappropriate for an Arduino page, but I would argue that this is indeed an Arduino issue as Arduino is both software AND hardware, and since this may help someone else with an Arduino, this belongs here.
A big thanks to @6v6gt. You rock!


text:
Arduino menu coding problem by Keypad and 128*64 graphic LCD
I am trying to modify on the menu code to be able to use a keypad shield and arduino for scrolling between lines. after uploading and trying the code the following has happened:
1- I can not scroll more than 2 lines.
2- If I press D, I can scroll to another 2 lines.
What is the problem in this code?
include "String.h"
include"AccelStepper.h"
include "Keypad.h"
include "U8glib.h"
U8GLIB_ST7920_128X64_1X u8g(12, 11, 10, 13);

//Keypad setup

const byte ROWS = 4;

const byte COLS = 4;

char hexaKeys [ROWS][COLS] = {

{'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} };

byte rowPins [ROWS] = {5, 4, 3, 2};

byte colPins [COLS] = {9, 8, 7, 6};

Keypad customKeypad = Keypad (makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

define KEY_NONE 0
define KEY_PREV 1
define KEY_NEXT 2
define KEY_SELECT 3
define KEY_BACK 4
uint8_t keycode1 = KEY_NONE;

uint8_t keycode2 = KEY_NONE;

uint8_t keycode = KEY_NONE;

void keymode(void){

keycode2 = keycode1;

char keypressed = customKeypad.getKey();

if (keypressed != NO_KEY){

switch (keypressed){

case 'A':

keycode1 = KEY_PREV;

Serial.println("A");

break;

case'B':

keycode1 = KEY_NEXT;

Serial.println("B");

break;

case 'C':

keycode1 = KEY_SELECT;

Serial.println("C");

break;

case 'D':

keycode1 = KEY_BACK;

Serial.println("D");

break;

}

if (keypressed != 'A' && keypressed != 'B' && keypressed !='C' && keypressed != 'D')

keycode1 = KEY_NONE;

}

if (keycode2 == keycode1)

keycode = keycode1;

else

keycode = KEY_NONE;

}

define MENU_ITEMS 4
const char *menu_strings[MENU_ITEMS] = {"Start", "Hello", "Let's Go", "End"};

uint8_t menu_current = 0;

uint8_t menu_redraw = 0;

uint8_t Last_key_code = KEY_NONE;

void drawmenu(void){

uint8_t i, h;

u8g_uint_t w, d;

u8g.setFont(u8g_font_6x13);

u8g.setFontRefHeightText();

u8g.setFontPosTop();

h = u8g.getFontAscent()-u8g.getFontDescent();

w = u8g.getWidth();

for( i = 0; i < MENU_ITEMS; i++ ) {

d = (w-u8g.getStrWidth(menu_strings[i]))/2;

u8g.setDefaultForegroundColor();

if ( i == menu_current ) {

u8g.drawBox(0, ih+1, w, h);

u8g.setDefaultBackgroundColor();

} u8g.drawStr(d, ih, menu_strings[i]);

} }

void updatemenu(void){

if (keycode != KEY_NONE && Last_key_code == keycode) {

return; } Last_key_code = keycode;

switch(keycode){

case KEY_NEXT:

menu_current ++;

if (menu_current >= MENU_ITEMS)

menu_current =0;

menu_redraw = 1;

break;

case KEY_PREV:

if (menu_current ==0)

menu_current = MENU_ITEMS;

menu_current --;

menu_redraw = 1;

break;

} }

void setup (){

Serial.begin(9600);

menu_redraw = 1;

}

void loop (){

keymode();

if (menu_redraw !=0) {

u8g.firstPage();

do{

drawmenu();

}while(u8g.nextPage());

menu_redraw = 0;

} updatemenu();

}

it is unclear how you want the code to work ... you need to provide clear description of expected behavior  ... your question is unanswerable until you do so

I just want to make a clear menu and to be able to scroll down without problems,
after that i will move to the next part.

https://github.com/neu-rah/ArduinoMenu will handle IO for you


text:
Variable declaration inside main loop
In the past I declared variables inside the main loop which worked just fine.
In a new project I did the same:
void loop(void)
{
    uint8_t counter;
    ....
    if (buttonPress)
        counter = 0;
    ...
    if (someCondition == true)
    {
        Serial.println(counter);
        counter++
    }
}

But then the output of the variable counter shows that for some reason the counter variable is reset to 0 instead of counting up. This happens even after the button is released.
The scope of the variable counter is the main loop and I just assumed that it will keep its value and count up.
What might be the reason for this variable to reset to 0?
Is it that other functions are called within the main loop?
Is it that an interrupt handler is called every now and then?
The solution I've found is to declare the variable as static:
static uint8_t counter;

Then it increments as expected.
Even though I've found a solution I'd really like to understand what the problem with my first approach was.

This question fits better in stack overflow, since it is not related to Arduino.

So the main loop in the Arduino just behaves as any regular function that is called?
For some reason I thought that variables declared in main() are automatically static and keep their value.

No they are not, afaik the loop() is just a function that has a while(true) or while(1) inside.

Thank you very much for the explanation and possible solutions.

Just to get this straight:
With the arduino the main loop() just is a regular C-function with all the implications regarding variable scope.
But in a C-program a variable declared in main() keeps its value.
So if I used plain C for my program instead of the Arduino framework the counter variable would work without being declared static.
Of course then the if-statements would be located in a while(1) loop.

Yes you are right (if I follow your sentences correctly). I'm not fully sure, but I guess the main() which is mandatory for c is created by the IDE and invisible for the user, it initializes something, than calls setup (once), than maybe some other checks are done, than a `while (true) { loop(); } is called,

(btw if an answer is helpful, upvote it (by clicking the 'up' arrow), if an answer (or the best answer is given that solves your problem), accept the answer.

@MichelKeijzers: Here is main().

@EdgarBonet Thanks for that code.

@Sören "But in a C-program a variable declared in main() keeps its value." - A variable in main() keeps it value until execution leaves main(). Just as for Arduino's loop(), and indeed any other function. (One difference of course is, that once you leave main(), your program exits and it doesn't matter what happens to the variables.)

Michael's answer was good, as usual. Let me give you some more background though:
In C/C++ (And in most modern languages) variables have a "scope", or an area where they are defined.
Global scope:
Variables declared at the top level of your program have global scope, and exist for the life of your program. These variables are usually created on the .data or .bss sections.
Local scope
Variables declared inside a function have local scope. Unless they are static, they get created when the function is entered, and get discarded when the function exits. These variables are created on the stack as part of the function's stack frame.
Object scope
In C++ and other object-oriented languages, instances of objects have their own scope, "instance variables". Every instance of an object has its own set of instance variables. (Think of cars, and a car radio. You and I might own the exact same model of car, but if I set my car's radio station and you set your car's radio to a different station, each instance of the car has a different setting for the radio station.)
Static variables:
Static variables are variables that are declared "statically." That means that they are only created once and persist, even if they are declared inside a scope like a function or a class instance. These have the lifespan of a global variable but can be declared inside a function or in an object.

Loop is a function, so variables declared inside of loop() are local variables. They get created anew every time the function is called, and discarded every time the function exits.

+1 for the great explanation and background

Your code has a couple of bugs.  First you don't initialize counter before using it.  Second the variable 'counter' has limited scope, it has no definition when loop() exits.  If you want this variable to stay around declare it as static.
Both bugs corrected
e.g.:
void loop(void)
{
    static uint8_t counter = 0;
    ....
    if (buttonPress)
        counter = 0;
    ...
    if (someCondition == true)
    {
        Serial.println(counter);
        counter++
    }
}

Note:  Initializing counter to 0 only happens once, on subsequent calls to loop() counter will retain it's previous value.

The problem is that you declare a new variable. So even though the name is the same, the local variable is destroyed at the end of the loop and recreated at the beginning.
Actually, there is no good solution:

Global variables are best to be avoided. They can be seen as 'singleton's', e.g. variables that are needed at many places in the code and have only one occurrence.
As you found out, static solves the problem. I would use this option, although personally I'm not a fan of static variables.
Another way is to put the loop in a while, so you get:
void loop(void)
{
    uint8_t counter = 0; // Always initialize variables
    while (true)
    {
        // Your code
    }
}
This will work too, as your counter is only initialized once, however the loop is already (internally) a while loop, so you have two.
A much better way but more extra work, is to create a C++ class, where counter can be a class variable, which is local for that class (which could still be a singleton). Of course this is only true when the counter variable is belonging logically to that class, if it is not, just keep it a global variable (updated after Edgar Bonet's remark).

Making the counter a property of an object which is itself a global variable would be no better than making the counter itself global. It would actually be worse: any complexity that serves no useful purpose is always a bad thing in a program.

@EdgarBonet You are right when that variable (the counter) is unrelated to the class that would be created (I was assuming so, but I will update my answer). If the counter is unrelated, than you are absolutely right.

Could you explain why simply using a global variable should be avoided? I see no disadvantage in terms of memory usage or performance. I'd say, using a global variable is just fine in many situations. In my opinion making it more complicate is also not very elegant.

@SimSon There is no disadvantage in terms of memory usage or performance, bit if you make all variables global and you have thousands of them, you can imagine what mess it will be. This will not happen easily in an Arduino Uno with 2 KB memory, but it's best to keep functionality isolated. Actually, one of the worst things about the Arduino IDE is that it works best with just an Ino file, and most people do not get further creating classes or separate files.

@SimSon: See Are global variables evil in Arduino?.

@MichelKeijzers okay, so how to manage this kind of problem is more a personal decision. I'm quite used to having several globals and I think it's very readable (a huge program with "thousands" of global variables will be complex anyway). Thanks for clarification

@EdgarBonet thanks, I allready know this question.

@SimSon In your case, you can use the static, because you will use the variable only in that one function. Or keep it global (than you can use it in different functions too when you decide to split the loop function when it gets to big, or when you need it in an interrupt). In the program I'm making I have classes with variables inside classes (called properties) but my program is over 1,000 lines.

@MichelKeijzers I'll keep that in mind, thank you!

Btw, there is a disadvantage of using not global variables, as Duncan C mentioned, global variables to to the heap, and local variables to a stack. That means they will not be counted in the summary you get when you build your sketch (so you have to manually keep track of the local variable size (and parameters) to know if you can run into memory problems.

Globals are statically allocated into the .data or .bss sections, just like static locals. They are all counted in the build-time memory usage summary. The heap is where you get with malloc() and new.

@EdgarBonet You are fully right (again) ... in the case of the OP both global and static will be counted towards .data/.bss, and local (non static) go to stack.

I don't like the "loop in a while" idea.  The void loop(void) function is already called from a loop, which can be presumed to have some other code in it until we know otherwise.  The "loop in a while" idea prevents that other code from running because it never returns.

@AaronD True ... actually it does  not even work  as Edgar Bonnet shows there is some code called in the framework after each call to loop.


text:
localtime - executing one after the other- different time_t, but getting same results
When I try to comapre 2 time_t values I get unexplained behavour
time_t t = 12345;
time_t T = 67890;
struct tm *tm = localtime(&t);
struct tm *Tm = localtime(&T);

    char timeStamp[40];
    sprintf(timeStamp, "(1) %04d-%02d-%02d %02d:%02d:%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
    Serial.println(timeStamp);
    sprintf(timeStamp, "(2) %04d-%02d-%02d %02d:%02d:%02d", Tm->tm_year + 1900, Tm->tm_mon + 1, Tm->tm_mday, Tm->tm_hour, Tm->tm_min, Tm->tm_sec);
    Serial.println(timeStamp);

I get the exact same date.
When commenting out one of each set, I get the correct answer for each one.
Workaround I did was, but i'm sure there is an elegant way to overcome:
        time_t t = 12345;
        time_t T = 12345;
        struct tm *tm = localtime(&t);
        uint8_t now_month = tm->tm_mon;
        uint8_t now_day = tm->tm_mday;

        struct tm *Tm = localtime(&T);
        uint8_t save_month = Tm->tm_mon;
        uint8_t save_day = Tm->tm_mday;

        if (now_month == save_month && now_day == save_day)
        {
        }

From the manual page of localtime() (emphasis mine):

The asctime(), ctime(), gmtime(), and localtime() functions
shall return values in one of two static objects: a broken-down time
structure and an array of type char. Execution of any of the
functions may overwrite the information returned in either of these
objects by any of the other functions.

As a solution, I suggest you take a copy of the struct tm used by
localtime() to store its result, rather than keeping a pointer to it:
struct tm tm = *localtime(&t);
struct tm Tm = *localtime(&T);

Well somehow I missed that line when seeking the answer. I can't see how they managed to pull such bad design (or it  has a reason for that).... I have a shocked look as in your user's pic :) TNX!

@guyd it is the C language old time API


text:
Upload s sketch to a 5v Pro-Micro board as 3.3V by mistake
I have 2 types of Pro-Micro(as shown here), both 5v, micro-usb, which worked as expected, until, accidentally were flashed as 3.3v using the Arduino IDE.
At first I thought that the fact it stoped working right after, has nothing to do with that error, but since again, did the same mistake, I understand that this is no coincidence.
After doing so, boards seemed to be powered on ( leds are ON ), but are not found under port in the Arduino IDE.
Are they really can be destroyed by such an error ?

Holding RST and GND pins after re-connecting USB, showed it on port menu.
needed another such holding, prior to upload.
All good now.

I had the same issue with a promicro wired in to a button box, before i found out that you need to upload a sketch....I know...I`m a noob, I was trying to rename my button boxes board to a Sparkfun board but I think i had 3.3v 8mhz selected instead of 5v 16mhz, as a result my board was not detected under comm ports and gave a driver error, given that...with my board at least there is only an 8 second delay in which you have to select the correct comm device and then upload a sketch, I shortened the process by opening IDE and selecting the board type and left IDE with a black sketch, of coarse this does not allow the board to be detected as a usb device but it fixes the comm port issue, instead of using a fiddly wire jumper i just used a small screw driver to jump the gnd and reset contacts and quickly selected the boards comm port in IDE then upload  with out a delay, by the time IDE actually recognizes a device you actually have closer to 3-4 seconds to react....but its doable.