text:
Fail to return int value from a function
I have created myJSON library to simplify read and write values from/ to FLASH of my ESP8266 NodeMCU/ Wemos Mini.
I do not want to "mess up" the question, posting my entire code/ library - but to try to explain what happens -
I get a 0 value when reading a specific key (and not its saved value ). My assumption is that is has nothing to do with myJSON library, but my understanding in returning a value from a function.
Code is as follows:
(some explanations first):
1) json is an instance of myJSON library.
2) json.setValue(key, value) - gets a key and a value ( char/ int) and save it to FLASH.
3)json.getINTValue(key, return_var)- gets a key and return its int value to return_var. function return 1 - for successful read, and 0 when not.
inside setup()
int int_val;
// json.setValue("int_key",343); // commented out after first run - to be sure is is saved and read from flash.
Serial.println(json.getINTValue("int_key",int_val)); // NOTE 2
Serial.print("Value is: "); // NOTE 3
Serial.println(int_val);   //  NOTE 3

myJSON ( only relevant code )
bool myJSON::getINTValue (const char *key, int retval){
        StaticJsonDocument<DOC_SIZE> tempJDOC;
        myJSON::readJSON_file(tempJDOC);
        bool hasKey = tempJDOC.containsKey(key);
        if (hasKey){
          retval = tempJDOC[key];
          Serial.print("retval :"); // NOTE 1
          Serial.println(retval);  // NOTE 1
          return 1;
        }
        else {
          return 0; // when key is not present
        }
}

void myJSON::setValue(const char *key, char *value){
        StaticJsonDocument<DOC_SIZE> tempJDOC;
        myJSON::readJSON_file(tempJDOC);
        tempJDOC[key]=value;
        myJSON::saveJSON2file(tempJDOC);
}
void myJSON::setValue(const char *key, int value){
        StaticJsonDocument<DOC_SIZE> tempJDOC;
        myJSON::readJSON_file(tempJDOC);
        tempJDOC[key]=value;
        myJSON::saveJSON2file(tempJDOC);
}

result is (SEE NOTATIONS):
21:01:03.198 -> retval :343  // OUTPUT NOTE 1
21:01:03.198 -> 1            // OUTPUT NOTE 2
21:01:03.198 -> Value is: 0  // OUTPUT NOTE 3

As far a I could understand :
1) setValue works as needed ( inc. saving to flash ).
2) unexplained besides getting value = 0, is when setting a char value ( there are 2 myJSON::setValue functions to deal with int and char), code works as needed.
Appreciate any help ( and sorry for my English ).
Guy

