text:
ESP8266 stops working when I use 2x static const char(PROGMEM)
*Sdk version: 2.2.2-dev(5ab15d1)
*Core Version: 2_6_1
This is the error returned:
Exception 3: LoadStoreError: Processor internal physical address or data error during load or store PC: 0x4000bf64 EXCVADDR: 0x4024e963
Decoding stack results
0x4020175d: HTML1(String) at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266/WString.h line 128
0x40238c26: umm_info(void*, int) at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\umm_malloc/umm_info.c line 164
0x40100278: millis() at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\core_esp8266_wiring.cpp line 188
0x40238c26: umm_info(void*, int) at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\umm_malloc/umm_info.c line 164
0x4020af74: String::copy(char const*, unsigned int) at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\WString.cpp line 214
0x40201a3c:

Code:
static const char HTML1[] PROGMEM = R"=====(
<!DOCTYPE HTML><html><head>
<meta charset='utf-8' name='viewport' content='width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0'>
)=====";

static const char HTML2[] PROGMEM = R"=====(
<button type='button' onclick='sendData(2)'>Test2</button>
)=====";

String html_return = HTML1;
html_return += "<button type='button' onclick='sendData(1)'>Test</button>";
Serial.println("Before Second Const Char");
html_return += HTML2; //<< ESP stops working here

If I remove static declaration, it doesn't compile in local function. I've tried to declare HTML1[] and HTML2[] out of the function without static declaration, but the error is the same.

I still have memory, I'm only using (42%) of 81Kbytes.
So I'm working without PROGMEM and it works like bellow:
String HTML2 = R"=====( <button type='button' onclick='sendData(2)'>Test2</button> )=====";

See Guide to PROGMEM on ESP8266 and Arduino IDE.
Since you put your char array into PROGMEM, special functions must be used to load it from flash into RAM; so to load it into a String object, the FlashHelper class must be used. You can simply use the macro FPSTR(progmem_ptr).
#include <Arduino.h>

void setup() {
    Serial.begin(115200);
    Serial.println("\nStart firmware");

    static const char HTML1[] PROGMEM = R"=====(
    <!DOCTYPE HTML><html><head>
    <meta charset='utf-8' name='viewport' content='width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0'>
    )=====";

    static const char HTML2[] PROGMEM = R"=====(
    <button type='button' onclick='sendData(2)'>Test2</button>
    )=====";

    String html_return = HTML1;
    html_return += "<button type='button' onclick='sendData(1)'>Test</button>";
    Serial.println("Before Second Const Char");
    //html_return += HTML2; //crashes
    html_return += FPSTR(HTML2); //works
    Serial.println("Result");
    Serial.println(html_return);
}

void loop() {

}

Outputs
Start firmware
Before Second Const Char
Result

        <!DOCTYPE HTML><html><head>
        <meta charset='utf-8' name='viewport' content='width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0'>
        <button type='button' onclick='sendData(1)'>Test</button>
        <button type='button' onclick='sendData(2)'>Test2</button>

FPSTR macro casts the type and so forces the use of the right + operator for a PROGMEM string. It is the same as html_return += F("some text stored in progmem");

Dear Maximilian, thank you for the detailed answer, works very well. Saved my ESP memory!


text:
Radio receiver: deep sleep when no byte arrives, and wake up when a byte arrives?
This code works to listen for bytes via radio (with a 433 Mhz receiver module) with the Manchester library and Manchester code, and do an action when certain bytes are received:
#include "Manchester.h"

void setup() {
  pinMode(3, INPUT);
  man.setupReceive(3, MAN_1200);
  man.beginReceive();
}

void loop() {
  if (man.receiveComplete()) {
    uint16_t m = man.getMessage();
    man.beginReceive();   // start listening for next message
    // do something with m
  }
}

But it requires to have the Arduino / ATtiny / ATmega / MCU constantly running.
Question: is there a way to put the ATtiny on deep sleep mode (to get < 1 uA consumption) and wake-up only when a byte arrives via radio?
I know how to do this with an interrupt or "pin change interrupt", but here with radio library Manchester, it's probably more complicated. How to do it?
In this case it's probably going to be more complicated than just:
sleep_enable();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_cpu();

how much power does the radio consume?

The attiny itself consumes 5ma or 1ma at 1mhz and this is too much to run on batteries; thus I'd like to use deep sleep mode if possible.

I couldn't do that with my 433Mhz module. It would constantly trigger my interrupt pin, even if there wasn't any being send by me. There was enough noise/interference on the 433Mhz, that my Arduino would have no time to sleep.

@Gerben Yes I thought this would be the problem. Indeed PCINT are bit-based (on/off), and reading a message Manchester-encoded is higher level (bytes, etc.), so I really wonder how to do this properly!

source: Stack Exchange

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

sort: votes


text:
How to Use Function Code 6 Modbus RTU library
I'm trying to communicate with a temperature controller using Modbus RTU.
I used this Arduino library.
I was able to read PV(current temperature value) using below code. It uses Function code 4.
I want to set SV value(Set Value) using Function code 6
I replaced telegram.u8fct = 0x04; to telegram.u8fct = 0x06; and telegram.u16RegAdd = 0x03E8; to relevant address for SV. But, I couldn't get success.
How can I implement Function Code 6 in this library ?
Code for read PV as below. Its working properly.
    #include <ModbusRtu.h>

    // data array for modbus network sharing
    uint16_t au16data[16];
    uint8_t u8state;

    /**
        Modbus object declaration
        u8id : node id = 0 for master, = 1..247 for slave
        u8serno : serial port (use 0 for Serial)
        u8txenpin : 0 for RS-232 and USB-FTDI
                     or any pin number > 1 for RS-485
    */
    //TRANSMISSION CONTROL PIN - 8
    //HADWARE SERIAL NUMBER - 2
    Modbus master(0, 2, 8); // this is master and RS-232 or USB-FTDI

    /*
       This is an structe which contains a query to an slave device
    */
    modbus_t telegram;

    unsigned long u32wait;

    void setup() {
      Serial.begin(9600);
      master.begin(9600); // baud-rate at 9600
      master.setTimeOut( 2000 ); // if there is no answer in 2000 ms, roll over
      u32wait = millis() + 1000;
      u8state = 0;
    }

    void loop() {
      switch ( u8state ) {
        case 0:
          if (millis() > u32wait) u8state++; // wait state
          break;
        case 1:
          telegram.u8id = 0x01; // slave address
          telegram.u8fct = 0x04; // function code (this one is registers read)
          telegram.u16RegAdd = 0x03E8; // start address in slave [CHANNEL 1 PV]
          telegram.u16CoilsNo = 0x01; // number of elements (coils or registers) to read
          telegram.au16reg = au16data; // pointer to a memory array in the Arduino

          master.query( telegram ); // send query (only once)
          u8state++;
          break;
        case 2:
          master.poll(); // check incoming messages
          if (master.getState() == COM_IDLE) {
            u8state = 0;
            u32wait = millis() + 100;
            Serial.println(au16data[0]);//PRINT TEMPARATURE VALUE
          }
          break;
      }
    }

I managed to change SV value.
According to the library, when using function code 6, It get sending data(temperature value) from au16regs[0]as below piece of code of library file.
Need to setup that value before requesting.
(ModbusRtu.h - line number 601)
case MB_FC_WRITE_REGISTER: //if cunction code 6
    au8Buffer[ NB_HI ]      = highByte(au16regs[0]);
    au8Buffer[ NB_LO ]      = lowByte(au16regs[0]);

It's OK to accept you own answer as the solution to the problem.

@VE7JRO yes. Its the ansawer to question. But, you will have to face a problem if you use this code in program with other functions.

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


text:
MP3 File through ARDUINO
Hey question is that it is possible to play MP3 file in arduino without changing it into .wav file if possible ,then your suggestions are welcome
Thanks

Yes, with an MP3 shield.

The UNO doesn't have the processing power to decode MP3.

Ok i will try for this ,thanks for your response :)

This little device is really good and easy to set up.
https://www.dfrobot.com/product-1121.html
You can use a pin and set it to ground with a resistor between to change songs if you don't need something fancy.


text:
Position Feedback for Stepper Motor
I want to rotate a gearwheel with a stepper motor. While Arduino is on everything is well.
My gearwheel transfer its power to a gear worm. The worm will go 10th cm and back repeatedly. When I cut the power, Stepper Motor stops where its last step and position. When the power is on Stepper starts from last position but steps starts from the first step.
Assume that 2038 steps are rotating the Motor one revolution. For example, when 1500 step pass and power cut. Worm is on 6th cm now. And the power is on. Stepper is working from 6th cm and is going 2038 steps. Now it is on 16th cm.
If I use servo, when the power is on, I can write the motor to the 0 position. But I have to use stepper motor. How can I fix this?
Stepper Motor: 28 BYJ 48
Driver: ULN2003A
The cod is here;
int State;
int Wait;

void setup() {

  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);

  digitalWrite(8,LOW);
  digitalWrite(9,LOW);
  digitalWrite(10,LOW);
  digitalWrite(11,LOW);
  State = 8;
  Wait = 2;
}

void loop() {

  turnRight(2038);
  delay(1000);
  turnLeft(2038);
  delay(1000);

  }

void turnRight(int Step) {
    for (int i = 0; i < Step ; i++){
      digitalWrite(State,HIGH);
      delay(Wait);
      digitalWrite(State,LOW);
      IncreaseState();
    }
}

void IncreaseState() {
  State++;
  if (State==12){
    State=8;
  }
}

void turnLeft(int Step) {
for (int i = 0; i < Step ; i++){
      digitalWrite(State,HIGH);
      delay(Wait);
      digitalWrite(State,LOW);
      DecreaseState();
    }

}

void DecreaseState() {
  State--;
  if(State==7){
    State=11;
  }
}

There are multiple ways to to this. The easiest and most commonly used way is to use a limit switch as home position sensor. At startup the device will first drive the motor in the direction of the limit switch, until the switch get's activated. Now the the absolute position on this axis is known and you can go on from there. (CNC machines and 3D printers mostly work that way. Often they retract again from the limit switch and approach the switch again with less speed, to increase the accuracy). For this you just need a micro switch on the axis and connect it to one input pin. In setup() you are driving the stepper motor in the direction of the limit switch, until it gets activated. Then you are on position zero and can go on with your sketch.
A more difficult way is to introduce a measurement of position into your device. A servo incorporates a potentiometer connected to the axis. By measuring the voltage on this potentiometer (it is basically a voltage divider), the servos electronics can always know, where it currently is. There are also fader potentiometers, where you don't rotate a knob, but you slide a fader over a linear rail. You might find a fader potentiometer, that fits your scale (10cm is not that much, there might be some).
Or you could save the current position to a non-volatile memory (like EEPROM) and retrieve it, when you start up. But since a power-cut during writing of the position may corrupt the data, you would have to go a more complex way. Something like sensing, that the power was cut, providing the Arduino with power through a big capacitor, so that, when it senses power loss, it still has enough time to write the current position to a non-volatile memory. (This is also better for the EEPROM, than continuously writing to it, since EEPROM has limited write cycles).
All in all I would suggest using the first mentioned method (limit switch). It is used in many devices for a reason. Though it depends on your exact project requirements.

Thanks for your reply, I'll try limit switch I think.

Another answer chrism didn't mention is to use an "absolute position rotary encoder". It's a device that outputs a bit pattern using "gray code" or "grays binary" that tells you the position of the shaft. The more bits in the encoder, the more precisely you can measure the position. The "gray code" bit pattern enables you to read the changing position without false reading due to contact/sensor bounce.
However, if you want to uniquely detect 2038 separate steps you'd need a 12 bit rotary encoder, which would be a little expensive and take a lot of interface pins.