bool myJSON::getINTValue(const char *key, int &retval){

@Juraj can you explain why? and why is it different from char variable ?

it is not an Arduino question. & is 'reference'. the parameter with & is not a value, but a reference to a variable

@Juraj - I know the mean of &, but why it doest not pass its value a to retval?

the parameters of a function call are copied into parameters in the function. if the pointer is copied it still points to a memory where you write the data. if int is copied then changing the value changes the copy, not the variable used as parameter. reference is kind of pointer
how to make an in-out parameter by passing a parameter by reference
void setup() {

  Serial.begin(115200);
  int x = 3;
  fnc(x);
  Serial.println(x);
}

void loop() {

}

void fnc(int &x) {
  x = 5;
}

prints 5
example with a complex type
#include <IPAddress.h>

void setup() {

  Serial.begin(115200);
  IPAddress ip(192, 168, 1, 5);
  fnc(ip);
  Serial.println(ip);
}

void loop() {

}

void fnc(IPAddress& ip) {
  ip = IPAddress(192, 168, 1, 3);
}

with &ip it prints 192.168.1.3. without & it prints 192.168.1.5

Tnx ! and the reason char behaves differently is because it points to a pointer ?

char* is a pointer. and char[] is a pointer too. it is copied so assigning a different pointer to it would not work. but if you change the memory where it points you will read outside of the function the same memory location with the changed content

Your problem is not directly how to return a variable, but how to give a variable from outsite the function as parameter to be filled by the function. There are basically 2 types how you can give a variable to a function: by value or by reference
The definition of getINTValue() says
getINTValue (const char *key, int retval)

so retval will be an integer and is called by value. This means, that a local variable with that name is created and filled with the value from the function call parameters. You are writing to this variable, but it get's thrown away when the function returns. And the writing to the local variable didn't change the outsite variable.
You need to use a call by reference. Your function must take a pointer to an integer variable. Then you dereference it and write to it:
getINTValue (const char *key, int *retval){
    ...
    *retval = tempJDOC[key];
    ...
}

When you call the getINTValue() function, it must be done like this:
int value;
bool result = getINTValue("int_key", &value);

The & operator gets you the pointer to the variable value, which the function then uses to write a value at that memory location.

char* is different, because you give an array to the function in this case. The compiler sees, that the used variable is an array and uses the pointer to the first element of the array as parameter. That is a common way, because you can iterate over an array by using pointers (without index numbers). You can do the same with any array of any type, but in this case you only have a single variable, not an array.

Oh, sorry, have read it wrong. Can you elaborate your comment shortly or give me a hint for what to google here? I learned it the way I've shown in my answer and while googling I couldn't find your way of doing it (though I didn't google for long). Would be great to learn more.

I wrote it as answer


text:
Convert a char array to Flash string
I would like to pass a formatted string to a method that accepts a __FlashStringHelper. Here is the method signature:
void myMethod(const __FlashStringHelper *str);

I have been using snprintf to format my string:
char cmd[30];
snprintf(cmd, 30, "There are %d seconds in a minute", 60);
myMethod(F(&cmd[0]));

Clearly the above doesn't work but how can I format a Flash String?
EDIT: I need to include an integer variable in my flash string. In the example above, '60' is a variable.
uint8_t nSeconds = 60;
char cmd[30];
snprintf(cmd, 30, "There are %d seconds in a minute", nSeconds);
myMethod(F(&cmd[0]));

Doesn't this method have an overload that accepts a const char*?

Direct answer
F() takes immutable string literals, that are known at compile time, and places them into flash ("PROGMEM") instead of RAM.  snprintf() creates strings at runtime and places them into a mutable array.  The two things are fundamentally incompatible.
Limited compile-time concatenation
A very limited form of what you're trying to do could probably done like this:
#define MY_STRINGIZE(x) #x

myMethod(F("There are " MY_STRINGIZE(60) " seconds in a minute"));

This expands to:
myMethod(F("There are " "60" " seconds in a minute"));

Adjacent string literals are concatenated together, which makes this:
myMethod(F("There are 60 seconds in a minute"));

All that said, you could just write 60 in there directly.  And there's none of snprintf's formatting capabilities possible here.
There is not a compile-time version of snprintf available in Arduino.  And I don't think the features of the C++ (or C) language are there to support the creation of one either.  Odds are there is a better way of achieving what you really want to do.
Working around this altogether
Often it's not necessary to concatenate strings at all, particularly if you're just to turn around and write them to a Stream, or more generally Print subclass, e.g. Serial, LCD, SDFile, SoftwareSerial, etc.  Concatenating things for you is a large part of what these do.  It is not necessarily to do it yourself in advance.
If you have a string literal and constant (or variable) and want to keep as much of it out of RAM as possible, using two separate .print()/.println() helps you do this:
printCapableThing.print(F("AT+CIPSTAT="));
printCapableThing.println(index);

F() places "AT+CIPSTAT=" into flash.
If index is a constant it will also wind not being resident in RAM.

Side note
I realize you're asking about, getting as much into flash as possible, but I also can't help but point out this same basic technique applies to this otherwise awful idea, for somewhat different reasons:
Serial.println(String(F("Key ")) + keyname + " : " + value);

This creates a horrific mess of allocations and deallocations and unnecessary copying, where if you just let the Stream/Print object do its job by calling print()/println() multiple times.  The result code is more reliable, smaller, and where not I/O-bound, faster when you do.

I guess what he really needs is not a compile-time version of snprintf (that would be quite useless), but a myMethod that takes a const char*.

I can absolutely see uses for compile-time string formatting.  Though yes, it probably will come down to the latter.

I mean you could be writing an implementation for snprintf(cmd, 30, F("There are %d seconds in a minute"), 60); (not hard to do with a temporary copy). But something like snprintf(F("..."), 30, F("Result is %d"), 60); cannot work, because the result of snprintf can certainly not be in flash.

You could, but you needn't.  There already exists an snprintf_P variant capable of taking the format string from PROGMEM.  You'd probably use PSTR there instead though. I'm not seeing the relevance of this though.

Thank you all for you responses!
@timemage: The '60 seconds in a minute' isn't my exact use case, my use case requires context which I tried to omit.
Mostly, I am trying to understand how I can format a string in program memory.

I can amend the answer if you have add more details to your question.  But, if I'm taking the question fairly literally, knowing that it is an example, is that there isn't a way to do that.  You can source parts of your ultimately cobbled-together string from flash/progmem.  But the result of formating will need to wind up in RAM.  Often it's not necessary to concatonate strings at all, particular if you're just to turn around and write them to a Stream (e.g. Serial, LCD, SDFile etc).

@timemage How can I use a variable inside a flash string? I added comments above. I need to issue an AT command to a GSM shield. The command requires an index variable. I could literally write out numerous methods to handle this, but for the sake of understanding how, I would prefer to write one method that accepts as input an integer (index) and issues the following command: AT+CIPSTAT={index}.
mySoftwareSerial->println(F("AT+CIPSTAT={index}"));

I could answer that, but there's something better which I alluded to above.  I'll amend the answer to what I'd suggest there instead.

Great answer, thanks @timemage!

source: Stack Exchange

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

sort: votes


text:
NodeMCU and SDS011
today I connected the SDS011 to NodeMCU. I noticed that this only works when the sensor is connected to the voltage VU. If I connect the sensor to another pin for the voltage, it does not respond.
Why is this so?
If I see it correctly, the reason must be that data is exchanged via RX and TX.
#include "SdsDustSensor.h"

int rxPin = 5; //d1
int txPin = 4; //d2
SdsDustSensor sds(rxPin, txPin);

void setup(){
  Serial.begin(9600);
  sds.begin();
  sds.setCustomWorkingPeriod(0);

}

void loop(){
PmResult pm = sds.readPm();
  if (pm.isOk()) {
     Serial.println(pm.pm25);
     Serial.println(pm.pm10);
  }

  delay(250);

}

how can anyone know? ... you said nothing about the sketch that you are using

Share some schematic/code.

The SDS011 needs 5 V powering and the VU pin is the 5 V from USB on the NodeMCU development board.

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


text:
Raspberry Pi with multiple arduinos using spi
I want to use Raspberry Pi as an aggregator & distributor of messages originating from or destined for a flight simulation program.
I'd like to use arduinos connected via spi as specific hardware controllers, communicating as fast as possible with the raspberry pi to accept messages as they come from the simulation program and at the same time to transmit messages to the simulator when various switches and controls are operated.  At the same time, each arduino might need to control additional spi devices by acting as master, when not operating in slave mode to the raspberry pi.
Can several Arduinos be connected to a Raspberry Pi as a slave devices while acting as a master device for other devices connected to the arduino like an adc, a dac, a multiplexer or motor controller?

yes ...........

Personally I'd use the USB connections... much simpler.

Yes it can be done but it is not to common. It will be a nightmare with the chip selects. The SPI was designed as a local high speed bus for use on a PCB, not communication between modules. This link will help explain what I am trying to say: http://www.eeherald.com/section/design-guide/esmod12.html Remember you will have to use a level translator for the Pi.


text:
Increase or decrease const byte value inside the code with a push button
I'm kind of new in the Arduino world. I decided to make a self learning project with an Arduino where it controls a conveyor that simply moves from right to left and back again. There is a start and stop button. On each end of the conveyor are inductive sensors to stop the motor when it reaches the end position. After a delay, the conveyer starts again the opposite direction. Inside the code I have a cycle counter that stops the conveyer after a certain number of cycles.
Now my question is, how could I change the value of the cycle counter using two push buttons. One to increase the other to decrease.
If there is somebody who could help I would appreciate.
Thanks already
const byte sensorLinksEnd  =  2;
const byte sensorRechtsEnd =  3;
const byte startPin        =  4;
const byte stopPin         =  5;
const byte relaisLinks     =  6;
const byte relaisRechts    =  7;

enum {relaisAn, relaisAus};
enum {warten, on, rechts, haltrechts, links, haltlinks, off};
byte schritt = warten;
byte zyklus = 20; //cycles
const byte maxzyklus = 20; //max cycles

void setup() {
  Serial.begin(115200);
  Serial.println(F("Start...."));
  pinMode(sensorLinksEnd, INPUT);
  pinMode(sensorRechtsEnd, INPUT);
  pinMode(startPin, INPUT);
  pinMode(stopPin,  INPUT);
  pinMode(relaisLinks, OUTPUT);
  digitalWrite(relaisLinks, relaisAus);
  pinMode(relaisRechts, OUTPUT);
  digitalWrite(relaisRechts, relaisAus);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop() {
  schrittkette();
}

void schrittkette()
{
  static unsigned long lastmillis;
  const unsigned long pauseZeit = 5000; // in ms
  if (digitalRead(stopPin))
  {
    schritt = off;
  }
  switch (schritt)
  {
    case warten:
      if (digitalRead(startPin))
      {
        zyklus = 0;
        schritt = on;
      }
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      break;
    case on:
      digitalWrite(LED_BUILTIN, HIGH);
      schritt = rechts;
      break;
    case rechts:
      digitalWrite(relaisRechts, relaisAn);
      if (digitalRead(sensorRechtsEnd))
      {
        digitalWrite(relaisRechts, relaisAus);
        schritt = haltrechts;
        lastmillis = millis();
      }
      break;
    case haltrechts:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      if (millis() - lastmillis > pauseZeit)
      {
        schritt = links;
      }
      break;
    case links:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAn);
      if (digitalRead(sensorLinksEnd))
      {
        digitalWrite(relaisLinks, relaisAus);
        schritt = haltlinks;
        lastmillis = millis();
      }
      break;
    case haltlinks:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      if (millis() - lastmillis > pauseZeit)
      {
        if (zyklus == maxzyklus)
        {
          schritt = off;
        }
        else
        {
          zyklus++;
          schritt = rechts;
        }
      }
      break;
    case off:
      digitalWrite(LED_BUILTIN, LOW);
      schritt = warten;
      break;
  }
}

What have you tried so far? With what exactly do you have problems? And please include your code in your question (not in the comments please)

The wording in your question's subject makes me wonder if you've read what const does.

@timemage thanks for the reply. Ok the const is only read-only. What woul be a alternative for that? How i can post here my complete Code? Sorry it´s the first time here

I put the complete Code in the first question

The alternative would be to not use the const keyword there. If it shouldn't be constant, then don't use the const keyword. For your whole question: You could divide that up into reading buttons and into changing variables. With which do you have problems exactly and what have you tried so far? Have you googled for tutorials on how to read buttons?

@chrisl  I know now that I can't use const. I would need I think a unsigned int or better a unsigned long. I want to be able to change a big number. Something around 60000 cycles.  It was over the tutorials that I was able to make my start and stop buttons. But unfortunately to change a variable like I want I didn't found until now nothing that I could understand. I'm a complete beginner in c++ coding. What I have until now is taking out from examples or asking for some tips. If you know a tutorial who would help for this particular situation, I would appreciate your help

@CarlosCosta is it maxzyklus that you wish to use as your cycle counter variable?

Thanks for the help everybody. I found a solution.

How I can put on a easy way here my Code to show?

@CarlosCosta If you have found a solution to your problem, you can write an own answer to your question and accept that as correct. Glad you found a solution and are willing to share it. +1

The const keyword tells the C/C++ compiler that the variable is a constant and cannot be changed in your code anymore.
Simply remove const and you can modify maxzyklus by using 2 digital inputs.
byte maxzyklus = 20; //max cycles


text:
Need help with calculator logic
I am trying to build a calculator with an Arduino, an LCD display, and a keypad. Getting inputs from the keypad is not the issue. Before I can add, subtract, multiply, or divide any two numbers, I want to make sure the calculator registered the given number. I am trying to program it (so far) so that I type in a number and press enter (the @ sign I assigned to my keypad) and the LCD prints out that number. As you will see, I attempted to devise a logic mechanism for the Arduino to recognize the typed number.
I thought since as you type more numbers the value of the first number typed increases by 10 fold each time (if you start by pressing 4 then if you press another number such as 5 following it, that 4 will become 40, and 400 if another number is pressed, etc...) I could multiply that number (and every following number) by 10, 100, 100, etc...
But it doesn't work and I need help so that the number can be collected by the Arduino.
Here's my attempt at it:
    #include <LiquidCrystal.h>
    #include "Arduino.h"
    #include "Keypad.h"

    int count = 0;
    int row = 0;
    int column = 0;

    //const int buzzer = 0;

    int value1;
    int value2 = 0;

    int spot1 = 0;
    int spot2 = 0;
    int spot3 = 0;
    int spot4 = 0;
    int spot5 = 0;
    int spot6 = 0;
    int spot7 = 0;
    int spot8 = 0;

    LiquidCrystal lcd(1, 2, 3, 4, 5, 6 );

    const byte ROWS = 4; //four rows
    const byte COLS = 3; //three columns
    char keys[ROWS][COLS] = {
      {'1','2','3'},
      {'4','5','6'},
      {'7','8','9'},
      {'%','0','@'}
    };
    byte rowPins[ROWS] = {10, 9, 8, 7}; //connect to the row pinouts of the
    keypad
    byte colPins[COLS] = {13, 12, 11}; //connect to the column pinouts of
    the keypad
    Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS
    );

    void setup() {
      //pinMode(buzzer, OUTPUT);
      lcd.begin(16,2);
      lcd.print("---Calculator---");
      delay(2000);
      lcd.clear();
      lcd.print("Value1: ");
      lcd.blink();

    }

    void loop() {
char key = keypad.getKey();

if(key != NO_KEY){
  lcd.print(key);
  if(key != '%' && key != '@'){
    count++;
  }
  else if(count == 1){
    spot1 = key;
  }
  else if(count == 2){
    spot2 = key;
  }
  else if(count == 3){
    spot3 = key;
  }
  else if(count == 4){
    spot4 = key;
  }
  else if(count == 5){
    spot5=key;
  }
  else if(count == 6){
    spot6=key;
  }
  else if(count == 7){
    spot7=key;
  }
  else if(count == 8){
    spot8=key;
  }

  if(key=='@'){
    if(count == 1){
      value1 = spot1;
    }
    else if(count == 2){
      value1 = (spot1*10)+(spot2);
    }
    else if(count == 3){
      value1 = (spot1*100)+(spot2*10)+spot3;
    }
    if(count == 4){
      value1 = (spot1*1000)+(spot2*100)+(spot3*10)+spot4;
    }
    if(count == 5){
      value1 = (spot1*10000)+(spot2*1000)+(spot3*100)+(spot4*10)+spot5;
    }
    if(count == 6){
      value1 = (spot1*100000)+(spot2*10000)+(spot3*1000)+(spot4*100)+(spot5*10)+spot6;
    }
    if(count == 7){
    }
    if(count == 8){
    }
    lcd.print(value1);
  }

  if(key  == '%'){
    count = 0;
    lcd.clear();
    lcd.print("Value1: ");
    lcd.blink();
  }
}

}

PS: If you know any better way to accomplish this goal, I would love to hear it.

Instead of storing all the different digits in a whole bunch of variables, why not keep one int variable and keep track of everything in it.  Instead of the count++ you just multiply the int by 10 and get ready to add the next digit.

Please be more explicit about what "doesn't work". Your method, while perhaps not very elegant should work, for small numbers anyway. I didn't spot a mistake from a quick glance at the code, but I don't know what I'm looking for.

the issue is that the calculator outputs 64 regardless of what I entered

I agree with @Delta_G - accumulate the value as you go instead of collecting digits then assembling them afterwards.  I'm not sure why you would get 64 from this, ...   Have you tried the accumulator approach?

If your keypad setup results in '%' and '@' arriving correctly, then it probably also results in the characters '0', '1', ... '9' arriving when number keys are pressed, rather than digit values 0, 1, ... 9 arriving.
Be that as it may, there's a far simpler approach to building value1 which does not use a big set of spot values like your method does.  Here is an illustration of it.
// ... Before number input, zero out a number-accumulator variable
long int nin = 0;

do {
  key = keypad.getKey();
  if (key != NO_KEY) {
    lcd.print(key);
    // As number keys are pressed, add them to tail of number
    if (key >= '0' && '9' >= key) {
      nin = 10*nin + (key & 0xF);   // Get low 4 bits of key
    }
  }
  if (key == '@') {
    lcd.print("Value = ");
    lcd.print(nin);
    // ... do whatever else with value
    // ... then get ready for next value
    nin = 0;
  }
} while (1);

if(key != '%' && key != '@'){
  count++;
}
else if(count == 1){
  spot1 = key;
}
else if(count == 2){
  spot2 = key;
}

You've got a problem here.  If key isn't '%' and isn't '@' then you increase count but since all the rest are else if to that then it skips over all of them and never actually puts the digit int the spot.

I tried removing the else's but it still does not appear to work

Define doesn't work.  What happens?  How does that compare with what you expect?

That may not be the only logical flaw in your program.  It's just the one that jumped out at me first.

The calculator spits out 64 no matter the input

Interesting. 64 is the ascii code for '@'.  If you press something that is not % or @ then you're not storing anything. But when you get @ then the first if isn't true and it goes to one of the else if where count is whatever and stores the 64 in one of the spots.

I can see that my method may not be the most effective. Any suggestions?

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


text:
Send button only works when pressed immediately after
I am new to Arduino and I am trying to create a Morse code based "chat".
I can submit a message in Morse code using the send button (the one on the right,) and when I press the button on the left and the whole decoded message should appear on the screen. However, this is not happening unless I press the send button immediately after introducing the Morse code. Can anyone help me out? I tried changing the delay period, but nothing seems to make it send how it should.
As I said, I am a beginner, so please go easy on me.
This is my code:
/* String tone = "-... ..- -. .- ";

  Morse code - Receiver

  modified on 14 Apr 2019
  by Saeed Hosseini @ Electropeak
  https://electropeak.com/learn

*/
#include <LiquidCrystal.h>
// Create an LCD object. Parameters: (RS, E, D4, D5, D6, D7):
LiquidCrystal lcd = LiquidCrystal(2, 3, 4, 5, 6, 7);
String code = "";
int len = 0;
char ch;
int ok;
char new_char;
int i1=0;
int i2=1;
const int but_send=8;
const int but = 12;
const int led = 13;
String a="";
unsigned long pres_len = 0, rel_time, pres_time = 0, old_time_len = 0, old_pres = 0, space = 0;
int state = 0;
int unit_delay = 250;
int min_delay = 10;
int buttonState = 0;

char MakeString()
{
  if (pres_len < (unit_delay*3) && pres_len > 50)
  {
    return '.';                        //if button press less than 0.6sec, it is a dot
  }
  else if (pres_len > (unit_delay*3))
  {
    return '-';                        //if button press more than 0.6sec, it is a dash
  }
}

void Morse_decod()
{
  static String morse[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
                             "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
                             ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "!"
                            };
  int i = 0;
  while (morse[i] != "!")
  {
    if (morse[i] == code)
    {
      Serial.print(char('A' + i));
      a=a+char('A' + i);
      //lcd.print(char('A' + i));
      Serial.print(" ");
      if(i2>=2)
      {
        i1++;
        i2=0;
      }
      else
      {i2++;
      }
      break;
    }
    i++;
  }
  if (morse[i] == "!")
  {
    Serial.println("");
    Serial.println("This code is not exist!");
  }

  code = "";
}
void sendText()
{
  Serial.println(digitalRead(but_send));
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  //if (digitalRead(but_send) == HIGH) {
    // turn LED on:
     //gitalWrite(led, HIGH);
  if(ok==1){
    Serial.println(a);}
  ok=0;

    //}
  //else {
    // turn LED off:
    //Serial.println("NIMIC");
  //}
 delay(200);
}
void setup() {
  Serial.begin(9600);
  pinMode(but, INPUT_PULLUP);
  pinMode(but_send, INPUT_PULLUP);
  pinMode(led, OUTPUT);
  lcd.setCursor(i1, 12);
  lcd.begin(16, 2);

}
void loop() {
label:
  while (digitalRead(but) == HIGH) {}
  old_pres = rel_time;
  pres_time = millis();
  digitalWrite(led, HIGH);
  while (digitalRead(but) == LOW) {}
  rel_time = millis();
  digitalWrite(led, LOW);
  pres_len = rel_time - pres_time;
  space = pres_time - old_pres;
  if (pres_len > min_delay)
  {
    code += MakeString();
  }
  while ((millis() - rel_time) < (unit_delay * 3))
  {

    if (digitalRead(but) == LOW)
    {
      goto label;

    }

  }

  Morse_decod();
    delay(1000);
  if (digitalRead(but_send) == LOW)
  {
    ok=1;
    //Serial.println("A intrat aici");
    sendText();
    //delay(100);

  }

 //Serial.println(digitalRead(but_send));

}

This is what should happen all the time, not only after pressing the send button very fast:

If needed, I can send a link from my tinkercad simulation.

tavis’ answer nailed down your problem: your program is completely
unresponsive when it is blocked in the first while loop of the
loop() function. Here I will try to give you some hints on how to
avoid this situation, but first some general comments:

if (pres_len < (unit_delay*3) && pres_len > 50)

The threshold should be unit_delay*2, maybe with a longer
unit_delay. In Morse, a dot is one unit, and a dash is three units. If
you have to set a threshold, it should be somewhere in the middle.
Otherwise, a perfectly valid dash of 2.99 units would be mistaken
for a dot.
Also, a function returning anything but void should always return a
value. What is this function supposed to return if press_len is
smaller or equal than 50? And if it is exactly equal to
unit_delay*3? The best way to make sure you did not forget any case is
to have an else at the end that returns a default value in case no
condition matches:
else
    return '?';  // we could not understand

In this particular case, it seems to me like you already did the
debounce prior to calling the function, so it could be simplified to
char getSymbol()
{
    if (pres_len < 2 * unit_delay)
        return '.';
    else
        return '-';
}

Note that giving functions meaningful names is an important step in
making the code easy to understand and reason about.

if(i2>=2)
{
  i1++;
  i2=0;
}
else
{i2++;
}

All this serves no useful purpose, as you do not use i1 or i2 after
setup(). Removing useless stuff is also important for the clarity of
the code.

Serial.println("This code is not exist!");

It should say “I cannot understand this code!”, but it may well exist.
Now, to the core of the issue. If you want the program to be responsive,
you should embrace non-blocking programming. This means getting rid of
delay() (see Blink Without Delay) and getting rid of blocking
loops, like the two while loops at the top of loop(). A very useful
approach is to program your system as a finite state machine.
Please, take the time to read and digest these two resources.
Next, as an example, I can point you to a Morse decoder of mine that is
based on the finite state machine concept. You do not have have to look
at my code, which may be too low level for your taste, but look at the
documentation of the program internals. It explains how the state
machines are built and interact with one another. Below is a state
diagram taken from that documentation. It shows the state machine that
takes the debounced “rise” and “fall” events as inputs, and generates
“dot”, “dash”, “end-of-char” and “end-of-word” symbols as outputs:

It looks like the line : while (digitalRead(but) == HIGH) {} will capture the processor in a loop until "but" is pressed.  So if you press the send button immediately after using "but" it might see that you pressed "send", but if you let the program loop get back to while (digitalRead(but) == HIGH) {}, then nothing can happen until "but" is pressed again.

Both tavis and Edgar Bonet have hit the nail on the head, and Edgar has provided you with an excellent tutorial.
You are unlikely to get this to work properly in the Tinkercad browser simulator because it runs at different speeds depending on the complexity of the code it is running. And the complexity varies when you press buttons, which throws the timing out as the Morse button is pressed.
However, I managed to get it roughly working in Tinkercad as follows.

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const byte MORSE_BUTTON_PIN = 6;
const byte SEND_BUTTON_PIN = 7;
const byte MORSE_LED_PIN = 8;

const unsigned long DEBOUNCE_DELAY_ms = 50;
const unsigned long MORSE_UNIT_1 = 500;  // milliseconds.
const unsigned long MORSE_UNIT_2 = 2 * MORSE_UNIT_1;  // milliseconds.
const unsigned long MORSE_UNIT_5 = 5 * MORSE_UNIT_1;  // milliseconds.

const String MORSE_CODES[] =
{
  ".-", "-...", "-.-.", "-..", ".",
  "..-.", "--.", "....", "..", ".---",
  "-.-", ".-..", "--", "-.", "---",
  ".--.", "--.-", ".-.", "...", "-",
  "..-", "...-", ".--", "-..-", "-.--",
  "--.."
};

String symbol;
String message;

Debouncer morse_button(MORSE_BUTTON_PIN, DEBOUNCE_DELAY_ms);
Debouncer send_button(SEND_BUTTON_PIN, DEBOUNCE_DELAY_ms);

void setup()
{
  Serial.begin(115200);
  pinMode(MORSE_BUTTON_PIN, INPUT);
  pinMode(SEND_BUTTON_PIN, INPUT);
  pinMode(MORSE_LED_PIN, OUTPUT);
  // Set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Hello, world!");
}

void loop()
{
  static unsigned long press_begin_time = 0;
  static unsigned long release_begin_time = 0;
  static bool measure_the_gap = false;

  morse_button.Update();
  send_button.Update();

  if (morse_button.Fall())
  {
    // Remember when the morse button was pressed and
    // switch on the LED.
    int timestamp = millis();
    digitalWrite(MORSE_LED_PIN, HIGH);
    press_begin_time = timestamp;
  }

  if (morse_button.Rise())
  {
    // Remember when the morse button was released and
    // switch off the LED.
    int timestamp = millis();
    digitalWrite(MORSE_LED_PIN, LOW);
    release_begin_time = timestamp;
    int pressed_time = timestamp - press_begin_time;
    if (pressed_time > MORSE_UNIT_2)
    {
      // Dash.
      //Serial.print("-");
      symbol += "-";
    }
    else
    {
      // Dot.
      //Serial.print(".");
      symbol += ".";
    }
    measure_the_gap = symbol.length() > 0;
  }

  if (measure_the_gap)
  {
    unsigned long timestamp = millis();
    //Serial.println("Measuring the gap.");
    if (((timestamp - release_begin_time) > MORSE_UNIT_2))
    {
      // A long gap between presses signifies the end of a symbol.
      //Serial.println("Long gap");
      //Serial.println(symbol);
      measure_the_gap = false;
      message += DecodeSymbol(symbol);
      symbol = "";
    }
  }

  if (send_button.Fall())
  {
    // Print the Morse string.
    //Serial.println(message);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print(message);
    message = "";
  }

  // Delay for Tinkercad simulator.
  // Not needed for real hardware.
  delay(10);
}

char DecodeSymbol(String& symbol)
{
  //Serial.print(symbol);
  //Serial.print(": ");
  char ch = '?';
  for (int i = 0; i < 26; i++)
  {
    if (symbol == MORSE_CODES[i])
    {
      ch = 'A' + i;
      break;
    }
  }
  //Serial.println(ch);
  return ch;
}

For debouncing the buttons, I used this debouncer that I've put on GitHub. For Tinkercad, you will need to copy and paste that debouncer code (the debouncer.h file followed by the debouncer.cpp file) into the top of the Tnkercad code file because Tinkercad doesn't allow you to include your own code files.

+1, but note that: 1. timestamp and pressed_time should be unsigned long in order to avoid rollover issues, but then these variables are not really needed. 2. symbol.length() > 0 is always evaluated right after adding a character to symbol, and in this context it is always true.


text:
int array passed through function has wrong values only after multiple passes
I have this code:
for(int i = 0; i < its; i++) {
    x1 = random(0,4);
    y1 = random(0,4);
    multiLamp(new int[2] {3,1}, new int[2] {x1,x2}, new int[2] {y1,y2}, wait, 2);
    multiLamp(new int[2] {2,0}, new int[2] {x1,x2}, new int[2] {y1,y2}, wait, 2);
    x2 = random(0,4);
    y2 = random(0,4);
    multiLamp(new int[2] {1,3}, new int[2] {x1,x2}, new int[2] {y1,y2}, wait, 2);
    multiLamp(new int[2] {0,2}, new int[2] {x1,x2}, new int[2] {y1,y2}, wait, 2);
}

which calls the function "multiLamp" and passes 3 int arrays with 2 values each. Here is the function:
void multiLamp(int epos[], int xpos[], int ypos[], int del, int len) {
  for(int it = 0; it < del; it++) {
    for(int i = 0; i < len; i++) {
      lamp(epos[i],xpos[i],ypos[i],2);
    }
  }
}

This function is supposed to call some function "lamp" with a few integers from the arrays. In the beginning this works fine but after more than 50 calls of the "multiLamp" function the values in the arrays become {0,128,128} and {3,3,3} or something similar even though the values passed into it from my main code are equally valid as before (they are somehow changed after being passed to the "multiLamp" function).
I can't seem to find the issue here. Any help is appreciated!
UPDATE:
Here is the full code, although I don't know if it will be of any use because I wrote it to control some LEDs and if you don't have the setup it's difficult to see if the code is working or not.
int e[] = {12,13,11,10};
int xy[] = {2,3,4,9,6,7,8,5,1,A0,A1,0,A3,A4,A5,A2};

void setup() {
  for(int a=0;a < 4;a++){
         pinMode(e[a], OUTPUT);
         digitalWrite(e[a], LOW);
  }
  for(int b=0;b < 16;b++){
         pinMode(xy[b], OUTPUT);
         digitalWrite(xy[b], HIGH);
  }
}

void loop() {
  bigCubes(100);
  rain(20, 30);
  miniCubes(15);
  every(80);
}

void lamp(int epos, int xpos, int ypos, int del) {
  int xypos = 4*xpos+ypos;
  digitalWrite(e[epos], HIGH);
  digitalWrite(xy[xypos], LOW);
  delay(del);
  digitalWrite(e[epos], LOW);
  digitalWrite(xy[xypos], HIGH);
}

void multiLamp(int epos[], int xpos[], int ypos[], int del, int len) {
  for(int it = 0; it < del; it++) {
    for(int i = 0; i < len; i++) {
      lamp(epos[i],xpos[i],ypos[i],1);
    }
  }
}

void every(int wait) {
  for(int i = 0; i < 4; i++) {
    for(int j = 0; j < 4; j++) {
      for(int k = 0; k < 4; k++) {
        lamp(i,j,k,wait);
      }
    }
  }
}

void miniCubes(int wait) {
  int cube[8][3] = {{0,0,0},{0,0,1},{0,1,1},{0,1,0},{1,1,0},{1,1,1},{1,0,1},{1,0,0}};
  for(int c = 0; c < 8; c++) {
    for(int it = 0; it < wait; it++) {
      for(int i = 0; i < 8; i++) {
        lamp(cube[i][0]+2*cube[c][0],cube[i][1]+2*cube[c][1],cube[i][2]+2*cube[c][2],2);
      }
    }
  }
}

void bigCubes(int wait) {
  multiLamp(new int[32] {0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3}, new int[32] {0,0,0,0,1,1,2,2,3,3,3,3,0,0,3,3,0,0,3,3,0,0,0,0,1,1,2,2,3,3,3,3}, new int[32] {0,1,2,3,0,3,0,3,0,1,2,3,0,3,0,3,0,3,0,3,0,1,2,3,0,3,0,3,0,1,2,3}, wait, 32);
}

void rain(int its, int wait) {
  int x2 = random(0,4);
  int y2 = random(0,4);
  int x1;
  int y1;
  for(int i = 0; i < its; i++) {
    x1 = random(0,4);
    y1 = random(0,4);
    multiLamp(new int[2] {3,1}, new int[2] {x1,x2}, new int[2] {y1,y2}, wait, 2);
    multiLamp(new int[2] {2,0}, new int[2] {x1,x2}, new int[2] {y1,y2}, wait, 2);
    x2 = random(0,4);
    y2 = random(0,4);
    multiLamp(new int[2] {1,3}, new int[2] {x1,x2}, new int[2] {y1,y2}, wait, 2);
    multiLamp(new int[2] {0,2}, new int[2] {x1,x2}, new int[2] {y1,y2}, wait, 2);
  }
}

Mhh, I see you creating 3 new arrays on each call of multiLamp(), but I never see you freeing them again. Beside the fact, that dynamic memory allocation is bad on an AVR board like the Uno, you need to actually free the allocated memory again, when you don't need it anymore, or you will rather fast fill up the RAM. If no memory is left, the Arduino behavior is undefined (though mostly they just reset). That seems the best candidate for the problem reason. Can you please provide a full compilable example sketch, which shows your problem? (not just a snippet)

The part that's actually a problem is really a general programming problem.

@chrisl I added the full code although I don't know if it's of any use to you.

@chrisl Do I have to free them up manually? I thought the arrays would free up if the function ends?

You are wrongly using the new operator for your arrays. That will dynamically allocate these arrays. They are put on the heap (not the stack like local variables) and thus don't get freed automatically, when the function exits. That has to be done by your code with the delete keyword. Your code just eats up all the available memory. Thats called a memory leak.
That you need to free your dynamically created variables is not an Arduino thing; this is correct for all C/C++ code. But the limited memory on AVR based Arduinos like the Uno makes it worse.
If you do the math, one iteration of void loop() will block 432 bytes of memory (216 array elements, each of type int thus 2 byte). The 2KB of memory (which is also needed for local and global variables) is eaten up rather fast.
I don't see, why you even would use dynamically created arrays. Why not just using locally defined arrays, like in the miniCubes() function?

That said, it is also a generally bad idea to use dynamic memory allocation microcontrollers, especially those with small memory. When creating and deleting objects of different sizes (which is the main advantage of dynamic allocation), you will leave small holes in your RAM, which are too small for one of your objects to fit. At some point your RAM is completely filled with these holes, so that no more memory can be allocated for your objects to save. Thats called memory fragmentation.
On your PC that isn't a problem because of 2 reasons:

The PC has loads of RAM available, and
the OS manages the RAM, defragmenting it, if necessary.

Since microcontrollers don't have an OS managing the RAM and often very limited RAM, you need to make sure, that your RAM doesn't get fragmented too much in the runtime of your code.

Many thanks! I did it as you told me and did it like in the miniCubes() function. That worked great.


text:
Arduino nano as HID Keyboard
I'm a bit of a noob in the Arduino area but I found an Arduino nano I bought a long time ago sitting on my shelf and collecting dust,
so I taught "why not make a project". I game a lot of racing games so I wanted to make a simple ignition button with it, but every time I tried to compile or verify it, it says

Keyboard not found. Does your sketch include the line #include "Keyboard.h"

did you include the keyboard library from the Sketch menu?

@dandavis - that would not be possible or at least not meaningful, as there is no such library for a nano.

@ChrisStratton: good call.

Unlike and official Arduino Uno, which uses a re-programmable ATmega16U2 for an USB to UART interface, a Nano uses an non re-porgrammable FTDI chip.

A typical Nano has no hardware support for this - so you could only do it by a means such as software-approximate USB, or by adding a USB device interface chip.  As the answer suggests, there are better platform choices.

Maybe this question might help you. https://arduino.stackexchange.com/questions/76557/how-can-i-make-my-arduino-uno-press-space-on-my-laptop-keyboard/76570#76570

Arduino Nano I am not sure. But I am sure that you can do it with Arduino UNO.
https://www.youtube.com/watch?v=tvqA-JcTQNg

Get yourself a Arduino Leonardo, Micro or Pro Micro (or Due, Zero, M0). Those can emulate a keyboard.
Start with reading the Arduino Keyboard Mouse reference.
The Arduino Nano can not use the Arduino Keyboard Mouse library.
Since many years, there is a library called "V-USB" that requires some extra hardware and makes it possible for a ATmega328p microcontroller to act as an USB device. It is not something for a beginner.
A few years ago, Arduino has changed the way the USB is used. The NicoHood HID library makes use of the new possibilities. It makes it possible for example to have extended features for a USB keyboard, like the media keys.
For a normal keyboard and mouse, the Arduino Keyboard Mouse library will do. It will be perfect for a ignition button. But you have to buy one of those boards (Leonardo, and so on).

or a teensy board

The solution to get a board that has built in USB support is not preferred for someone who just wants to use the boards they already have.  It is possible to use a board that can communicate with your computer over serial, such as the Arduino Nano, to send data to a Python program which can then turn the input from the Arduino into keyboard presses, etc. using libraries.
For this approach, you would need to know python.
The libraries to use are:
pyserial - communication with Arduino
pynput - control the computer's keyboard
threading (comes with python) - allow pyserial and pynput to work simultaneously

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


text:
Listen for specific frequency
I’m trying to build a custom baby monitor for my wife who is deaf. It needs to detect loud noises and listen for a specific series of tones from a feeding pump our daughter uses.  It will then send a radio signal to the other room to trigger a bed shaker.
I do have a loop which samples the MAX4466 microphone and uses a “peakToPeak” calculation to determine volume, which I can use to trigger for loud noises (pasted below).  However, I cannot figure out how to determine the frequency of a noise sample.  I’ve tried searching for other sketches and tutorials that would work, but haven’t found anything.  The feeding pump, when it has an error puts out a series of tones which alternates between 4.1 kHz and 2.1 kHz.   What I wanted to do is see if the first tone is sounding, and then if the second tone shows up within a couple seconds afterwards, then it would trigger sending the signal to the other device.
I’ve tried for two days now to find a way to determine the frequency, but haven’t figured it out.  Any help would be greatly appreciated.  The closest I was able to get was this: Instructables - Arduino Frequency Detection, but when I use this script, the Arduino can no longer do analogRead() to get the status of various setting knobs and such I have on the device.
The script I use to get the sound level / loudness is:
  #define micPin 0                      // Microphone
  const int sampleWindow = 96;          // Sample window width in mS (50 mS = 20Hz)
  unsigned int sample;
    while (millis() - startMillis < sampleWindow) {
      sample = analogRead(micPin);
      // Check peakToPeak mins and maxs
        if (sample < 1024) {
          // toss out spurious readings
           if (sample > signalMax) { signalMax = sample; }          // save just the max levels
           else if (sample < signalMin) { signalMin = sample; }     // save just the min levels
        }
    }
    peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude

I don't have enough info to write a proper answer, but I suspect you're going to have to use something like a (fast) Fourier transform or a discrete cosine transform to get frequency information from real-world inputs. The article you link to uses (from a quick skim) variations on zero-crossing, which will go wrong as soon as you get background noise or multiple frequencies. A quick Google for "arduino fft" gave some hopeful-looking results. I hope that gives you something to get started. Good luck.

Might be able to use a Frequency-to-Voltage Converter http://www.analog.com/media/en/technical-documentation/data-sheets/ADVFC32.pdf

it would be a lot more practical to pipe the audio to a real computer and use fancy audio libs to achieve your goal. i guess a raspPI is "real" enough. look for "frequency bargraph" examples since they do everything you need and a tiny bit more (visualization)

I think the FFT solution is the best for your solution but... I usually find it more reliable to open the device I want to monitor and hook up a sensing point there (be it a transistor, an optocoupler, an op-amp, ...). If the alarm sound is the only one the feeder plays, you can just get the signal of the buzzer, filter it out a bit and you will have a digital signal for your arduino..

As stated in previous answers, frequency measurement is unlikely to be
reliable because the microphone is going to pick up ambient noise, which
is a combination of many individual frequencies. You want instead to see
how much sound amplitude you have at the specific frequency of the
feeding pump. Fourier analysis seems like the natural tool for the job.
However, a Fourier transform is heavy math, and overkill for your
application. You are only interested in the Fourier amplitude at one
specific frequency. Computing that single amplitude is way easier and
faster than doing a full-fledged Fourier transform.
My preferred method for doing that is called homodyne detection. It
is fast enough to be done in real time by an Arduino Uno sampling at
9.6 kHz. Basically you multiply the input signal by both a sine and
a cosine at the target frequency, then you low-pass filter both
products. The two resulting signals are the real and the imaginary part
of the complex amplitude you are looking for.
Here is a small program of mine that does almost exactly what you are
looking for: homodyne.ino. It is set for one specific frequency
(1 kHz, but it's trivial to change), and you will have to adapt it
to be able to change the target frequency between 4.1 and 2.1 kHz.

You can use a DFT(Discrete Fourier transform) that just checks the component frequency magnitude at 4.1kHz and 2.1kHz. Below is some code that works for my Arduino UNO. When I put a signal generator on A0 with a 2.3V(peak to peak) sine wave, the result goes above 0.5 at the respective frequencies.
float Single_Point_DFT(int16_t inputArray[], int startingIndex, int endingIndex, float sampleFreq, float freqToSampleFor){
  float N = endingIndex - startingIndex + 1; //N=number of samples
  float k = freqToSampleFor * N / sampleFreq;
  float radiansPerSample = 2.0 * 3.14159 * k / N;

  float RealSum = 0;
  float ImaginarySum = 0;
  for (int n = 0; n <= endingIndex - startingIndex; n++){
    float angle = n * radiansPerSample;
    float voltage = inputArray[startingIndex + n] * (5.0 / 1023.0);

    RealSum += voltage * cos(angle);
    ImaginarySum -= voltage * sin(angle);
  }

  return sqrt(RealSum*RealSum + ImaginarySum*ImaginarySum) / N;
}

const int analogInPin = A0;
uint32_t startTime_uS;
uint32_t endTime_uS;

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

void loop() {
  int16_t values[128];

  while(1)
  {
    startTime_uS = micros();
    for(uint8_t n = 0; n<128; n++)
    {
      values[n] = analogRead(analogInPin);
    }
    endTime_uS = micros();

    float sampleFreq = 128.0*1000000.0/(endTime_uS - startTime_uS);
    float result = Single_Point_DFT(values, 0, 127, sampleFreq, 2100);
    Serial.print(result);
    Serial.print(", ");
    result = Single_Point_DFT(values, 0, 127, sampleFreq, 4100);
    Serial.println(result);
  }
}

This calculation is pretty slow due to the float arithmetic and the sine/cosine calculations, But is is fast enough if the beeps last longer than a quarter of a second.

single-frequency DFT or related goertzel algorithm is indeed a good idea.  But doing it with floating point math on a system without hardware support of that is a very bad idea.  Also there's no need to take the square root, you can just compare the squared value.

A few ways, fft, 1057, or sin multification. Fft is quite calculation and space intensive, even in interfere form. For the detection of a known frequency, 1057 can be very efficient.
Multification is iterative so space and mips efficient. But you will need to filter and it detects with a delay.
A more efficient way is hardware filtering followed by rectification .

Could you give more details on “1057”?

With a microphone listening for one frequency in ambient audio you have to do far more than just count cycles or measure time between crossings.
You have to sample a burst of audio into a buffer at a minimum of double the rate of the highest frequency you are interested in. Then you need to analyse that audio sample to determine the amplitudes of the different frequencies within it. FFT (Fast Fourier Transform) is the most popular method of doing that, and there are integer maths based libraries and examples around on the internet suitable for running on an Arduino.

Yes, in general, however 1) Undersampling and looking for the aliased frequencies is not out of the question and might be used to advantage on an underpowered system 2) computing a full FFT is not needed and probably not efficient when the desire it to find two alternativing frequency components.