Thanks for yor adding. I used Limit Switch and worked well for now. I'll try your idea for improvement in another project.


text:
Stepper motor only rotates once in a loop?
I am quite new to this , I am trying to program two motors , aStepper and bStepper.
I want the program to rotate aStepper then rotate the bStepper and when that is done rotate aStepper again , and then repeat.
The first iteration works fine.However, it only does the loop once and the bStepper doesn't rotate again.
Am I doing something wrong with the loop?
(aStepper is the UNIPOLAR 28BYJ-48 connected to its driver , and bStepper is a Nema 17 connected to A4988)
#include <AccelStepper.h>
#include <Stepper.h>

#define StepsPerRotation 2038

#define dirPin 2
#define stepPin 3
#define motorInterfaceType 1

AccelStepper bStepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
Stepper aStepper(StepsPerRotation, 8, 10, 9, 11);

void setup() {

  bStepper.setMaxSpeed(200);
  bStepper.setAcceleration(30);
}

 void loop() {

   aStepper.setSpeed(20);
   aStepper.step(1016);

   bStepper.moveTo(-6000);
   bStepper.runToPosition();

   aStepper.setSpeed(20);
   aStepper.step(-1016);
}

Thank you in advance

How should bStepper move again after the first time? You directed it to go to position -6000, so it will go to -6000 on the first run. On the second it already is there, so further movement

Oh , I thought after it completes the loop it would just run again. How can i better approach this? with bstepper.runSpeed(); instead?


text:
How to prevent counter increment when holding the button
I am a newbie and also a noobie. Kindly assist this poor boy over here.
I am looking for a way to increment a variable by one each time a button is pressed. Current approach is the following :
void buttonLoop() {
  int win = 0;
  while (win ==0) {
  display.setCursor(0, 0);
  //getButtons() function can be used to test if any button is pressed, or used like:
  //getButtons(TSButtonUpperLeft) to test a particular button, or even like:
  //getButtons(TSButtonUpperLeft|TSButtonUpperRight) to test multiple buttons
  //results are flipped as you would expect when setFlip(true)
  if (display.getButtons(TSButtonUpperLeft)) {
    display.println("Pressed!");
    score++;
    updateScore();
  } else {
    display.println("          ");
  }
  display.setCursor(0, 54);
  if (display.getButtons(TSButtonLowerLeft)) {
    display.println("Pressed!");
    score++;
    updateScore();
  } else {
    display.println("          ");
  }
  display.setCursor(95 - display.getPrintWidth("Pressed!"), 0);
  if (display.getButtons(TSButtonUpperRight)) {
    display.println("Pressed!");
    score++;
    updateScore();
  } else {
    display.println("          ");
  }
  display.setCursor(95 - display.getPrintWidth("Pressed!"), 54);
  if (display.getButtons(TSButtonLowerRight)) {
    display.println("Pressed!");
    score++;
    updateScore();
  } else {
    display.println("          ");
  }
}
}

In my case, the counter will keep increasing if I do not let go of the button. How do I make it so that the counter will only increase by 1 even if i continue holding onto the button.
Thank you for all the kind souls in this society :)

Look for the Bounce2 library in the IDE library manager.

check to see if the button was released before allowing the counter to increment again

See my answer in this thread:
How to connect Big Dome Button with arduino
That thread explains how to wire up a switch and write code that increments a counter each time a button is pressed.
The bits you care about:
Connect one lead of the switch to a digital input, and the other lead to ground.
Then set your switch pin to INPUT_PULLUP mode. Now your switch will read HIGH until it's pressed, then it will read LOW.
create a variable at the top of your code called buttonState:
byte buttonState = HIGH;

Also define an unsigned long variable nextReadMillis:
unsigned long nextReadMillis = 0;

and a pressCount variable:
unsigned int pressCount = 0;

And define a debounceTime:
#define debounceTime 50

In your loop, do something like this:
void loop() {
    //Get the new millis(value)
    unsigned long newMillis = millis();

    //only look at the new button value if enough time has elapsed.
    if (newMillis >= nextReadMillis) {
       byte newButtonState = digitalRead(buttonPin);

       //Only do something if the button state has changed
       if (buttonState != newButtonState) {
          buttonState = newButtonState;
          nextReadMillis = newMillis + debounceTime;
          //If the button is now in the pressed (LOW) state, increment the count
          if (buttonState == LOW) {
              pressCount++;
          }
       }
    }
}

That's pseudo-code. It likely has syntax errors. It's not meant to be copy/pasted. Use it as a guide for your project.
The code using millis() is a version of "software debouncing." Electrical switches tend to "jitter" or "bounce" between their on and off states very rapidly when they are first pressed/released. By only checking for state changes after a brief delay, you ignore the jitter in the readings.
You can adjust the value of debounceTime up or down a little. A value of 50 is 1/20th of a second, which should make your button presses quite responsive, but still debounce the switch well. If you find your count sometimes increases by more than one for a button press, you can increase the value to 100 or even 500, although at 500 (1/2 second) the button won't respond to really rapid presses


text:
Debouncing Switch Issue
I’m trying to use a LDR to monitor the light levels and if the LDR is covered and the button is pressed, the LED should switch on. I’m in the process of adding debouching but every time I run the code, the it goes in the if (val > 421) part the led is on, but the button hasn’t been pressed and the code stops.
I’m suspecting it may be a logic issue with the states. I’m using the millis function for the debouncing so the code should ignore the first 200ms of when the button is pressed. I just help in regard to the debouncing so when the LDR is covered and the switch is pressed , the LED should turn on.
The code is shown below:
const int buttonPin = 8;
const int ldrPin = 0;
const int LEDPin = 13;

boolean buttonState = 0;
boolean NEWbuttonState = 0;
boolean LEDState = 0;
int bounce_time = 200;
unsigned long my_time;

boolean on;

int val = 0;

void showValue(float myval)
{
  Serial.print(myval);
  Serial.print(" lightstatus ");
  Serial.println(LEDState);
}

void setup()
{
  pinMode(buttonPin, INPUT);
  pinMode(LEDPin, INPUT_PULLUP);
  on = false;
  analogReference(DEFAULT);
  pinMode(ldrPin, INPUT);
  Serial.begin(9600);
  my_time = millis();
}

void loop()
{

  val = analogRead(ldrPin);

  NEWbuttonState = digitalRead(buttonPin);

  if ((millis() - my_time) > bounce_time)
  {
    digitalWrite(LEDPin, LOW);

    if (buttonState != NEWbuttonState)
    {
      buttonState = NEWbuttonState;

      //if button is pressed
      if (NEWbuttonState == 1 && LEDState == 0)
      {
        buttonState = NEWbuttonState;

        if (val > 421)
        {
          my_time = millis();

          digitalWrite(LEDPin, 1);
          LEDState = 1;
          showValue(val);
          Serial.print("button press");
        }

        if (val < 420)
        {
          my_time = millis();

          digitalWrite(LEDPin, 0);
          LEDState = 0;
          showValue(val);
        }
        buttonState = 1;
      }
      else
      {
        if (NEWbuttonState == 0)
        {
          buttonState = 0;

        }
      }
    }
  }
}

Look for the Bounce2 library in the IDE library manager.

you described what you want to happen when the button is pressed, but you forgot to say what should happen when the button is released

If your Arduino is an uno or nano or similar, const int ldrPin = 0; conflicts with Serial. Or, if it's intended for analogRead, you should avoid pinMode(ldrPin, INPUT);  Better use  const byte ldrPin = A0;

Please show us how you have connected the LDR to the Arduino.

Bouncing of a mechanical switch happens in very few milliseconds, faster than you can see a led shine.
So, for your task, you don't need any debouncing.
The description or your task lacks what should happen "if not". I assume the led should shine while both button is pressed and ldr is covered. If either button is not pressed, or ldr is lit, the led should remain off.
This one is too simple:
void loop() {
  bool ldrDark = analogRead(A0) < MAX_LDRBRIGHT;
  digitalWrite(led, ldrDark && digitalRead(buttonPin));
}

To add a delay (led goes on only when button is pressed some time) is easy as well.
const byte LED = LED_BUILTIN; // 13 on UNO

const byte BUTTON = 8;  // Button connects to GND
const byte PRESSED = LOW; // due to INPUT_PULLUP
const int DELAY = 300; // ms
bool btnState; // true = HIGH when presse

const byte LDR = A0; // LDR to 5V, Resistor to GND : Low values when dark
const int MIN_LDRBRIGHT= 420; // depends on resistor and LDR

void setup() {
   pinMode (LED, OUTPUT);
   pinMode (BUTTON, INPUT_PULLUP);
}

void loop() {
  static unsigned long lastOpen;
  if (digitalRead(BUTTON) == PRESSED) {
    if (millis() - lastOpen > DELAY)
      btnState = HIGH;
    else btnState = LOW;
  } else {
      lastOpen = millis(); // to remember last moment button was released
      btnState = LOW;
  }

  bool ldrDark = analogRead(A0) < MIN_LDRBRIGHT;

  digitalWrite(LED, ldrDark && btnState);
}

You should see led follow the covered ldr (while button remains pressed) faster than button changes.  If that's the intention of this exercise.


text:
MQTT on nano with Ethernet shield not working
I'm using an arduino nano with an ethernet shield (ENC28J60), and  ethernet eem to be working (I can create a webserver with Ethercard library).However, i'm stuck when i try to connect to a MQTT server.
I tried NanodeMQTT (stuck at waitforlink), Adafruit MQTT Library + Ethernet.h ( MQTT_connect() : Connection failed, endlessly retrying), PubSubClient + Ethernet.h (client.connect return 0) and some others.
At this point i am wondering if i am doing the right configuration each time:

when asked an ip, i set the static one i want for my arduino : 192.168.1.50
when asked an gwip, i set one of wy internet router : 192.168.1.254
when asked for a server, i set it to my mqtt server ipv4 : 192.168.1.185 (and port is 1883)
when asked for a mac adress, i keep the one in the example, or just write a random one

Do you know what can cause the ethernet.h or mqtt library to fail, but still ethercard is working fine ?

Try simple then add features.  For example, try to get the Ethernet working first.  Then add the MQTT.  Who is asking for IP addresses?  Are you saying these are the IP addresses you have added to your program / sketch?  If your program / sketch is not long maybe you can include it in your question.

try UIPEthernet library instead of Ethernet, which is for a different chip

i'm using the basic bluit-in examples for theese libraries, and did not include them since i tried 3 and none worked. But since Ethercard work on my end, i will try to fiddle with it and a MQTT library then. Also tried UIPEthernet with no success, but did not even realise it was a standard library designed for ENC28J60, thanks for pointing that out, maybe i can just adapt some Ethernet.h code by replacing it with UIPEthernet

Thanks to Juraj pointing me that UIPEthernet is just a replacement for the Ethernet library, I finnally found this article Which works just fine.


text:
How to connect Big Dome Button with arduino
I am quite new to arduino and for a project I want to use big dome button which when pressed it will count how many times has been pressed.It is using 12 volts.The button is this https://www.sparkfun.com/products/9181

a switch doesn't need voltage. the 12 V is for the indicator LED. you can wire the microswitch like any button

I looked at their demo video https://www.sparkfun.com/news/874 (@3:05) and did not see much about a 12V LED driver. If you own that Button already, just unscrew it and have a look at the led. Counting and score display has nothing to do with the button hardware.

More info from sparkfun: > "They use a 12V LED for illumination, but we found it works fine at 5V, albeit a bit dim."  I read:  unscrew it, search for the resistor or replace the led by a real one and your own resistor. The 12$ are charged for the plastic garbage, the "electronics" is for free.

As others have said, the 12V powers the switch's internal LED.

EDIT:
Switches don't need power. If you skip all power to the switch it will still work but it won't light up.
End of edit:

If you want the switch to light up, connect the V in to 12V, or if you connect it to 5V, it will be dim, but -probably- still light. (You are certain to have a 5V pin on your Arduino board. Using that means you don't need a separate 5V supply.)
Now connect one lead of the switch to a digital input, and the other lead to ground.
Then set your switch pin to INPUT_PULLUP mode. Now your switch will read HIGH until it's pressed, then it will read LOW.
create a variable at the top of your code called buttonState:
byte buttonState = HIGH;

Also define an unsigned long variable nextReadMillis:
unsigned long nextReadMillis = 0;

and a pressCount variable:
unsigned int pressCount = 0;

And define a debounceTime:
#define debounceTime 50

In your loop, do something like this:
void loop() {
    //Get the new millis(value)
    unsigned long newMillis = millis();

    //only look at the new button value if enough time has elapsed.
    if (newMillis >= nextReadMillis) {
       byte newButtonState = digitalRead(buttonPin);

       //Only do something if the button state has changed
       if (buttonState != newButtonState) {
          buttonState = newButtonState;
          nextReadMillis = newMillis + debounceTime;
          //If the button is now in the pressed (LOW) state, increment the count
          if (buttonState == LOW) {
              pressCount++;
          }
       }
    }
}

That's pseudo-code. It likely has syntax errors. It's not meant to be copy/pasted. Use it as a guide for your project.
The code using millis() is a version of "software debouncing." Electrical switches tend to "jitter" or "bounce" between their on and off states very rapidly when they are first pressed/released. By only checking for state changes after a brief delay, you ignore the jitter in the readings.
Note that if you want your LED to only light when the button is pressed, you could control it with another digital pin. You'd assign a different pin to controlling the LED output, set that pin to OUTPUT mode, and switch the pin based on button state inside the body of the if (buttonState != newButtonState) if statement.
If your LED draws ≤20mA at 5V, you could connect it directly to your output pin. If it draws more than that, you will need a transistor to drive it so you don't draw too much current from your output pin and burn it out. Wiring a transistor driver is beyond the scope of this post however.


text:
ESP32 saving data to SD card in .csv doesnt format correctly
i want to save a vector to a .csv file on a SD Card.
I watched this tutorial on how to do it and it describes it perfectly even though its kinda dated.
My Problem is that everything is saved into the first cell of the .csv file so it gets constantly overwritten.
It should save only the first vector into the first cell, then the second vector into the second cell and so on.
I just get all three vectors with the commas into the first vector like this:
8, 9, 10
Also the header which should appear at the top is also gone.
I would really appreciate some help. Thanks!
Here is my setup and loop:
#include <iostream>
#include <string>
#include <vector>
#include "SD.h"
#include "SPI.h"
#include "EKG_data_transmision.h"

#define CS_Pin 5 // Chip Select Pin

EKG_data_transmision EKG_data_transmision;

std::vector<unsigned short> vector_1 = {1,2,3,4,5,6,7,8,9,10};
std::vector<unsigned short> vector_2 = {2,3,4,5,6,7,8,9,10,11};
std::vector<unsigned short> vector_3 = {3,4,5,6,7,8,9,10,11,12};
unsigned int for_x = 0;

void setup() {
  // open serial
  Serial.begin(9600);
  Serial.print("Init SD Card...");
  pinMode(CS_Pin, OUTPUT);

  if(!SD.begin(CS_Pin))
  {
    Serial.println("Card failed or not present");
    return;
  }

  EKG_data_transmision.vectorData = SD.open("/data.csv", FILE_WRITE);  //erstelle data.csv datei

  if(EKG_data_transmision.vectorData)
  {
    EKG_data_transmision.vectorData.println(", , , ,");
    String header = "ID, Value, Time, Whatever";
    EKG_data_transmision.vectorData.println(header);
    EKG_data_transmision.vectorData.close();
    Serial.println(header);
    Serial.println("card init sucess");
  }
  else
  {
    Serial.println("Couldnt open vector data file");
  }

}

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

  while(for_x <= 8){
    for_x++;
    EKG_data_transmision.write_vector_to_SD(vector_1, vector_2, vector_3);
    delay(1000);
  }

  delay(10000);
}

Here is my function that should save everything to the SD Card:
bool  EKG_data_transmision::write_vector_to_SD(std::vector<unsigned short> vector_ADC_1, std::vector<unsigned short> vector_ADC_2, std::vector<unsigned short> vector_ADC_3) // Übertrage
{
  dataString = String(vector_loc) + "," + String(vector_ADC_1[vector_loc]) + "," + String(vector_ADC_2[vector_loc]) + "," + String(vector_ADC_3[vector_loc]); // + "\r\n"

  vectorData = SD.open("/data.csv", FILE_WRITE);

  if(vectorData){
    //sd karte immer noch da und schau ob data.csv exisitiert
    vectorData.println(dataString);
    Serial.println("This is vector:");
    Serial.println(vector_loc);
    Serial.println("Im actually writing this:");
    Serial.println(dataString);
    vectorData.close(); // close the file
    }

  else{
    Serial.println("Error writing to file !");
}
  vector_loc++;

  return 0;
}

Thanks for your fast answer. I just changed every WRITE to APPEND. Now the values get saved into different cells but only into Row A. I thought with "," it switches into different rows. Do you have an answer to that?

in my language Excel uses ; for csv, because we have , as decimal separator

Thanks a lot for you help!! I just tried it and with ; it works perfectly.

I moved the first comment to an answer

In Arduino SD library FILE_WRITE constant instructs the function to open the file for append, but in the esp32 SD library it opens the file for rewrite. Use FILE_APPEND to open the file for append.
File file = SD.open(path, FILE_APPEND);


text:
config file for Arduino Uno installed on Raspberry PI
The Arduino code shown runs successfully. My problem is configuring the Arduino IDE so it fits within the Raspberry Pi window. The second image, the built-in serial port /dev/ttyAMA0, is produced. It is blank.
The Arduino Menu bar cannot be accessed. Therefore, the Tools button and other buttons for running the code are not available. The user can adjust the width of the Arduino IDE window but cannot move it around the screen or up or down.
The /boot/config file is setup up for a Adafruit 5" Backback monitor. No other app, Thonny Pi, or the terminal has these problems.
It appears to me that the config file needs some work. That is only a guess.
Any suggestions will be greatly appreciated.

Please edit the post to remove non-code text from code tags

In Linux you can move things around in different ways. For example:

Hold ALT and click and drag anywhere in the window. The whole window will move and you can get to the edge to resize it.
Press ALT-Space then M and you can use the cursor keys to move the window around
Press ALT-Space then X and it will maximise the window to the screen size

Thank you. The command key works.

What you can do is set the default IDE window size by editing preferences.txt:
Click the link on the line following File > Preferences > More preferences can be edited directly in the file.
This will open the Arduino15 (or similar folder name) folder.
Close the Arduino IDE.
Open the file preferences.txt in a text editor
Change the editor.window.height.default and editor.window.width.default properties to your desired window size.
Save the file.


text:
Reading I2C data from SW6106 register
I am using the SW6106 powerbank IC as an I2C but no matter what I have tried I couldn't read something other than "FF".
Datasheet for the IC.
Timing diagram for reading data:

Timing diagram for writing data:

The code I use:
#include <Wire.h>

byte ADDRESS_SLAVE = 0x3C;
byte REGISTER_XY = 0xB0;
byte READ_LENGTH = 1;

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

  Wire.begin();
  Wire.setClock(400000); // set I2C 'full-speed'

  Wire.beginTransmission(ADDRESS_SLAVE);
  Wire.write(REGISTER_XY);  // set register for read
  Wire.endTransmission();
}

void loop() {
   Wire.requestFrom(ADDRESS_SLAVE,READ_LENGTH);
   byte buff[READ_LENGTH];
   Wire.readBytes(buff, READ_LENGTH);
   for (int i = 0; i < READ_LENGTH; i++) {
     Serial.println(buff[i], HEX);
   }
   Serial.println();
   delay(1000);
}

Serial monitor output:

I really couldn't understand anything from that timing diagram and couldn't read anything from the IC. I'd appreciate any help.
Edit:
I edited the code a little bit to see what Wire.endTransmission(); returns.
#include <Wire.h>

byte ADDRESS_SLAVE = 0x3C;
byte REGISTER_XY = 0xB0;
byte READ_LENGTH = 1;

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

  Wire.begin();
  Wire.setClock(400000); // set I2C 'full-speed'
}

void loop() {
  Wire.beginTransmission(ADDRESS_SLAVE);
  Wire.write(REGISTER_XY);  // set register for read
  int x = Wire.endTransmission();
  Serial.println(x, DEC);
  delay(200);
}

And it retruns the following:

I really don't know where I am doing wrong.

Have you tried the I2C scanner to check it's on the right address? Sometimes the quoted address in datasheets is the 7-bit address and sometimes the 8-bit address.

@Majenko Yes, I have tried it and I can confirm it's on the right address.

The way that I2C works on that chip, looking at the diagrams, is perfectly normal. Maybe if you move the write (register select) into the loop to just before the read?

Is pin LED4/I2C connected to ground?

You ignore both the return values from Wire.endTransmission() and Wire.requestFrom(). Please output them to the Serial monitor for debugging. Wire.endTransmission() returns a status code and Wire.requestFrom() returns the number of bytes actually read.

@chrisl I edited the code to see what Wire.endTransmission() returns, and it returns a 0 or 3. I edited the post and added the code with a screenshot of the serial monitor.

Check the clock of the power bank ic

@AderNawfal the datasheet say it is 100/400K. I tried both of them and the results are same for both of them.

What the diagram shows is a write to slave address 0x3C with the value 0xB0, then a read 1-byte request for address 0x3C. Can you try this code? https://hastebin.com/wuxuxulito.cpp

@MaximilianGerhardt I tried your code and it returns the following I2C write ret: 0 I2C slave sent us 8 bytes 0. I really don't know why the ic returns 0.

So the I2C write goes through without any errors (was ACKed on both address and data), and the read returns a whopping 8 bytes (?) but then only 1 byte with content 0x00? What's supposed to be returned as data? I can just see 1 byte, but not the meaning. You can also try to remove the Serial.println() except for the one that print the bytes, and some dividor between.

@MaximilianGerhardt Oh, I am really sorry, I was just editing the code to see the other bytes if I could get anything. The original code returns I2C write ret: 0 I2C slave sent us 1 bytes 0 . So It doesn't returns 8 bytes. And I don't know what it should return because the datasheet doesn't specifies anything about the data.