text:
Options for powering a Futaba servo
In one of my earlier questions it was determined for me that my Futaba Servo should not be powered directly from the 5v pin of my Arduino and should instead be powered by an alternative source. I was told the Servo requires a “high current 5 volt power supply” so I’m wondering what my best options are as my knowledge in servo control is quite limited. Is there some type of board that helps with this? Do I need a specific battery? If the servo needs a battery could it run off of the same battery as the arduino? Im trying to keep my design as compact as possible so multiple battery packs could pose complications.
The specific information can be found here.
Thanks for any help!

Based on the link to the specifications, this is a "high speed, high torque" servo. Unfortunately, none of the information includes the maximum or typical current draw, though there are warnings to higher gauge wire than usual and to avoid long leads and Y-splitters.
These are indications that your power supply should be "beefy", and by the class of servos this is in, I would guess you need a supply capable of supplying 5V at up to 3 amps.
The "harder" the servo has to work to move, the more current it will draw. This servo wants around 5V, but 4.8V is acceptable from a 2S (2 series) LiPo battery pack.
4.8V, however, is not quite enough for a 5V Arduino at 16MHz (the standard speed). As long as all the Ground wires are connected together, you could have one battery pack for the Arduino and a 4.8V pack for the servo.
All that said, there are only 2 primary specification points of a power source -- Output Voltage and Max current. You should try to MATCH voltage ratings of a power source to the device being powered, and ensure the device being powered DOES NOT EXCEED the current rating of the power source.