Well so it does correctly see the data I assume. If you have a logic analyzer you can double-check the data trace. Now the translated datasheet (http://ismartware.com/enet_upload/file/20181214/20181214101104_63565.pdf) really doesn't say much more, but it does show that "IRQ" should be connected also. Maybe certain events trigger an IRQ pulse and you're supposed to read the I2C register? But then why are you allowed to write to it? Is it for the LEDs or input? The datasheet gives 0 information about this and withouth that I don't know what you further want to do with this chip..

@MaximilianGerhardt I found this chip on a cheap qc3.0 supported powerbank pcb and when I checked the datasheet I saw that it supports i2c. So I thought to myself maybe I could get some verbose data about the current and voltage output and maybe a battery gauge. But the datasheet is really poor documented. I hope I can get something useful out of it

Next best thing would be to find out a contact email of the chip manufacturer and request details.

I know this post is very old, but I was able to get the register map from the manufacturer, Ismartware. Here's a link to the datapack for anyone else that may end up here while searching for the same thing.


text:
How to execute commands over desired amount of time
I have a program that receives 4 commands on 4 channels to change the color of an LED using mqtt communication. Lets just focus on two of the channels, the time and the red.
I am sending a length of time that I would like to complete the color change by, and a new color value.
I have ran my test runs to calculate the amount of time it seems to take to update a single value. I calculate this by setting the intervalRed value to 0.01
with a duty cycle of 1024, commanding the led to go from its starting value to its ending value of fully on, by the interval value would be 10,240 ticks.
when I send that command, take the resulting execution time ( 287ms ) and calculate the time to update a single tick I get a value of 0.028027 ms to complete a single increment.
When I set the hardcoded tickTime to that value: 0.028027
and I send a color change from off to on/vice-versa with a requested completion time of 1000ms, the actual execution time varies.
the larger the requested execution time varies, causes a greater difference between the actual and requested time.
I ran many test trials with a set interval to gain a value for the length of time for a single tick but no matter when value I use, there are still discrepancies. I dont believe using a hardcoded value for the length of time for a single tick is the correct way to assure the color change will occur over a given time.
I am happy to provide the terminal output for any attempts to show the output of values used in my calculations if needed (But I believe I need a difference approach all together)
What is the best way to assure the color change completes in the requested amount of time?
Perhaps some calculation based on the amount of time passed rather then calculating a hardcoded value for the time of a single tick?
    #include <ESP8266WiFi.h>
#include <PubSubClient.h>

#define CLIENT_NAME "ESP8266_1" // just a name to identify this client
WiFiClient wifiClient;
PubSubClient mqttClient("10.0.0.131", 1883, wifiClient);

//set rgb led pins
int pinGreen = 4;
int pinBlue = 12;
int pinRed = 14;

float currentRed = 1024;
float currentGreen = 1024;
float currentBlue = 1024;

int nextRed = -1;
int nextGreen = -1;
int nextBlue = -1;

float intervalRed = -1;
float intervalGreen = -1;
float intervalBlue = -1;

//the float time was calculated by
//IntervalValue(set to 0.01)/Value Change (1024 when going from on to off) = 10,240 ticks
//ExecutionTime (beginning time - end time) /# of ticks = 0.0347643
// I seem to be getting varying execution times so I have tried values between 0.028 and 0.04
float tickTime = 0.028027;
int executionTime = 1;
int showTime = 1;
int beginningReceivedData;

void setup()
{
  Serial.begin(9600);
  //set rgb led pins to output

  pinMode(pinRed, OUTPUT);
  pinMode(pinGreen, OUTPUT);
  pinMode(pinBlue, OUTPUT);
  digitalWrite(pinRed, HIGH);
  digitalWrite(pinGreen, HIGH);
  digitalWrite(pinBlue, HIGH);

  mqttClient.setCallback(callback);
  WiFi.begin("partyHouse", "whatsthepassword");
  connectToWiFiAndBroker();
}

void connectToWiFiAndBroker()
{
  Serial.print("\nConnecting to WIFI");
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println("Connected to WIFI!");

  Serial.println("Connecting to broker");
  while (!mqttClient.connect(CLIENT_NAME))
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println("Connected to broker!");

  mqttClient.subscribe("InterestingTopics/#");
}

void loop()
{
  if (!mqttClient.connected()) {
    connectToWiFiAndBroker();
  }
  mqttClient.loop();

  updateColors();
}
//------------------------------------------------------------------------------------------------------------------------
//The CallBack for processing incoming data
//------------------------------------------------------------------------------------------------------------------------
//the topic is the path based on the subscription
void callback(char* topic, byte* payload, unsigned int length)
{
  //for tracking the time it takes to process the data, as well as the time it takes to complete updating the colors over the desired time
  beginningReceivedData = millis();
  char commandValue[length+1];
  for (int i = 0; i < length; i++)
  {
    commandValue[i] = (char)payload[i];
  }
  commandValue[length+1] = '\0';
  if (strcmp(topic, "InterestingTopics/time") == 0) {
    executionTime = atoi(commandValue);
  }
  if (strcmp(topic, "InterestingTopics/red") == 0) {
    showTime = 1;
    nextRed = atoi(commandValue);
    intervalRed = (nextRed - currentRed)/(executionTime/tickTime);
    //manual Interval value used for calculating the tickTime
    if (nextRed < currentRed) {
      intervalRed = -0.1;
    } else {
      intervalRed = 0.1;
    }

    Serial.print("next: ");
    Serial.print(nextRed);
    Serial.print(" Current: ");
    Serial.print(currentRed);
    Serial.print(" Interval: ");
    Serial.println(intervalRed, 10);

    Serial.print("time to process incoming single value (red): ");
    Serial.println(millis() - beginningReceivedData);
  }
  if (strcmp(topic, "InterestingTopics/green") == 0) {
    nextGreen = atoi(commandValue);
    intervalGreen = (nextGreen - currentGreen)/(executionTime/tickTime);
  }
  if (strcmp(topic, "InterestingTopics/blue") == 0) {
    nextBlue = atoi(commandValue);
    intervalBlue = (nextBlue - currentBlue)/(executionTime/tickTime);
  }
}

void updateColors() {
  //------------------------------------------------------------------------------------------------------------------------
  //Updating the Red
  //------------------------------------------------------------------------------------------------------------------------
  if (currentRed != nextRed && nextRed > -1) {
    currentRed = currentRed + intervalRed;
    //if value decreasing and it passes the next value, set values equal to prevent passing
    if (intervalRed < 0 && currentRed < nextRed) {
      currentRed = nextRed;
    }
    if (intervalRed > 0 && currentRed > nextRed) {
      currentRed = nextRed;
    }
    analogWrite(pinRed, (int)currentRed);
    //this else exists just to print the different in time from receiving the value to the time it took to update
  } else if (currentRed == nextRed && nextRed > -1 && showTime == 1) {
    //showTime set to zero to only print the time once
    showTime = 0;
    Serial.print("full color change has completed taking this much time: ");
    Serial.println(millis() - beginningReceivedData);
  }
  //------------------------------------------------------------------------------------------------------------------------
  if (currentGreen != nextGreen && nextGreen > -1) {
    currentGreen = currentGreen + intervalGreen;
    //if value decreasing and it passes the next value, set values equal to prevent passing
    if (intervalGreen < 0 && currentGreen < nextGreen) {
      currentGreen = nextGreen;
    }
    if (intervalGreen > 0 && currentGreen > nextGreen) {
      currentGreen = nextGreen;
    }
    analogWrite(pinGreen, (int)currentGreen);
  }
  if (currentBlue != nextBlue  && nextBlue > -1) {
    currentBlue = currentBlue + intervalBlue;
    //if value decreasing and it passes the next value, set values equal to prevent passing
    if (intervalBlue < 0 && currentBlue < nextBlue) {
      currentBlue = nextBlue;
    }
    if (intervalBlue > 0 && currentBlue > nextBlue) {
      currentBlue = nextBlue;
    }
    analogWrite(pinBlue, (int)currentBlue);
  }
}

Don't assume an update takes a fixed time and blast constant changes. Write code that calculates change/millisecond. Then record the starting millis() value when you begin a sequence, and each time through your loop, calculate float(millis()-startTime)/sequenceTime. That will give you the % of color change to apply now. Then use that percentage to calculate the interpolated color value.
That will give you an adaptive system that will set the color value to the approximate desired color for the current stage in your animation, regardless of how long each iteration the loop takes. If the loop lags for some reason, you will get more coarse changes between color values, but it will still track your desired pacing.

Note that you'll get more responsive code by adapting the above to use fixed-point math, since most Arduinos don't have hardware floating point support and their floating point is quite slow as a result. Mapping arbitrary floating point to fixed point is a little bit tricky, however. I'd suggest just writing it using floating point to start, and then optimizing it to fixed point math if it's too jumpy.

Thank you for the suggestion of fixed point math, I did see a significant difference in execution time when I went from double to float in my math. Not sure I understand how to convert to fixed but, time to do more research

Fixed point math uses a fixed "binary decimal place" and treats all values as between 0 and 1 (or 0 and 2, or 0 and 4, depending on where you put the assumed binary decimal place. If you scale all of your values to the range of your fixed-point, you can do integer math on the values, and then interpret the results as fixed-point values, and get much, MUCH faster performance. Figuring out the scaling and ranging takes some thought though.

Note that you could also try using short floating point values rather than float. That will be faster still, and easier to program than fixed point math. It makes your calculations pretty low precision however.


text:
How to program Arduino LCD shield with Python?
so I want to run a Arduino LCD shield with Python code..But after having some research on the Internet, I can not found any tutorial, some just give some basic code with LED.
And one things that how can I add a LCD library (LyquidCrystal.h in Arduino code) if i program in Python.
Thank you guys very much.

You cannot program an Arduino with Python

It's like @chrisl wrote in the comments. You cannot program Arduino with python.
You can however upload an open source Firmata protocol implementation onto the Arduino and then write python code on your PC that will send commands to the Arduino by USB cable to tell it what to do.
This way you actually execute your code on PC, but control Arduino pins. Only drawback is that you need to have a PC connected to the Arduino at all times. This is not very practical.
There is a really nice tutorial here
Example python code looks like this:
import pyfirmata
import time

board = pyfirmata.Arduino('/dev/ttyACM0')
while True:
    board.digital[13].write(1)
    time.sleep(1)
    board.digital[13].write(0)
    time.sleep(1)

I'm afraid that only solution to controlling LCD shield this way without writing any C is to write the entire LCD library in python basing on pyfirmata calls to control the Arduino pins. It's not as hard as it sounds, and even a beginner could easily succeed.

However, if the task is to run an existing Arduino LCD library, it has to run on the Arduino.
If it needs data from a python script, it's questionable, whether firmata is the proper transport mechanism. And if that python script gets all data from the Arduino, one should consider to run that logic directly on the Arduino, instead of that generic firmata overhead.

@DataFiddler Yes, if I can not program all things on Python..so I wonder that if there any ways to pass data from Python (for ex. "Hello World") to Arduino LCD sheild.

As it's unclear to me what you want to outsource from Arduino to a Python node, I have no idea, whether pyfirmata or pyserial is your way to go. ( If at all, IMO )


text:
LCD Blinking after inserting code : A medication reminder system using Arduino Uno
RTC DS3231,Arduino Uno and 4 push buttons, 10K potentiometer, 4 of 10K resistor and a buzzer. I decided to follow from an online source and encounters a few problems which already fixed but this one puzzles me. Would really appreciate your help. The RTClib.h library is already installed.LCD Blinking after inserting code and it shows blocks instead of characters.
There's other picture in this link too.
https://drive.google.com/open?id=1OzHqZlS7mnkngMx-EIiqIgzdHZaTsHr8

#include <LiquidCrystal.h>
#include <Wire.h>
#include <RTClib.h>
#include <EEPROM.h>

RTC_DS3231 rtc;

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;                 // lcd pins
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

int buzz = 13;
int addr=17;

const int buttonPin2 = 9;
const int buttonPin3 = 8;
const int buttonPin1 = A0;
const int buttonPin4 = 7; // the pin that the pushbutton is attached to
int val2 = 0;
int val3=0;
int pushVal;
int bS1 = 0;         // current state of the button
int lBS1 = 0;     // previous state of the button

int bS2 = 0;         // current state of the button
int lBS2 = 0;

int bS3 = 0;         // current state of the button
int lBS3 = 0;

int bS4 = 0;         // current state of the button
int lBS4 = 0;

// configure the pins to the right mode
int buzz8amHH = 8;          //    HH - hours         ##Set these for reminder time in 24hr Format
int buzz8amMM = 00;          //    MM - Minute
int buzz8amSS = 00;          //    SS - Seconds

int buzz2pmHH = 8;          //    HH - hours
int buzz2pmMM = 1;          //    MM - Minute
int buzz2pmSS = 00;          //    SS - Seconds

int buzz8pmHH = 8;          //    HH - hours
int buzz8pmMM = 2;          //    MM - Minute
int buzz8pmSS = 00;          //    SS - Seconds

int nowHr, nowMin, nowSec;

void gwsMessege(){               // print get well soon messege
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Stay Healthy :)");     // Give some cheers
    lcd.setCursor(0, 1);
    lcd.print("Get Well Soon :)");// wish
}

void helpScreen() {              // function to display 1st screen in LCD
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Press Buttons");
    lcd.setCursor(0, 1);
    lcd.print("for Reminder...!");
 }

void timeScreen() {              // function to display Date and time in LCD screen
  DateTime now = rtc.now();             // take rtc time and print in display
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Time:");
    lcd.setCursor(6, 0);
    lcd.print(nowHr = now.hour(), DEC);
    lcd.print(":");
    lcd.print(nowMin = now.minute(), DEC);
    lcd.print(":");
    lcd.print(nowSec = now.second(), DEC);
    lcd.setCursor(0, 1);
    lcd.print("Date: ");
    lcd.print(now.day(), DEC);
    lcd.print("/");
    lcd.print(now.month(), DEC);
    lcd.print("/");
    lcd.print(now.year(), DEC);
    delay(500);
}

void setup()
{
Wire.begin();
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));            // uncomment this to set the current time and then comment in next upload when u set the time
  //rtc.adjust(DateTime(2019, 1, 10, 7, 59, 30));                // manual time set

  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Welcome To Our");                                      // print a messege at startup
  lcd.setCursor(0, 1);
  lcd.print("Medicine Reminder");
  delay(1000);
  gwsMessege();
  delay(3000);
  helpScreen();
  delay(2000);
  timeScreen();
  delay(3000);
  lcd.clear();

  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);
  pinMode(buzz, OUTPUT);
  Serial.begin(9600);
}