text:
Reading data from ThingSpeak via Arduino Uno+ESP8266
I am integrating thingspeak and arduino plus Esp8266 mean making a simple project which contain my android app to update the thingspeak channel and then want to read the data of that channel via arduino uno. the android parts works fine but at the arduino side i got stuck and unable to read the channel data via esp8266(attached to my arduino uno).
Here is my code.any help would be appreciated.
it shows in serial monitor connecting to thingspeak.com and show nothing next.
#include "WiFiEsp.h"

// Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(2,3); // RX, TX
#endif

char ssid[] = "M T G";            // your network SSID (name)
char pass[] = "androidGUII";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

char server[] = "arduino.cc";

// Initialize the Ethernet client object
WiFiEspClient client;
static const char* host = "api.thingspeak.com";
static const char* apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
void setup()
{
  // initialize serial for debugging
  Serial.begin(115200);
  // initialize serial for ESP module
  Serial1.begin(9600);
  // initialize ESP module
  WiFi.init(&Serial1);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }
  // you're connected now, so print out the data
  Serial.println("You're connected to the network");
  printWifiStatus();
  Serial.println();
}

void loop()
{
      const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
        Serial.println("connection failed");
        return;
    }
  client.println("GET /channels/xxxxxxx/feeds.json?api_key=xxxxxxxxxx&results=2 HTTP/1.1");
  while (client.available() == 0);  // wait till something comes in; you may want to add a timeout here
  Serial.println(client.read());
  client.stop();  // close socket
  delay(10000);
}
void printWifiStatus()
{
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

http://forum.arduino.cc/index.php?topic=535651

dear this is my question which is not answered yet there too..thats' why i posted it here.thank for your time

@mtg client.read() reads a single byte. I doubt that's what you want.

HTTP GET request needs to end with an empty line and HTTP 1.1 requires a Host header.
Add an empty line and eiher change the HTTP version to 1.0
client.print("GET /channels/421932/feeds.json?api_key=");
client.print(apiKey);
client.println("&results=2 HTTP/1.0");
client.println(); // empty line

or add the Host header
client.print("GET /channels/421932/feeds.json?api_key=");
client.print(apiKey);
client.println("&results=2 HTTP/1.1");
client.print("Host:");
client.println(host);
client.println(); // empty line

the empty line is only for requests with body like POST request, to mark the start of the request body

@Juraj I tested it in Python by sending it over TCP with only a single pair of "\r\n" and the server didn't respond. Had to be "\r\n\r\n".

I looked up the protocol. It requires the empty line after the header for all requests

WiFiEsp] Connecting to api.thingspeak.com
13
[WiFiEsp] Disconnecting  3         //now it shows this in serial monitor

use the library https://github.com/mathworks/thingspeak-arduino


text:
Searching for a good keypad
I'm wanting to make a keypad for my gragedoor. I found one like this but i don't think it is very waterproof.
Now i'm wondering if someone of you know a good keypad that can be used outdoors and can be connected to a arduino (preferably arduino nano).
Hope you can help.
Edit if found this keypad will i be able to program this one with a arduino?
link

Look for the keyword "IP65" in your searches.

I'm voting to close this question as off-topic because questions seeking recommendations for specific products or places to purchase them are off-topic as they are rarely useful to others and quickly obsolete. Instead, describe your situation and the specific problem you're trying to solve.

You can connect almost any keypad to an Arduino that does not have active circuitry (by active I mean the keypad has it's own MCU etc.), those with active circuitry might need some more work due to incompatible logic voltages or custom protocols.

@Avamander could you check out the keypad i just linked in my question? I think this one could work

It's an USB keyboard by default, Arduinos don't usually do USB. (It's also tad expensive, search more)

The membrane keyboard you have linked (first link) in your question should be water resistant, if not water proof.
We use something similar at my work. You can have the keypad stuck to the outside of the enclosure and then have a rubber seal (or silastic) sealing where the ribbon cable enters the enclosure.

You will notice that the ribbon cable pretty much exits the bottom of the keypad. The better ones to get, if you can find them, are the ones where the ribbon cable exits the keypad further away from the edge (see example image below). That way the adhesive backing of the keypad seals the cable entry into the enclosure.

As far as hooking it up to an Arduino - no problems at all. A 16 key matrix keyboard has 8 connections, 4 for each row and 4 for each column. Every time you press a key, the row and column are shorted together.

The way I would connect it up is to have the rows connected as inputs and the columns as outputs. One by one I would turn one of the columns on (HIGH) and see which input(s) are reading a HIGH. If it is I know that that key (row and column) is pressed. This method will handle multiple keys pressed at once.
There is an walk-through tutorial posted at instructables.com.
The more expensive keypad in your second link and this one both have the option of connecting by PS2. There is an Arduino page on connecting and controlling a PS2 keyboard here.

Thanks for the amazing answer but i would like to put this at the front of my house and i dislike the looks of it :). Thats why i found the more expensive one, now i was wondering if i could use that one on a arduino?

The more expensive one and this one  both have the option of connecting by PS2. http://playground.arduino.cc/Main/PS2Keyboard

Thank you! So every keypad with a ps2 connector "should" work?

"Should" is the right word. I have never tried it myself. Why not find an old PS2 computer keyboard and give it a try before you buy the keypad.

This one has a PS2 connector aswel and it has backlit:
https://www.aliexpress.com/item/Industrial-waterproof-metal-led-backlit-illuminated-keypads-with-12-keys/32812155017.html?spm=2114.40010208.4.6.MGManS

That keypad and the original metal one both have the line"Matrix output or standard USB/PS2 output  with controller". Looks like it has the matrix output as well. Worth a try!

I got it working! :) Now i'll buy the keypad thanks for everything!