void ValSet(){
  Serial.println(EEPROM.read(addr));
  val2 = EEPROM.read(addr);                         // read previosuly saved value of push button to start from where it was left previously
  switch (val2) {
    case 1:
      lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Reminder set ");
    lcd.setCursor(0, 1);
    lcd.print("for Once/day !");
      pushVal = 1;
      delay(500);
      break;
    case 2:
      lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Reminder set ");
    lcd.setCursor(0, 1);
    lcd.print("for Twice/day !");
      pushVal = 2;
      delay(500);
      break;
    case 3:
      lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Reminder set ");
    lcd.setCursor(0, 1);
    lcd.print("for Thrice/day !");
      pushVal = 3;
      delay(500);
      break;
  }
}

// the main loop will constantly check to see if the button has been pressed
// if it has, a counter is incremented, and then some action can be taken
void loop()
{                                         //call to set thrice/day
    if (pushVal == 1) {                                // if push button 1 pressed then remind at 8am
    at8am();                                           //function to start uzzing at 8am
  }
  else if (pushVal == 2) {                             // if push button 2 pressed then remind at 8am and 8pm
    at8am();
    at8pm();                                           //function to start uzzing at 8mm
  }
  else if (pushVal == 3) {                             // if push button 3 pressed then remind at 8am and 8pm
    at8am();
    at2pm();                                            //function to start uzzing at 8mm
    at8pm();
  }
  // read the state of the button
  bS1 = digitalRead(buttonPin1);
  bS2 = digitalRead(buttonPin2);
  bS3 = digitalRead(buttonPin3);
  bS4 = digitalRead(buttonPin4);

  // check to see if it different than the last time we checked

if (bS2 != lBS2) {
    // either the button was just pressed or just released
    if (bS2 == HIGH) {
      // it was just pressed
      Serial.println("n02");
      EEPROM.write(17,1);
      push1();
      delay(1000);
    }
  }
  lBS2 = bS2;

if (bS3 != lBS3) {
    // either the button was just pressed or just released
    if (bS3 == HIGH) {
      // it was just pressed
      Serial.println("no3");
      EEPROM.write(17,2);
      push2();
      delay(1000);
    }
  }
  lBS3 = bS3;

if (bS4 != lBS4) {
    // either the button was just pressed or just released
    if (bS4 == HIGH) {
      // it was just pressed
      Serial.println("no4");
      EEPROM.write(17,3);
      push3();
      delay(1000);
    }
  }
  lBS4 = bS4;

if (bS1 != lBS1) {
    // either the button was just pressed or just released
    if (bS1 == HIGH) {
      val3=EEPROM.read(addr);
      EEPROM.write(17,0);
      digitalWrite(buzz, LOW);
      pinstop();
      EEPROM.write(17,val3);
    }
  }
  lBS1 = bS1;

  timeScreen();
  ValSet();
}
void push1() {                   // function to set reminder once/day                                           //save the state of push button-1
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Reminder set ");
    lcd.setCursor(0, 1);
    lcd.print("for Once/day !");
    delay(1200);
    lcd.clear();
  }

void push2() {                      //function to set reminder twice/day
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Reminder set ");
    lcd.setCursor(0, 1);
    lcd.print("for Twice/day !");
    delay(1200);
    lcd.clear();
  }

void push3() {                    //function to set reminder thrice/day
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Reminder set ");
    lcd.setCursor(0, 1);
    lcd.print("for Thrice/day !");
    delay(1200);
    lcd.clear();
  }

void pinstop(){                   //function to stop buzzing when user pushes stop push button
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Take Medicine  ");
    lcd.setCursor(0, 1);
    lcd.print("with Warm Water");
    delay(5000);
    lcd.clear();
  }