text:
JSN-SR04T-2.0 with NodeMCU not starts after reset or reconnect usb power
I have bought a NodeMCU (1.0) and a JSN-SR04T waterproof ultrasonic sensor compatible with HC-SR04.
If I upload my program to NodeMCU it works but sometimes it measures a wrong distance - it is an another question, but it may connect to this question.
If I press the reset button my application not starts or if it is unplugged and plugged in to usb power it not starts.
If I unplug the ultrasonic sensor 3.3V and ground it starts.
It starts with the following code:
const int trigPin = D4;
const int echoPin = D3;

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

void setup() {

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input

  flashLed();
  Serial.begin(115200);
  flashLed();
  delay(10);

  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
  }
  Serial.println("");
  Serial.println("WiFi connected");

  server.begin();

  Serial.println("Web server running. Waiting for the ESP IP...");
  delay(10000);

  Serial.println(WiFi.localIP());

  digitalWrite(LED_BUILTIN, HIGH);

}

I have uploaded the full source code to github project:
https://github.com/kisdaniel/nodemcu-wif-http-HC-SR04/blob/master/HomeDashboardUltrasonicHttp.ino
Why it not starts?
UPDATE:
I have make a minimal version of code to reproduce the problem:
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(2000);
}

Wiring:
Node MCU 3.3V -  Vcc (ultrasonic sensor)
Node MCU GND  -  GND (ultrasonic sensor)
Node MCU D4   -  Trigger (ultrasonic sensor)
Node MCU D3   -  Echo (ultrasonic sensor)

Why it not starts?

Full source can by download from github you can try it, if you need a minimal version I can remove all unnecessary code to reproduce the problem.

This post saved my day! All Ultrasonic sensor codes around the internet use D3 for the Echo input, and this causes the NodeMCU not booting up always.

To enable ESP8266 firmware flashing GPIO0 pin must be pulled low
  before the device is reset. Conversely, for a normal boot, GPIO0 must
  be pulled high or floating.

The D3 pin is equivalent  GPIO0. For a normal boot, GPIO0 must be pulled high or floating while powering up or resetting the module. After that (normal boot), you can use the output for other purposes.
You can use a different output or try to use a pull-up resistor for the D3.

@Look Alterno If I add the following text will it be enough?: For a normal boot, GPIO0 must be pulled high or floating while powering up or resetting the module. After that (normal boot), you can use the output for other purposes.

If I connect the Echo to D2 it semms to be working. after reset.

This is the correct identification of the issue, but it's unlikely that adding a pullup resistor on D3/GPIO0 will help, as it's probably  being driven low actively.

This answer saved my day! All Ultrasonic sensor codes around the internet use D3 for the Echo input, and this causes the NodeMCU not booting up always.

I had the same problem. Eventually I worked out what was going wrong with the information at "Startup Guide for ESP8266 NodeMCU WeMos"
It explains -
"Using GPIO0 (D3), GPIO2 (D4) and GPIO15 (D8) can be bit tricky. There are certain reasons, for example, GPIO0 (D3) and GPIO2 (D4) are pulled HIGH (PULL-UP Resistor) for normal start up of ESP8266 while GPIO15 (D8) is pulled LOW (PULL-DOWN Resistor). It is recommended to not use these pins as INPUT."
The problem happens when one of the NodeMCU pins that goes HIGH in startup - D3 and D4 - is connected to the "ECHO" pin of the JSN-SR04T sensor while the supply and ground pins are connected. The "ECHO" pin has low impedance and reduces the voltage on either D3 or D4 to about 1 Volt. This prevents the NodeMCU from rebooting.
The problem doesn't happen if the D3 or D4 pin is connected to the "TRIGGER" pin of the JSN-SR04T sensor because it has high impedance and doesn't reduce the voltage on the NodeMCU pin connected to it.
This matches what the article I found recommended: using D3, D4 and D8 for OUTPUT is OK, but it is recommended to not use them for INPUT.


text:
Do I need Kalman Filter after I read DMP data on MPU6050?
In my project I need to use as noiseless as possible data from a MPU6050, I do have some nice DMP data, what will happen if I apply Kalman filter above it? Will I get more noiseless data? Or will it become unreliable anymore? Are there any benefits to do that ?

That would entirely depend on your filter - do a good job and you can remove noise and trivialities from the signal, but do a bad job and you can remove any meaning.   Keep in mind that micrco-machined accelerometers have limitations - integrating to a position is a loosing proposition.

The DMP data from the MPU6050 is already filtered, and while I have not expirimented with the DMP data much myself I believe it is pretty clean. If there is a calibration process you can do to improve it, that is probably worth expirimenting with, but you should not filter the values a second time.
You should figure out what your application's noise tolerance actually is before worrying about different filters. There are potential benefits to your own filter, I think knowing exactly how it performs in edge cases and being able to calibrating it to your specific problem could be beneficial; However, it could also end up being worse than the DMP. Don't forget that filter calculations can generally take a few milliseconds for an arduino to run that you don't have to worry about with the DMP.
If you do work on your own filter, you will need to turn off the DMP and filter the raw values. Look into complementary, mahoney, and madgwick filters as well as kalman, which is quite computationally expensive. Using an existing library or an implementation from an open source quadcopter project is probably most efficient. The math associated with kalman filters and 3d rotations gets very complicated very quickly.