void at8am() {                      // function to start buzzing at 8am
  DateTime t = rtc.now();
  if (int(t.hour()) == buzz8amHH && int(t.minute()) == buzz8amMM  && (int(t.second()) == buzz8amSS || int(t.second()) < buzz8amSS+10)) {
        /////////////////////////////////////////////////////
        digitalWrite(buzz,HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Time to take ");
        lcd.setCursor(0, 1);
        lcd.print("Morning medicines.");
        delay(5000);

        /////////////////////////////////////////////////////
      }
}

void at2pm() {                          // function to start buzzing at 2pm
  DateTime t = rtc.now();
  if (int(t.hour()) == buzz2pmHH && int(t.minute()) == buzz2pmMM  && (int(t.second()) == buzz2pmSS || int(t.second()) < buzz2pmSS+10)) {
        /////////////////////////////////////////////////////
        digitalWrite(buzz,HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Time to take ");
        lcd.setCursor(0, 1);
        lcd.print("Afternoon medicines.");
        delay(5000);

        /////////////////////////////////////////////////////
      }
}

void at8pm() {                           // function to start buzzing at 8pm
DateTime t = rtc.now();
  if (int(t.hour()) == buzz8pmHH && int(t.minute()) == buzz8pmMM  && (int(t.second()) == buzz8pmSS || int(t.second()) < buzz8pmSS+10)) {
        /////////////////////////////////////////////////////
        digitalWrite(buzz,HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Time to take ");
        lcd.setCursor(0, 1);
        lcd.print("Night medicines.");
        delay(5000);

        /////////////////////////////////////////////////////
      }
}

encounters a few problems which already fixed but this one puzzles me so which problem exactly? This sketch and the complexilty of the project is huge. You should provide a minimal example of what exactly is broken with which component, then people can help you better.

the lcd and the connection to the 4 push button and is my wiring correct ?

Some troubleshooting ideas:
1. does turning the potentiometer change the brightness of the LCD?
A. If not, there is a (1) power problem (2) wiring problem.
2. Do you ever get strange characters on the LCD or just the "shows blocks instead of characters"?
A. If you only get the blocks.  THe data is probably not making it to the LCD.  THe LCD will display blocks by default.
B. If you get strange character data too, then data lines probably are't wired properly.
3. Upload a program which only does the following:
A. Initializes the LCD
B. prints one line of output every time in the loop()  This is the easiest way to determine if it is your wiring.  If you don't see anything on the LCD then there is a high probability you have a wiring problem.
This is also very easy to try because you just open up a new sketch, create it and upload it to your device.
LCD Example
Try this official Arduino LCD Example (just make sure your data lines match -- you can change the values in the sample code so they are appropriate for your situation.
If it is a wiring problem I'd start looking at

if you are getting the needed amount of current / voltage to the LCD
is each data line connected properly.  Unhook power and use a meter to check continuity from your Arduino to your LCD pins.

Your wiring image is difficult to see. I recommend checking one by one.
Firstly, you connect Arduino with LCD only, make it work first. And then try the next.
I took at a glance at your code. There are some points you should check or change:

DO NOT use delay() function, if you uses delay() function, many pressing events will be missed. You should use timestamps instead. I recommend using ezButton library to avoid the blocking or implement timestamp by yourself (refer to BlinkWithoutDelay example).
Seemingly, you are using the external pull-up/pull-down for buttons. I recommend using the internal pull-up to reduce the complexity of wiring.

For LCD, please refer to this tutorial


text:
How to retrieve a page from a web-server using ESP8266 with the program running on Arduino instead of the ESP module?
I have connected an ESP8266-01 module to an Arduino as in the following schematic with the RX and TX pins changed to pins 8 and 9 instead of 0 and 1:

I am using the ESP8266wifi library at the following link:
https://github.com/ekstrand/ESP8266wifi
I have looked at the ESP8266HTTPClient library but that is for the ESP8266 board. I want my code to run on the Arduino Uno and not on the ESP8266! I have written the following code:
#include <SoftwareSerial.h>
#include <SerialESP8266wifi.h>

const String API_PASSWORD = "stn1234";

#define RX_PIN          8   // RX of Arduino (connected to TX of ESP8266)
#define TX_PIN          9   // TX of Arduino (connected to RX of ESP8266)
#define ESP_RESET_PIN   12

#define SERVER_IP           "192.168.43.234"
#define SERVER_PORT         "80"
#define WIFI_SSID           "MyWIFI"
#define WIFI_PASSWORD       "myWifiPassword"

uint8_t wifi_started = false;

const char RST[] PROGMEM = "RST";
const char IDN[] PROGMEM = "*IDN?";

#define CHANGE_DELAY        5000

void initializeWifi();
void transmitData(String);
String getResponse();
void transmitStatus();

SoftwareSerial swSerial =  SoftwareSerial(RX_PIN, TX_PIN);
SerialESP8266wifi wifi(swSerial, swSerial, ESP_RESET_PIN, Serial);

void setup()
{
    Serial.begin(9600);
    Serial.println("Initializing...");
    initializeWifi();
    Serial.println("Initialization complete");
}

void loop()
{
    transmitStatus();
    Serial.print("Transmission complete, ");
    int s = (CHANGE_DELAY/1000);
    Serial.print(s);
    Serial.println("s until next cycle");
    delay(CHANGE_DELAY);
}

void transmitStatus()
{
    int a = (int)random(100);
    int b = (int)random(100);
    String url = "/LocalWebProject/api/testConnection.php?a=" + String(a) + "&b=" + String(b);

    transmitData(url);
    String response = getResponse();
    Serial.print("Reply received: ");
    Serial.println(response);
}

void initializeWifi()
{
    swSerial.begin(115200);
    Serial.println("Starting Wifi");
    wifi.setTransportToTCP();
    wifi.endSendWithNewline(false);     // Will end all transmissions with a newline and carrage return ie println.. default is true

    wifi_started = wifi.begin();
    if(wifi_started)
    {
        Serial.println("Wifi started, connecting to AP...");
        wifi.connectToAP(WIFI_SSID, WIFI_PASSWORD);
        Serial.println("Connected to AP");
    } else {
        Serial.println("ESP module not working");
    }
}

void transmitData(String url)
{
    Serial.println("Connecting to server...");
    wifi.connectToServer(SERVER_IP, SERVER_PORT);

    String data = String("GET ") + url + " HTTP/1.1\r\n" +
           "Host: " + wifi.getIP() + "\r\n" +
           "Connection: close\r\n\r\n";

    Serial.println("Connected. Transmitting data...");
    wifi.send(SERVER, data);
}

String getResponse()
{
    while(1)
    {
        Serial.println("Waiting for response...");
        WifiMessage in = wifi.listenForIncomingMessage(6000);
        if(in.hasData)
        {
            if(in.channel == SERVER)
            {
                Serial.print("Reply received from the server: ");
                Serial.println(in.message);
                return in.message;
            }
        }

        delay(1000);
        Serial.print("Retrying, ");
    }
}

I have an Apache server running on Ubuntu 18.10 with a PHP project running on port 80. The testConnection.php page takes 2 GET parameters (integers) and returns the sum.
Problem:
It says that ESP module is not working. The AP in my case is a local hotspot on my mobile.
I have tried running the given example "SerialESP8266_library_test" and confusingly enough, it prints that it has successfully connected to my AP, but on my phone I do not see it connected. Only 1 device is visible as connected, which is my laptop which is running the Apache server and the web project. Also connectToAP returns 1, and connectToServer returns 0.
What am I doing wrong? I know that the ESP module requires power and the Arduino 3V3 is insufficient but I am just testing the code right now and I will do the required changes later on. Due to this, I am placing my Android phone just beside the ESP module so that it has no problems connecting to it.
Any help would be greatly appreciated! Thanks in advance.

https://github.com/jandrassy/WiFiEspAT/blob/master/examples/Basic/WebClient/WebClient.ino

swSerial.begin(115200). I don't think softwareSerial can even run that fast. The library you are using for wifi uses 9600 baud. I'd give that a try.

@Gerben Some modules are 9600, some are 115200 - it depends on the version of the firmware. SoftwareSerial can run at 115200, but it can't react fast enough to incoming bytes to reliably receive a stream of data.

@Juraj The WiFiEspAt requires flashing with AT 1.7, I did not want to do that

@Gerben I tried with 9600 and made some other changes. Now, it correctly connects to the AP (shows up on my phone), also connects to the server. But receives a HTTP 400 Bad request error. Is there any problem in the GET request format? My page is at:  http://192.168.43.234/LocalWebProject/api/testConnection.php

Host header value should be the name or IP of the server

@Juraj as per the examples, etc., the host is the local IP of the ESP module. Anyway, I tried your suggestion by providing the SERVER_IP there but still I get the same problem

the HTTP protocol is not defined by this example

Finally it is working by setting baud rate to 9600 and shortening the GET URL. Maybe there is a length restriction in the library.


text:
Arduino MKR QoS 1 logging with ArduinoMqttClient
I am collecting data with Arduino MKR GSM 1400 and sending data to Azure Cloud (IOT HUB). Currently I use ArduinoMqttClient ArduinoMqttClient
My question is, how to ensure both parties accepted QoS1 ? Is there any logging (in serial monitor) to see confirmation about delivery, re-transmit and so on? I did not find how to enable logging or whether azure on the other side accept the settings and they communicate each other for QoS 1.
Here is sample of code for publishing in ArduinoMqttClient:
  Serial.println("Publishing message");
  bool retained = false;
  int qos = 1;
  bool dup = false;

  String payload;

  payload += "hello";
  payload += " ";
  payload += millis();
  payload += " ";
  payload += cont++;

  // send message, the Print interface can be used to set the message contents
  mqttClient.beginMessage(outTopic, payload.length(), retained, qos, dup);
  mqttClient.print(payload);
  mqttClient.endMessage();

Here is sample of code for subscribe in ArduinoMqttClient:
  Serial.print("Subscribing to topic: ");

  // subscribe to a topic
  // the second parameter set's the QoS of the subscription,
  // the the library supports subscribing at QoS 0, 1, or 2
  int subscribeQos = 1;

  mqttClient.subscribe(inTopic, subscribeQos);

check if any of the mqttClient functions return a status

Did not find any other reliable as this one...


text:
Using interrupts to facilitate time-keeping
I am making a clock on an Arduino Mega using interrupts to facilitate time-keeping. The following is my timer breakdown:

Timer0: Used for my calls to millis() which allows me to determine when a second has passed.
Timer1: Used to interrupt at 8000Hz and play a sound sample on the fast PWM pin.
Timer2: Used for fast PWM in order to approximate sound.

My time seems to be accurate for roughly 15-25 minutes and then it starts to lag behind the phone time I am using as a comparison. I am wondering if this is bound to happen using interrupts to keep track of time, or if there is something I am doing in my ISR that might be slowing things down. My ISR looks like the following:
ISR(TIMER1_COMPA_vect) {
  // re-enable global interrupts so that other ISRs can execute (millis can keep incrementing)
  // As per: https://forum.arduino.cc/index.php/topic,46133.0.html#4
  sei();

  test_time = millis();
  if (test_time - start_time >= 1000) {
    start_time = test_time;
    // ... play some audio
  }
}

Setting up Timer1 is done as follows where SAMPLE_RATE = 8000:
void  init_timer(void) {
  noInterrupts (); //  Disable  all  interrupts

  //  Clear  Timer1  register  configuration
  TCCR1A = 0;
  TCCR1B = 0;

  //  Configure  Timer1  for  CTC  mode (WGM = 0b0100)
  bitSet(TCCR1B , WGM12);

  //  Disable  prescaler
  bitSet(TCCR1B , CS10);

  // Set  timer  period , which is  defined  as the  number  of
  // CPU  clock  cycles  (1/16 MHz) between  interrupts  - 1
  OCR1A = (F_CPU / SAMPLE_RATE) - 1;

  //  Enable  timer  interrupts  when  timer  count  reaches  value in  OCR1A
  bitSet(TIMSK1 , OCIE1A);

  //  Enable  interrupts
  interrupts ();
}

What drift are you experienceing? It might just be the inaccuracy of the crystal and not the interrupts counting wrong.

I have just been eyeballing the drift. After about 30 minutes I notice that it has lagged ~1 second.

Hm over ~-550ppm drift is pretty bad, crystal oscilators I've looked at have about +/-100ppm. Have you done a negative test, like doing just a minimal sketch without your ISRs which prints millis() and tracking the drift? Also would an external RTC (like DS3231) be an option?

@MaximilianGerhardt: The Mega is not clocked off a crystal: it uses a ceramic resonator instead. 555 ppm is consistent with the accuracy you can expect from a ceramic resonator. C.f. http://jorisvr.nl/article/arduino-frequency

The resonator accuracy can be as bad as 0.1% ( 1000 ppm ) but should be rather consistent with stable temperatures. If you increment odd seconds every 999 ms, and even seconds every 1000 ms, you should be fine currently :) Your error will be less by one magnitude (factor 10) ( A second off per ~4 hours). But there are more accurate external time signals (RTC, NTP). BTW: Long term accuracy is great for the power grid frequency, and available everywhere,

Thank you all for your help :). I am aware of RTC and NTP, I am just trying to avoid using them for this project.


text:
Why NRF24L01+ pipe has 5 byte address
I am studying NRF24L01+ module. I see, that only 6 receivers can be connected with the transmitter, via their unique pipes. What I can’t get is why the pipe id (address) has 5 long bytes.
As to me,1 byte would be much more than enough.
What is the purpose in 5-byte address in 5 bidirectional communications?

I see, that only 6 receivers can be connected with the transmitter source link?

@MaximilianGerhardt, In every worthy tutorial I found. In docs also: http://tmrh20.github.io/RF24/classRF24.html#a9edc910ccc1ffcff56814b08faca5535

what would you do if you had a 100 clusters of 6 receivers each near each other?

The datasheet (https://www.sparkfun.com/datasheets/Components/SMD/nRF24L01Pluss_Preliminary_Product_Specification_v1_0.pdf) page 54 shows 6 pipes, and each pipe holds a 5 byte (max) address; (actually, RX addresses 2-6 only modify the last 8 bit of the pipe1)). So you can have 6 communication partners and each one is identified by a 40-bit address, so 2^40 possibilities. It comes down to address space (for addresses) and hardware limitations (number of pipes). If the address space was too small, you would have address collisions (two or more modules have the same address), which is bad.

@jsotola that question disturbs me too. how should I generate these pipe ids.

use your birthday

5 bytes = more than 1 million million unique addresses, although not all addresses (as the nRF24L01 datasheet points out) are advised, for instance because they mimic the nRF's preamble packet.
So what is the purpose of addresses?
The purpose is to ensure that radio transmissions are received at the intended radio module.  Consider a radio network where you have 1 transmitter (TX) and 3 receivers (RXs) within range of one another, all using the same radio frequency (channel).  Now all receivers will detect a message sent by the transmitter, but only act upon it, such as raising an interrupt flag, it if the TX and RX addresses match.  To avoid chaotic communication, failed packets or on-air collisions you need each receiver to have a unique address.  Consider these like a postal address.  You should have an intuition of what would happen to your mail if both you and your neighbor had the exact same address.  Since the 2.4 GHz band can be extremely busy in public places with WiFi and Bluetooth traffic (which as an aside, Bluetooth is based on the nRF protocol), having 40 address bits seems quite sensible, as the probability of matching addresses by chance is almost zero.
So what are pipes?
If you read the nRF datasheet, you will see that in TX mode the radio can only send on using one address.  In RX mode, the radio will listen for messages on up to 6 different addresses.  Why 6?  This is likely arbitrary - a balance between register memory allocation, most probable number of nRF modules being used simultaneously and the likelihood of more efficient network topologies (such as star/tree networks) that do not require huge numbers of pipes.  A pipe represents one of these 6 addresses that a radio can receive the message and send and an ACK packet if requested.  That's all.
I hope this answer clears any confusion you had between nRF addresses and pipes.

I see, that only 6 receivers can be connected with the transmitter,

That depends on how you define "connected".  It is only possible for one transmitter to, at any one time, send data to up to 6 other devices (one per pipe). However, that is something that is very rarely done.
In practice no more than 2 pipes are needed for you to communicate with thousands of devices.
In general:

Pipe 0 is the pipe you send data on
Pipe 1 is the pipe you listen for incoming data on

You should always send on pipe 0 because that is the pipe that any ACK messages will be received on (set pipe 0's address to the address you are sending to).
With pipe 1 set to the receive address you are always ready to receive data from elsewhere.
The transmitter doesn't need to know about every other device - only the one device it is sending data to at any one moment in time.
You can set up multiple addresses on other pipes if you want to receive data that is being sent to different addresses, though there's not many circumstances where you'd want to do that (such as if you want to communicate with different pipe widths to different groups of nodes, effectively bridging between two separate networks).
In summary:

Pipe 0's address changes all the time depending on who you are sending to (assuming you are using Auto ACK)
Pipe 1's address is static and is your address that you will receive on.

To illustrate it more:

Node A has address "NODEA".
Node B has address "NODEB".
Node C has address "NODEC".

Node A has pipe 1 address set to "NODEA".
Node B has pipe 1 address set to "NODEB".
Node C has pipe 1 address set to "NODEC".

Node A sets pipe 0 address to "NODEC"
Node A sends a packet through pipe 0
Node C receives the packet on pipe 1 since it's addressed to "NODEC"
Node C responds with an ACK to its own address ("NODEC")
Node A receives the ACK on pipe 0 since it's address is "NODEC".

Node A sets pipe 0 address to "NODEB"
Node A sends a packet through pipe 0
Node B receives the packet on pipe 1 since it's addressed to "NODEB"
Node B responds with an ACK to its own address ("NODEB")
Node A receives the ACK on pipe 0 since it's address is "NODEB".

what is the difference between pipes and addresses then?

A pipe is what you communicate through. An address is where you communicate from or to.


text:
need to compare if a byte is less than 80 hex
I am using an infrared sensor called OTI301. In its data sheet it says that in order to obtain object temperature and ambient temperature values I need to extract the binary information from the sensor and use the binary information in given formulas. I have done all that but for some reason I am not getting the right values for the object temperature. The ambient temperature seems to work well but when I put a hot object, more than 320 F, the formula returns a random negative number. Also the the sensor can go up to 780 F so I know the temperature has not been capped. Please see pictures for important data sheet information, or here are the links for the complete data sheets
https://drive.google.com/file/d/1XMRDCNzY3fn0q6lkGejs5D-pqksfRuZ8/view?usp=sharing.
https://drive.google.com/file/d/1mmdkHkNbwC5VgQxGMrq07XolajNvgBkN/view?usp=sharing. Lastly, here is the part of the code where I extract the information and apply formulas.
     void loop()
 {
   if (Wire.read()) // On success, read() will return 1, on fail 0.
   {
     buttonState = digitalRead(button);
     //Serial.println(buttonState);
     Wire.beginTransmission(DEVICE_ADDRESS);
     Wire.write(0x80);  // readout command
     Wire.endTransmission(false);
     Wire.requestFrom(DEVICE_ADDRESS, 6); // request 6 bytes
     uint8_t data[6];
     for (int i = 0; i < 6; i++) {
         data[i] = Wire.read();
     }

      //Calculate Object Temperature
     if(data[5] < 0x80) {
       TA = (data[3]+ data[4]*256+data[5]*65536)/200;
     }
     else {
       TA = (((data[3]+ data[4]*256+data[5]*65536)) - 16777216) /200;
     }

     //Calculate Ambient Temperature
     if(data[2] < 0x80) {
       TA = (data[0]+ data[1]*256+data[2]*65536)/200;
      }
     else {
       TA = (((data[0]+ data[1]*256+data[2]*65536)) - 16777216) /200;
     }

What data type is TA?

on a nano, int calculations are 16 bit. A multiplication by *65536 wont work as expected if you don't force it into 32bit arithmetics.

@Majenko I defined TA as a float.

When you calculate TA you are doing integer math. Try as DataFiddler wrote and cast the numbers to long, so that the result cannot overflow

@DataFiddler: A multiplication by 65536 will work as expected, because 65536 is a 32-bit long int.

You said "I defined TA as a float." That doesn't matter. In C/C++, expressions are only "promoted" to a larger/different data type AFTER they are evaluated. Your calculations are being done using 16-bit ints, which overflow, and then cast to a float.
(C/C++ evaluates expressions from the inner-most outward, and if one of the operands to an operator is a larger type, it will "promote" the other operand to the larger type before doing a calculation. It won't notice that a calculation will overflow and promote the operands to fix that problem however.)
Try this:
   TA = (data[3]+ data[4]*256+uint64(data[5])*65536)/200;

That version of the code forces data[5] to an unsigned long before multiplying it by 65536.
Do the same thing to the value that you multiply by 65536 in all of your expressions and you should avoid overflow.

Thank you all. problem solved!

On the Nano, uint64 (I guess you mean uint64_t) is not the same as unsigned long: the latter is 32-bits only. 2. The overflow happens with data[4], not with data[5]. 3. Your formula gives grossly bad results for temperatures larger than 163.84 °C (try data = {0,0,0,0,128,0}).

overflow on data(4)? Is data an int or a byte?

The rules of integer arithmetics are tricky in C++. There are rules that
give the type of integer literals:

256 and 200 are of type int, which is the default type for
integer literals. On the Nano, this type is 16-bits, and covers the
range from −32,768 to +32,767.
65536 being too large for the int type, it is implicitly
considered a long int. This type is 32-bits on the Nano, and covers
roughly ±2.15×109.

Then there are rules for the types used in arithmetic operations. No
computation is ever done on a type smaller than int: anything smaller
is promoted to int. Then, if you combine two operands of different
types, the larger type “wins” and the compiler implicitly converts the
other operand to the larger type. Note that if two types have the same
bit size, the unsigned one is considered “larger”.
Let's go now through your formula, and see the types of the different
terms:
data[3]       = uint8_t
data[4]*256   = uint8_t * int → int
data[5]*65536 = uint8_t * (long int) → long int

Now you may see the problem. Your calculation will eventually overflow,
but the overflow is not in data[5]*65536, as one may naively expect.
What happens is than when the temperature reaches 163.84 °C (≈ 327 °F),
data[4] becomes 128, and data[4]*256 is 32,768, just too large for
an int. The result overflows to −128, hence the negative values you
see.
The simplest solution is to force 256 to be a long int, by appending
the L suffix to the number. Then the multiplication will be performed
with the long int type, and there will be no overflow:
TA = (data[3] + data[4]*256L + data[5]*65536) / 200;

On a final note, it is worth noting that the numbers 256, 65536 and
16777216 used in the formula are all powers of two. Even powers of 256.
You may notice that, save for the division by 200, what this formula
describes is the coding of an integer as a 24-bit, little-endian, two's
complement number. This format (two's complement little-endian) is
exactly what the Arduino uses internally for representing numbers. You
could then avoid all those calculations and get your result by just
telling the compiler that what those memory cells are actually holding
is a 24-bit integer:
float TA = *(__int24*)&data[3] / 200.0;

This works for both positive and negative temperatures, but it has the
drawback of breaking some C++ rules (aliasing rules), and using the
non-standard type __int24. A safest way to achieve the same is to
build a 32-bit integer by putting the bits in place using bitwise
operations. But note that then a sign-extension byte is needed to
convert the 24-bit number to 32 bits:
uint8_t sign_extension = data[5] & 0x80 ? 0xff : 0x00;
int32_t reading = (uint32_t) data[3] <<  0
                | (uint32_t) data[4] <<  8
                | (uint32_t) data[5] << 16
                | (uint32_t) sign_extension << 24;
float TA = reading / 200.0;

int32_t reading = (int32_t)(int8_t)b[5] <<16 | (uint16_t)b[4] << 8 | b[3] ; the highbyte just has to be signed, then it's still tricky but a bit simpler.


text:
Uno PWM freq conflicts with other PORTs
Am working on a small project in which I can control the speed a 24V DC Motor using a Variable resistance to A/D then generate the right PWM to an optocoupler while displaying the speed in 4 7-segments, the problem is the PWM (PORTD Pin 5) pin 5 on the Uno is not working when I Initialize any pin of PORTB (7-segment port)
int main(void)
{
  uint8 duty_cycle = 0, digit_t = 0, digit_h = 0, digit_ten = 0, digit = 0, read_index = 0, duty_old = 0;
  uint16 old_reading = 0, motor_rpm, read_average = 0;
  uint32 adc_readings = 0;
  /* Declare the 4 7-segments in the system */
  //    BCD_Segment seg_1, seg_2, seg_3, seg_4;

  //    /* Initialize the 7-segments */
  //    Segment_Init(&seg_1, B, pin0, pin1, pin2, pin3, D, pin0);
  //    Segment_Init(&seg_2, B, pin0, pin1, pin2, pin3, D, pin1);
  //    Segment_Init(&seg_3, B, pin0, pin1, pin2, pin3, D, pin2);
  //    Segment_Init(&seg_4, B, pin0, pin1, pin2, pin3, D, pin3);
  //    //
  //    ///* Turn off segments */
  //    //Segment_OFF(&seg_1);
  //    //Segment_OFF(&seg_2);
  //    //Segment_OFF(&seg_3);
  //    //Segment_OFF(&seg_4);
  /* segment pins */
  //SET_BIT(DDRB, 0);
  //SET_BIT(DDRB, 1);
  //SET_BIT(DDRB, 2);
  //SET_BIT(DDRB, 3);

    /* Enable pins */
SET_BIT(DDRD, 0);
SET_BIT(DDRD, 1);
SET_BIT(DDRD, 2);
SET_BIT(DDRD, 3);

  /* display 0*/
  //CLEAR_BIT(PORTB, 0);
  //CLEAR_BIT(PORTB, 1);
  //CLEAR_BIT(PORTB, 2);
  //CLEAR_BIT(PORTB, 3);

  /* segments off */
  CLEAR_BIT(PORTD, 0);
  CLEAR_BIT(PORTD, 1);
  CLEAR_BIT(PORTD, 2);
  CLEAR_BIT(PORTD, 3);

  uint16 adc_reading = 0;
  Boolean adc_flag = False;
  /* Declare the 4 7-segments in the system */

  /* Initialize the adc and the pwm timer */
  ADC_init();
  PWM_Init();

  while (1)
    {
      ADC_StartConversion();
      adc_flag = ADC_WaitForFlag();

      /* calculate the ADC voltage */
      adc_reading = ADC_GetValue();

      if((adc_reading <= 256) && (adc_reading >= 0))
    {
      PWM_DutyCycle(0);
    }
      else if((adc_reading > 256) && (adc_reading <= 512))
    {
      PWM_DutyCycle(50);
    }
      else if((adc_reading < 768) && (adc_reading > 512))
    {
      PWM_DutyCycle(75);
    }
      else if(adc_reading >= 768)
    {
      PWM_DutyCycle(100);
    }

      /* Clear the ADC flag */
      ADC_ClearFlag();

      /* update the pwm */
      //PWM_DutyCycle(duty_cycle);
    }
}

and here the code for the bad PWM
    int main(void)
    {
      uint8 duty_cycle = 0, digit_t = 0, digit_h = 0, digit_ten = 0, digit = 0, read_index = 0, duty_old = 0;
       uint16 old_reading = 0, motor_rpm, read_average = 0;
  uint32 adc_readings = 0;
  /* Declare the 4 7-segments in the system */
  //    BCD_Segment seg_1, seg_2, seg_3, seg_4;

  //    /* Initialize the 7-segments */
  //    Segment_Init(&seg_1, B, pin0, pin1, pin2, pin3, D, pin0);
  //    Segment_Init(&seg_2, B, pin0, pin1, pin2, pin3, D, pin1);
  //    Segment_Init(&seg_3, B, pin0, pin1, pin2, pin3, D, pin2);
  //    Segment_Init(&seg_4, B, pin0, pin1, pin2, pin3, D, pin3);
  //    //
  //    ///* Turn off segments */
  //    //Segment_OFF(&seg_1);
  //    //Segment_OFF(&seg_2);
  //    //Segment_OFF(&seg_3);
  //    //Segment_OFF(&seg_4);

  /* segment pins */
  /* just enabling one pin or all fails the PWM on PORTD PIN 5*/
  SET_BIT(DDRB, 0);
  //SET_BIT(DDRB, 1);
  //SET_BIT(DDRB, 2);
  //SET_BIT(DDRB, 3);

    /* Enable pins */
SET_BIT(DDRD, 0);
SET_BIT(DDRD, 1);
SET_BIT(DDRD, 2);
SET_BIT(DDRD, 3);

  /* display 0*/
  //CLEAR_BIT(PORTB, 0);
  //CLEAR_BIT(PORTB, 1);
  //CLEAR_BIT(PORTB, 2);
  //CLEAR_BIT(PORTB, 3);

  /* segments off */
  CLEAR_BIT(PORTD, 0);
  CLEAR_BIT(PORTD, 1);
  CLEAR_BIT(PORTD, 2);
  CLEAR_BIT(PORTD, 3);

  uint16 adc_reading = 0;
  Boolean adc_flag = False;
  /* Declare the 4 7-segments in the system */

  /* Initialize the adc and the pwm timer */
  ADC_init();
  PWM_Init();

  while (1)
    {
      ADC_StartConversion();
      adc_flag = ADC_WaitForFlag();

      /* calculate the ADC voltage */
      adc_reading = ADC_GetValue();

      if((adc_reading <= 256) && (adc_reading >= 0))
    {
      PWM_DutyCycle(0);
    }
      else if((adc_reading > 256) && (adc_reading <= 512))
    {
      PWM_DutyCycle(50);
    }
      else if((adc_reading < 768) && (adc_reading > 512))
    {
      PWM_DutyCycle(75);
    }
      else if(adc_reading >= 768)
    {
      PWM_DutyCycle(100);
    }

      /* Clear the ADC flag */
      ADC_ClearFlag();

      /* update the pwm */
      //PWM_DutyCycle(duty_cycle);
    }
}

and the output is like this

Here's the code for PWM_Init
void PWM_Init(void)
{
  /* Making the pwm pin output */
  pinMode(pin5, D, Output);

  /* fast pwm mode */
  SET_BIT(TCCR0A, WGM00);
  SET_BIT(TCCR0A, WGM01);
  CLEAR_BIT(TCCR0A, WGM02);

  /* Inverting */
  SET_BIT(TCCR0A, COM0B1);
  SET_BIT(TCCR0A, COM0B0);

  /* prescaler 1024 */
  SET_BIT(TCCR0B, CS00);
  CLEAR_BIT(TCCR0B, CS01);
  SET_BIT(TCCR0B, CS02);
}

void PWM_DutyCycle(uint8_t duty)
{
  OCR0B = (duty * 255) / 100;
}

Can you be more specific about what "bad PWM" means?

I used the fast PWM mode so the output should be continuous like the first pic, but when write to the DDRB in any pin the PWM output is like what appears in the last pic

Please show us your PWM code, like PWM_Init() and such

What is connected to pin 12?

I added the code for the PWM_Init() and PWM_DutyCycle()

for pin 12 it's not connected to anything and not even Initialized.

Re “pinMode(pin5, D, Output);”: you mean pinMode(5, OUTPUT);?

it means pin 5 of PORT D is output it writes to the DDRD register and this pin is pin5 on the UNO


text:
Finger print scanner using Arduino
Any help is greatly appreciated! Trying to build a small door lock that is controlled by a finger print sensor, (I know it will not be very practical). My issue is with putting the hardware together, I have the sensor connected to the Arduno uno with the green and yellow to pins 2 and 3 respectively, then the red and black to the ground and 5V rail. My issue is not knowing how to go about connecting the adafruit chip to the breadboard as I am going to try to use wifi for this project. Secondly I noticed most people use the adafruit Fingerprint sensor which has the module and mine is just a cheap sensor from amazon and was wondering if it will still be able to work the same? Sorry for all the questions I am very new to this and I apologize for sounding so lost haha, anything helps.

you have not told us what device you actually have ... saying that you connected yellow and green wires does not mean anything specific

You should give us a link to that fingerprint sensor. Or even better: to it's datasheet

sorry my bad, here is the link: https://www.amazon.ca/gp/product/B07TZQ6YTH/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1

There doesn't seem to be any information on the internet on how to use this device.   Did it come with any manual or documentation ?

No that is my issue,I am kind of lost now, was hoping I wouldn't have to buy a whole new sensor

please post a clear picture of the backside of the sensor .... make sure that it fills most of the frame

Just uploaded the backside of the sensor, hope the quality is good enough!


text:
Will an Arduino UNO operating at 16mHz communicate with UART / I2C with an STM32 operating at a different frequency?
I plan to connect Arduino UNO via I2C / UART with a controller based on STM32F334K8T6, whose frequency will be about 20mHz or higher.
Tell me, does the difference in clock frequencies of microcontrollers affect the operation of buses between them?
The tire speed will be equal. (UART 115200 Baud / I2C 100kHz)

20 millihertz? I guess you mean megahertz, or MHz, with a capital M.

Tell me, does the difference in clock frequencies of microcontrollers affect the operation of buses between them?

No it doesn't. Or not much any way. It may affect the accuracy of clock generation1, which may have an affect at very high asynchronous baud rates, but other than that, no.
For synchronous communication it's all synchronised to the communication protocol's clock, so processor clocks are irrelevant.

1: Baud rates are usually generated as an integer division of the system clock. Different system clocks give different results for baud rate divisor calculations, yielding marginally different baud rates. Different baud rates will have different error percentages on different system clocks. At low speeds this has no noticeable affect. At high speeds (millions of bits per second) it can cause errors to creep in.

Majenko, thank you for the answer!

Nice thorough answer.  You provided a simple yes/no answer, and then added some more nuance without obscuring the top level "doesn't matter" nature of the answer. Well done. (As usual.)


text:
Understanding analog pins in pinMode
When passing the pin number in pinMode its possible to use A0 - A7, does it apply only to that methode?
How can pinMode expect a number (is it int?) type in case of digital pin another (is it then string?) in case of analog pin?
I want to use that in my class methode, is there a way to use that and have my code more readable or should I use the pin numbers?
P.S. I have tried to read the source code but I don't understand the uin8_t (I know its a byte, but not how it can understand A5 as an int)
Tnx a lot

pinMode is actually declared as void pinMode(uint8_t, uint8_t);  in arduino.h
A0 is a defined as a number (somewhere depending on the actual hardware), on an Uno/Nano it translates to 14, and when executing pinMode it translates to the appopriate bit in the correct DDRx register.

On an atmega328 Arduino pin 14 ( or A0 ) is directed to PORTA bit 0, which can be used as a digital I/O or alternatively as an ADC channel.

The ATmega328 doesn't have a port 0. pin 14 (A0) is PC0.

Correct: PORTC Bit 0  Thanks.   In the DIP28 atmega328P-PU its Pin 23


text:
4:1: error: expected initializer before 'void'

int button

void setup()
{
 pinMode(13, OUTPUT);
 pinMode(12, OUTPUT);
 button 4;
 pinMode(4=INPUT);
}

void loop()
{
  if(digitalRead(4)== LOW);
  {
  digitalWrite (13, HIGH);
  delay (250);
  digitalWrite (13, LOW);
  digitalWrite (12, HIGH);
  delay (250);
  digitalWrite (12, LOW);
  }
 }

I need help, im new on this and i want to try something like Press button to start LOOP but it didtn work. it still telling me :4:1: error: expected initializer before 'void' and 4:1: error: expected initializer before 'void' but i still cant find a mistake on code.

You are missing a semicolon after the button declaration

Please don't post photos of the code editor, that's not useful. Paste your code in with at least four spaces ahead of each line to retain the formatting.

There's significant syntax errors in your code. I think I've caught them all.
   //int button;

   void setup() {
     pinMode(13, OUTPUT);
     pinMode(12, OUTPUT);
     // button 4;
     pinMode(4, INPUT);
   }

   void loop() {
     if (digitalRead(4) == LOW) {
       digitalWrite (13, HIGH);
       delay (250);
       digitalWrite (13, LOW);
       digitalWrite (12, HIGH);
       delay (250);
       digitalWrite (12, LOW);
     }
   }

NICE!! Thank you, I can finally start simulation. But do you know why the leds are always on? The leds doesnt react to button.

@Deepee: The button-input needs a pullup resistor to keep it HIGH when the button is not pressed. The easiest way to add one is to make pinMode(4, INPUT); read pinMode(4, INPUT_PULLUP); instead. This uses an internal pullup provided by the MCU and saves you having to install one on your board.

@JRobert Thanks :) . U solved my problem.

Also good to note about the commented out and unused button 4; : if you want to assign 4 to the variable button, you use the = operator, so button = 4;


text:
srd-05vdc-sl-c and coil operating time
I'm using Arduino UNO to control an imatic relay board with 16 relays model srd-05vdc-sl-c.
I use all the relays to control some linear actuators and everything is working fine.
My only question is: are the coils used for these relays for continuous use? I mean, can I continue to give power to some coils for more than 30 minutes? Or will they be destroyed?
Should I write a specific Arduino routine to power off all the coils when not used, or can I leave them powered for 30 or more minutes?
I checked the relays and they do not overheat.

You can leave them energized for more than 30 minutes. My 16 year old car with 250,000 km still has the original fuel pump relay. I can't imagine how many hours of continuous use it received over this period of time. The relay in my car is not the same make / model as the relays you are using, so you should check with the manufacture to see if there is a "service lifetime" specification.


text:
need at least 5 volts but 3.7 lithium polymer battery does not supply enough Voltage
I am building a device using an Arduino Nano, an OLED display and infrared thermometer sensor. I want to make it rechargeable so I am using a 1 cell lipo battery and a tp4056 circuit protection board, which cuts power at 4.2 V and 2.5 V. The OLED runs in the 5.0 V port and the sensor runs in the 3.3 V port in the Arduino. Of course the system does not work since the battery only delivers 3.7 V and when I measure the voltage in the Nano, it is actually seeing around 2.6 volts in each port (I'm assuming this drop is due to internal resistance of the cables and the protection circuit). Having said that I was thinking about using a boost converter but everything I find online says that the input voltage for the boost converter should be at least 3.5 V for it to deliver a constant 5.0 V output. This would not work since as I mentioned, the protection circuit will cut the power at 2.5 V which is well below the 3.5 V mark. Is there another practical solution I could use for this system to work with 1 cell lipo battery. I don't want to use 2 cell battery pack since it would make it more expensive and bigger in size. Also, I ran the project with a 9.0 V battery and it worked perfectly fine.

This is exactly why the typical LiPO battery shield includes a boost converter.
I'm not sure where you saw the unusually high (3.5V) low-voltage limit, but that isn't typical of most converters.

Correction I meant 3 V, but this still does not solve the problem since the tp4056 cuts power at 2.8 volts according to data sheet. Please do correct me if I am wrong. Thanks in advance.

I'm not sure what you perceive the "problem" to be. Most boost regulators will shut down once they can no longer maintain regulation. If this happens at a voltage that is higher than the level that would actually cause battery damage, that isn't really a problem -- it actually helps extend the overall life of the battery, even if the amount of use per charge is slightly less.

I would recommend using a display that does not require 5v to run.  Using a lower voltage display like an led based one will simplify the system.  My favorite thing to use is the adafruit feather huzzah8266 with the charlieplex display board on top.  They fit together via header pins and it has a built in lipo charging circuit and battery connector.  You can then wire your sensor in and voila.
https://www.adafruit.com/product/2821
https://www.adafruit.com/product/3134