text:
Arduino with NFC: Garbled Serial Monitor
I started working on a small programming project just for fun and I have got stuck. I have been using the following tutorial to make an Amiibo Music Box
Now using the libraries the tutorial suggested, I successfully uploaded the sketch to the device. However when I put an Amiibo or NFC card on top and look at the Serial Monitor, I get lots of garble and no sound.
¸ý×ÿòœy_ÿ#À–Yÿ›l°   _Yÿ8dÐa4’ÿ’Í�©ÿ›—Lµ›ú’áo°)h@’öþ8‚¤hþ:dÐ S4ê’ÉãÈô›l°É�°ò“ƒc¶ÿ™l±a“ùü8‚´hþ›l°É�´÷“ÅiØð
¶–t=Üý’ÉãÈôâd@àÉ‘ø8‚¤hþ
–e¼Õý’ÍÐPÿK¬ÀàÉ�ú8�·i™–e¼Õý8©Pòý’t=Üý“ƒf–ÿü’t=Ø9UY6þ›hX Cú’Í�©ÿ(l„±Ô_ü8‚´hþKìAÀò ý:‚´hþ8lÐaÓ4â’ÌcÈõ›hX Cú“ƒf–ÿKìEÀò ý’ÌiØõ8lÐaâtý“ƒ&–ÿè4@’âþ“ƒ&–ÿš’L²µšý8�·yÿ)l„úÈï’ÉãÈõ(l„±Ô_ü’ÍÙ:dÐ`S4ê2"´žþ)l„úÈï2"ßŸÿ›h±ÑªÛÖ’áoÞÿüÒt=Ø‘�&’ÿ�šA’âþ“ƒc¶þ›l±ÑªËÓ’Í�©ÿ8lÐaâtý’ÍÙ
––\5,ÿ’Í�©ÿè4@àâþ8©Pòý–t=Üý:‚´hþ
––t=Üý8‚´hþ8l€a¢tý’ÉãÈõš’L²µšýÜ,þÍ›þëÖÿÜ,þÜ,ÿÜ,ÿYÿ\ÿëòÿÜ,þêëòÿëòÿê4KÖÿ\ÿ]ÓÜ,ÿ\

I tried the card that comes with the kit and it does not work either. Has anyone got any idea why this has failed? I have put a link to the libraries and code I am using below.

https://github.com/ModusPwnin/Interactive-Amiibo-Stand
https://github.com/ModusPwnin/Interactive-Amiibo-Stand/blob/master/Amiibo%20Stand%20v3
https://github.com/adafruit/Adafruit_NFCShield_I2C
https://code.google.com/p/wavehc/

I am new to this but I want to understand why this is not working as well. Can anyone help me?


text:
Data changes when working with classes
When I pass an array, and it's len to the constructor of a class. I store the length, and access it later, it's value changes, seemingly at random.
#include "Arduino.h"

#define NUMSENSORS 2
const byte dataPins[] = {A5, A4};

class B {
    public:
        B(byte pin) { _pin = pin; }
        byte getPin() { return _pin; }
    private:
        byte _pin;
};

class A {
    public:
        A(const byte sensorPins[], int len) {
            Serial.print("provided len is: ");
            Serial.println(len);
            _len = len;
            Serial.print("Stored len is: ");
            Serial.println(_len);
            for (int i=0; i<len; i++) { myBarray[i] = new B(sensorPins[i]); }
        }
        B* myBarray[];
        int _len;
        void printLen() {
            Serial.print("Length is: ");
            Serial.println(_len);
        }
};

void setup() {
    Serial.begin(115200);
    A test(dataPins, NUMSENSORS);
    for (uint8_t i=0; i<10; i++) {
        test.printLen();
        delay(100);
    }
}

void loop() {
}

The value of len is fine in the constructor,  but is different when I call it in the function "getLen".
I feel as though it has something to do with pointers. Because if I comment out the for loop in the constructor of A, the value is correct.
Any help would be greatly appreciated, thanks in advance.

B* myBarray[]; has no size, and no memory allocated to it. Where do you think you are copying the data to?

I  thought that the memory would be allocated when I call the new B(sensorPins[i])... am I wrong? And why would that affect the value of A::_len in the later call?

No, B is allocated when you call new B(). The array is not allocated - ever - so it resides at address 0. Any writes to it will overwrite any other variables that have been allocated in that area, such as A.

Okay, fair enough. So how would I fix it? Sorry, but I am fairly new to c++

Either pre-allocate it with a fixed (maximum) size, or use malloc() to allocate the right amount of bytes to the array - that is, _len * sizeof(B) bytes.

Forcing a max length of the array worked! Thanks a lot. I'm going to have to look at malloc () to figure it out. so I can dynamically allocate memory.

There seems to be something missing here. What is the intention of the A and B class? They actually do no add anything as all the info you are using is in the dataPins vector and NUMSENSORS.

Let us do this with a template class and avoid malloc, etc.
#define membersof(x) (sizeof(x) / sizeof(x[0]))

const byte dataPins[] = { A5, A4 };

class B {
public:
  byte getPin() { return (_pin); }
  void setPin(byte pin) { _pin = pin; }
private:
  byte _pin;
};

template<unsigned len>
class A {
public:
  A(const byte sensorPins[]) {
    for (unsigned i = 0; i < len; i++)
      _vec[i].setPin(sensorPins[i]);
  }
  unsigned getLen() { return (len); }
  B* getB(unsigned ix) { return (ix < len ? &_vec[ix] : NULL); }

private:
  B _vec[len];
};

void setup() {
  Serial.begin(115200);
  A<membersof(dataPins)> test(dataPins);
  unsigned len = test.getLen();
  Serial.print(F("test.getLen()="));
  Serial.println(len);
  for (unsigned i = 0; i < len; i++) {
    B* bp = test.getB(i);
    Serial.print(F("test::B["));
    Serial.print(i);
    Serial.print(F("].getPin()="));
    Serial.println(bp->getPin());
  }
}

void loop() {
}

Cheers!


text:
ArduinoJSON define as extern
My sketch contains 2 .h files. one defines
on 1st .h file:
#define JSON_SIZE_IOT 400
#define JSON_SIZE_SKETCH 300
StaticJsonDocument<JSON_SIZE_IOT> paramJSON;
StaticJsonDocument<JSON_SIZE_SKETCH> sketchJSON;

and other need to define paramJSON and sketchJSON as extern
on 2nd .h file:
extern JsonDocument paramJSON;
extern JsonDocument paramJSON;

but I get this error:
error: conflicting declaration 'ArduinoJson6172_91::StaticJsonDocument<400u> paramJSON'
 StaticJsonDocument<JSON_SIZE_IOT> paramJSON;

....
: previous declaration as 'ArduinoJson6172_91::JsonDocument paramJSON'
 extern JsonDocument paramJSON;

please look at the code snippets that you posted ... the problem appears to be obvious ... the copy'n'paste bug strikes again

@jsotola do you mean JsonDocument instead StaticJsonDocument? it does not work either way

no ... you made a duplicate declaration

@jsotola See edit which code snippet belong to which .h file ( unless I don't understand why it is a duplicate )

don't do variable definitions in h file which is included in multiple translation units

@Juraj I understand what you say, it can be done, but it is very not clear way. Does it mean that it is impossible to do so ?

a variable definition should always be in cpp. in h only if you know what you are doing. but in to extern: it must be the same type including the template types.

@Juraj Thank you. My .h file sums each functionality used in sketch. BTW, there is no .cpp in my case, only .ino and .h's. How would you have done it if there was a .cpp file ?

then put it in ino or add a cpp file

For an extern the whole definition has to match the "master" definition.
So if you have:
StaticJsonDocument<JSON_SIZE_IOT> paramJSON;

then you extern has to be:
extern StaticJsonDocument<JSON_SIZE_IOT> paramJSON;

Of course you have to make sure your JSON_SIZE_IOT is the same for both - so it's best if that comes from a common source.
This is known as explicit instantiation declaration and you can read more about it in the Class template C++ reference.

Doesn't StaticJsonDocument a template ? that is why I used JsonDocument . Since JSON_SIZE_IOT defined using #define - how can I use it? ( pre-processor won't pass extern)

@Guy.D You can't extern to a different type. If you want to have something else then give yourself a pointer to it and do a cast to that pre-defined object.


text:
ESP32 seconds from epoch
When using ESP8266 - getting seconds from epoch is done using
NTP.begin(NTPserver, 2, true);
delay(delay_tries);
time_t t = now();

while t stores amount of seconds from 1-1-1970.
When trying to do the same, using ESP32 - I cant get that numeric representation.
code below is from ESP32 example- updating time using NTP server ( process is done correct ). BUT when using now() yields 1970, as if NTP update has never occured.
How can I get time from Epoch ?
#include <WiFi.h>
#include "time.h"
#include <TimeLib.h>    <------- Added to original Code

const char* ssid       = "YOUR_SSID";
const char* password   = "YOUR_PASS";

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;

void printLocalTime()
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

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

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println(" CONNECTED");

  //init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  printLocalTime();

  //disconnect WiFi as it's no longer needed
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
}

void loop()
{
  delay(1000);
  printLocalTime();
  Serial.println(now());   <-------- Added to original code
}

where is now() defined or even used in the code you posted?

Does your code output "Failed to obtain time"?

try time(nullptr) instead of now() - since now() is not even a valid function in the code you posted

you can use the NTP library on ESP32 and you can use the SDK time functions on esp8266 too

@JaromandaX - sorry, now with 2 additional line to original code

@Juraj - Also with #include <NTPClient.h> and timeClient.begin();     timeClient.setTimeOffset(3600); yeilds the same result ( time is updated, but cant get epoch )\

@Guy.D - just because you added now() to the code you've shown, doesn't make it valid (if I try to use now() in ESP32 code, it doesn't even compile :p

to return 'epoch' seconds there is a function time in time.h
time_t now;
time(&now);

time_t is defined as long
this time is retrieved by the ESP32 SDK from NTP servers configured with  ESP32 Arduino function configTime
EDIT: it is the standard C time() function

since time also returns a time_t you can use it like now() ... i.e.  time(nullptr);


text:
Error using `NtpClientLib.h`
Since Core of ESP8266 upgraded to v.3.0 (now it is 3.0.2), I encounter errors using this library.
First, the deprecation of byte to uint8 (hoped that an upgrade of NTP lib to 3.0.2 beta will solve it ), but now even using library's built in example file fails, show the same message regarding byte error.
Is there a workaround ?
In file included from /home/guy/Documents/git/Arduino/libraries/NtpClientLib/examples/NTPClientESP8266/NTPClientESP8266.ino:38:
/home/guy/Documents/git/Arduino/libraries/NtpClientLib/src/NtpClientLib.h:501:32: error: reference to 'byte' is ambiguous
  501 |     bool summertime (int year, byte month, byte day, byte hour, byte weekday, byte tzHours);
      |                                ^~~~
In file included from /home/guy/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/xtensa-lx106-elf/include/c++/10.3.0/cmath:42,
                 from /home/guy/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/xtensa-lx106-elf/include/c++/10.3.0/math.h:36,
                 from /home/guy/.arduino15/packages/esp8266/hardware/esp8266/3.0.2/cores/esp8266/Arduino.h:34,
                 from sketch/NTPClientESP8266.ino.cpp:1:

EDIT 1 :: VERSIONS

I just compiled that example fine no problem with 3.0.2. Maybe there's something broken about your Arduino / ESP8266 installation.

Or maybe your libraries are out of date...?

@Majenko - see installed version, IDE, and Example sktech fails

Don't use the library manager to install libraries. Download it direct from Github. You can pretty much guarantee that whatever is in the library manager will be out of date.

@Majenko - Amazing!! You were right. I delted all NTPClient libraries, and reinstalled only from github... and its OK now. Thnk you

The esp8266 Arduino 3 has breaking changes so library authors need to adjust their libraries to this changes. Check the repository of the library for the fixes.
The NtpClient library was marked as deprecated by the author. The reason was that there is a better way to work with NTP on ESP. Now the library was 'restarted' as an alternative to SDK functions because the author solved microseconds accuracy.
If you don't need microseconds accuracy, you don't need to use Arduino NtpClient library on esp8266 or esp32. The Espressif SDK have support to get the NTP time to internal RTC.
Both ESP Arduino cores have examples for NTP. For esp8266 it is the esp8266/NTP-TZ-DST example.
The NTP part should be in setup()
configTime(TIME_ZONE, "pool.ntp.org");

TIME_ZONE should be value from TZ_ constants from TZ.h, for example I have
#include <TZ.h>
#define TIME_ZONE TZ_Europe_Bratislava

The SDK will keep the time with the internal RTC of the ESP and adjust it periodically from NTP server.
You can get the esp8266 RTC time time with
time_t t = time(nullptr); // epoch
struct tm *tm = localtime(&t);
uint8_t minute = tm->tm_min;
uint8_t hour = tm->tm_hour;

if you want to wait in setup() until the time is retrieved you can use
  time_t now = time(nullptr);
  while (now < SECS_YR_2000) {
    delay(100);
    now = time(nullptr);
  }

Firstly, thank you very much. Second, is there a way to update daylight saving automatically ?

@Guy.D, it adjusts for day light saving time automatically. I built an alarm clock with esp8266 and these functions. https://github.com/jandrassy/SunriseClock

Tough your answer avoids the use of the library asked, but to mark it as an Answer, I need you to reff to Majenko's answer, that actually solved it.

@Guy.D, I updated the answer


text:
How to run TCP socket server on Arduino Uno WiFi?
2017-03-23 update
I still don't know why it works so well on Yún. Maybe it has a better antenna? Anyway, I've returned Uno WiFi and got a SparkFun ESP32 Thing. Unfortunately, it has the same problem as Uno WiFi. To fix it I've switched from TCP to UDP. It made a world of difference: servos are very responsive now. UDP is OK for my use case: I can send the state of the whole system in each message and lost messages or messages arriving out of order are not a big problem.
Original question
I want to control servos over WiFi with high precision and low latency. I managed to achieve this using TCP socket communication with Arduino Yún. I want to repeat this with Arduino Uno WiFi, but I can't find example code for socket communication. I connected to the board using telnet but servo output is jerky — as if there was a delay after each servo.write call.
How can I run a TCP socket server on Arduino Uno WiFi in a way that
allows for fast low latency communication?
Longer description
I experimented with controlling servos over WiFi using an Arduino Yún board that I borrowed from a friend. I connected a MG92B servo to pin 9, 5V, and GND. I start a TCP socket server on the Arduino and send angle values from a Python script dozens of times per second. It works smoothly.
Encouraged by this experiment I bought my own Arduino. I chose Arduino Uno WiFi (developer edition) because, unlike Yún, it's compatible with shields. Unfortunately I can't find example code for socket communication. I found an example that uses telnet, so I adapted it and used it with my Python script. Sadly, the servo movement is jerky — as if there was a delay after each servo.write call.
Below is a video showing both boards running two sketches: "no network movement" and "network movement".
Video

Code
I attach all code I used.
Arduino oscillation test with no remote control
I use this code to test that the servo is working correctly.  It works on both Arduino Yún and Arduino Uno WiFi.
#include <Servo.h>

const int servoPin = 9;
Servo servo;

void setup() {
    servo.attach(servoPin);
}

void loop() {
    // configure movement
    int angleMin = 15;
    int angleMax = 165;
    int interval = 30;

    // oscillate between `angle_min` and `angle_max`
    int angle = angleMin;
    for (int i = 0; i < 2; i = (i + 1) % 2) {
        int sign = pow(-1, i);
        for (int j = 0; j < angleMax - angleMin; j += 1) {
            angle += sign;
            servo.write(angle);
            delay(interval);
        }
    }
}

Arduino Uno WiFi reading from telnet
This is jerky.
#include <Servo.h>
#include <UnoWiFiDevEd.h>

const int servoPin = 9;
Servo servo;

void setup() {
    Wifi.begin();
    servo.attach(servoPin);
}

void loop() {
    while (Wifi.available()) {
        servo.write(Wifi.read());
    }
}

Arduino Yún reading from socket
This is smooth.
#include <Bridge.h>
#include <Servo.h>
#include <YunClient.h>
#include <YunServer.h>

// configure
const int port = 5555;
const int servoPin = 9;

// listen on given port
Servo servo;
YunServer server(port);

void setup() {
    // set up servo
    servo.attach(servoPin);

    // start server
    Bridge.begin();
    server.noListenOnLocalhost();
    server.begin();
}

void loop() {
    YunClient client = server.accept();
    byte angle;

    if (client) {
        while (client.connected()) {
            angle = client.read();
            if (angle != 255) {
                servo.write(angle);
            }
        }

        client.stop();
    }

    Serial.println("waiting for client");
    delay(1000);
}

Python writing to socket
This is the network equivalent of the Arduino oscillation test.  Works both with Yún (port 5555) and Uno (port 23).
import socket
from time import sleep

# connect
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('192.168.240.1', 5555))  # use 5555 for Yun and 23 for Uno

# configure movement
angle_min = 15
angle_max = 165
interval = 30 / 1e3

# oscillate between `angle_min` and `angle_max`
while True:
    angle = angle_min
    for sign in [1, -1]:
        for _ in range(angle_max - angle_min):
            angle += sign
            client.send(bytearray([angle]))
            sleep(interval)

I suspect these delays are caused by TCP buffering.
For some theory on this sort of thing, perhaps read about Nagle's Algorithm which covers some of the issues with small packet buffering.  It seems reasonable to me that lower-power and/or lower-speed (or even "just different") boards would use more aggressive buffering.
TCP uses all manner of buffering and checks to ensure guaranteed delivery of data (or reported error), whereas UDP does not.
If UDP is working for you, perhaps you may want to include some of your own error tracking in the comms protocol, unless missing the odd packet is not an issue to your control system.


text:
INPUT_PULLUP not work for D8 in my NodeMCU v3
I changed my arduino NodeMCU application pin mode to use INPUT_PULLUP mode instead of INPUT. D8 input pin is not working as expected, I is always in LOW even the button is pressed or not.
I have 3 input pins (D2, D7, D8), when I changed to internal pull up resistor, I removed each external resistors from input and changed the circuit accourding to this: https://www.arduino.cc/en/Tutorial/InputPullupSerial
D2 and D7 works well, but D8 is not. I checked with a volage between GND and pins:

when button on D2, D7 is not pressed: 2.95 - 3 V
when button on D8 is not pressed: 0.8 V
when button on D2, D7, D8 is pressed: 0V (as expected)

You can see my code in github:
https://github.com/kisdaniel/HomeDashboardGarageDoorOpener

Pin D8 is esp8266 pin 15. This pin is one of the boot configuration pins and for use on a dev board, it must be pulled down at boot. So the NodeMcu has a pull down circuit on this pin and internal pullup is weaker then this external pulldown.


text:
Having problems with I2C - Slave is receiving "b ~ ,,,"
so I'm facing a pretty large problem. I'm experimenting with I2C and using one Arduino that acts as a countdown timer to send the current reading on the timer to another Arduino. I'm pretty new to electronics in general so bear with me.
The way the countdown timer works is it stores the time as a String, and uses substring and toInt() to adjust the timer.
I know that with I2C you can only send some data, Strings not included, so I tried converting the String to an array of characters using toCharArray(). My conversion seems to be working well, as I have tested it with the Serial.println() and it displays the time correctly.
Therefore, I am convinced the problem lies with the Slave code. I'm not sure how to set up the Slave Arduino to receive the actual time. Below, I've pasted links to the code of both the Master and the Slave respectively.
Master: https://pastebin.com/AFjTDZB7
Slave: https://pastebin.com/viNGWn9c
How should I change my slave code so everything works?
Also, when I changed the datatype of "time" in the Slave code from char* to int, all I got in the Serial Monitor was 48. Weird.
Would really appreciate any help and guidance cause I'm pretty stuck. All the tutorials I find online are pretty complicated.
Thanks!
Master Code:
#include < Wire.h >
String time = "10:11";
boolean doubleDigits = false;

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

void loop() {
  Serial.println(time);
  sendTime(time);
  int First2 = time.substring(0, 2).toInt();
  if (First2 > 9) {
    doubleDigits = true;
  }

  int Last2 = time.substring(3).toInt();
  if ((time.substring(3) == "00") && (time != "00:00")) {
    First2 = First2 - 1;
    Last2 = 59;
    if (doubleDigits == false) {
      time = "0" + String(First2) + ":" + String(Last2);
    } else {
      time = String(First2) + ":" + String(Last2);
    }
  } else if (time != "00:00") {
    Last2 = Last2 - 1;
    if (Last2 < 10) {
      if (doubleDigits == false) {
        time = "0" + String(First2) + ":0" + String(Last2);
      } else {
        time = String(First2) + ":0" + String(Last2);
      }
    } else {
      if (doubleDigits == false) {
        time = "0" + String(First2) + ":" + String(Last2);
      } else {
        time = String(First2) + ":" + String(Last2);
      }
    }
  }
  if (time.substring(1, 2) == ":") {
    time = "0" + time;
  }
  delay(1000);
}

void sendTime(String time) {
  Wire.beginTransmission(9); //transmit to device 9
  char buffer[32];
  time.toCharArray(buffer, 32);
  Wire.write(buffer);
  Serial.println(buffer);
  Wire.endTransmission(); //stops transmitting
}

//master

Slave Code:
#include <Wire.h>
char* time;

void setup() {
  Wire.begin(9); //start as slave on address 9
  Wire.onReceive(receiveEvent); //attach a function to trigger when something is received
  Serial.begin(9600);
}

void receiveEvent(int bytes) {
  time = Wire.read(); //read one character from the I2C

}

void loop() {
  Serial.println(time);
  delay(1000);
}

//slave

Edit: added code

Can't see the code, can't answer the question.  I would expect 48 if you changed a char* of the time to an int without understanding what you were doing.  48 is ASCII 0.

@CodeGorilla, alright, added the code to the main post. Can you take a look please? Would really appreciate it.

You still need to fix sendTime in the master code, but...

In the slave code.  receiveEvent takes a number of bytes as a parameter, presumably you are supposed to read this many bytes, can you call read with that number?  Even if you did you are reading to a char pointer, which will cause issues unless read is allocating the memory, which you should then be releasing.  Basically you have a couple of issues here and you need to look at them.
In the Master code. sendTime doesn't look right.  I would expect you to have to send a certain number of bytes using the Write function.  You are just sending 32 chars, the fact you are sending signed char's rather than unsigned char's shouldn't be an issue (but its technically incorrect).
I don't really understand what you are trying to achieve in the rest of loop, annotation would help :)

OK, If you take this as a new version for the slave you should be able to see it working.  It might not be 100%, but you should get something.  (I haven't even compiled this code, so you might have to sort out a few bugs)
#include <Wire.h>

#define MaxTimeBufferSize (33)
#define MaxReadSize  (MaxTimeBufferSize - 1)
char timeBuffer[MaxTimeBufferSize];

void setup()
{
  Serial.begin(9600);  // Init first so you can see any issues during setup.
  Wire.begin(9); //start as slave on address 9
  Wire.onReceive(receiveEvent); //attach a function to trigger when something is received
}

// Assumes the bytes are actually printable ASCII characters.
void receiveEvent(int bytes)
{
  const int bytesToRead = (bytes < MaxReadSize) ? bytes : MaxReadSize;
  for (int index = 0; index < bytesToRead; ++index)
  {
     timeBuffer[index] = Wire.read(); //read one character from the I2C
  }
  timeBuffer[bytesToRead] = 0; // Null terminate the bytes (so they will print as a string)
}

void loop()
{
  if (timeBuffer[0])  // Only print the buffer if there is new data
  {
    Serial.println(timeBuffer); // The buffer is NULL terminated.
    timeBuffer[0] = 0;  // Stop the buffer  printing again.
  }
  delay(1000);
}

Hey, thanks for your reply, @CodeGorilla. I realize that Slave contains a problem, I just don't know how to fix it. That's why I'm asking for help.
Also, for the Master code, all it does is act as a countdown clock, by maintaining a String called "time" and uses some toInt(), concatenation and toString() functions to change the value of time every second and send that value to the Slave.

works like a charm! Thank you, really appreciate it!

@A.Lordos, the code by @CodeGorilla shows how to read more than one byte as a Slave. It stores the received data in a buffer, and that buffer is printed to the serial monitor to show it.
May I make a suggestion: start all over and do it right.
Forget the String objects and use a integer (int, or unsigned or unsigned long) as a countdown counter for the seconds. Count the seconds, nothing else.
When you need to display the counter, then you can make it in the format of "10:11". But only to display it, the base of the sketch is still that single variable for the seconds.
When you need to transmit the counter to the Slave, send the integer variable as binary data (the integer itself), not a text string.
In the Arduino examples, a text is transferred over the I2C bus. That is however almost never done. In most cases binary data of variables is transferred over I2C.
This is a good tutorial: Nick Gammon's Tutorial about I2C