text:
I2C master's output is always 255
we are using 2 Arduino UNO as a master/slave for this i2c protocol. we used the first Arduino(slave) as a sensor that will input dummy data (in this case, temperature data). the Arduino(master) should be able to output what the slave has input, but every time we run it, the output is always 255 instead of the temperature data. We don't know what is wrong with the code, but we what to read the real data. Can anyone help us? Thank you.
Here was the code we use for the Master.
// Include Arduino Wire library for I2C
#include <Wire.h>

// Define Temp Slave I2C Address
#define TEMP_ADDRESS 9

void setup()
{
  Wire.begin(); // Initialize I2C communications as Master
  Serial.begin(9600); // Setup serial monitor
  Serial.println(">>>MASTER IS READY<<<");
  Serial.println('\n');
}

void loop()
{
//Temperature
  delay(50);
  Wire.requestFrom(TEMP_ADDRESS, 12);
  Serial.print("TEMP ADDRESS: ");
  Serial.println(TEMP_ADDRESS);
  Serial.println("Receive data from TEMP Slave");
  byte MasterReceivedTemp = Wire.read();
  Serial.print("Temperature = ");
  Serial.println(MasterReceivedTemp);
  Serial.println('\n');
}

You're requesting 12 bytes from the slave? Is the slave expecting you to ask for 12 bytes?

Chances are you're "reading" -1 (which is 255 when squeezed into a byte)n which means "no data available to read".

Are you sure,you are really reaching the slave? You are reading data with Wire.read(), without checking, if there is actually data in the buffer. If there isn't, read will return -1, which then gets to be 255, when downcasted to byte. Print out the return value of Wire.requestFrom(), which shows the number of actually read bytes. Have you checked with the I2C Scanner example, if the slave is really found at that address?


text:
how to serially off leds in an esp running mqtt
hi im using at tiny 85 to monitor dc switches and to serial print with this code
below to esp8266 with local broker to turn leds on and off but its only working through mqtt but not with physical switches which are connected to at tiny 85. please help this is my mqtt code
//////at tiny code///
#include <SendOnlySoftwareSerial.h>

SendOnlySoftwareSerial myserial (4);  // Tx pin

int sw1 = 0;
int sw2 = 1;
int sw3 = 2;
int sw4 = 3;

int sta1 = 0;
int sta2 = 0;
int sta3 = 0;
int sta4 = 0;

bool st1 = false;
bool st2 = false;
bool st3 = false;
bool st4 = false;
void setup () {

  myserial.begin(9600);
  pinMode(0, INPUT);
  pinMode(1, INPUT);
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, OUTPUT);

  }
void loop ()
{
  sta1 = digitalRead(sw1);
  sta2 = digitalRead(sw2);
  sta3 = digitalRead(sw3);
  sta4 = digitalRead(sw4);
  if (sta1 == HIGH && st1 == false){
    myserial.println("sw1 on");
    st1 = true;
    delay(1);
  }
    else if (sta1 == LOW && st1 == true){
      myserial.println("sw1 off");
      st1 = false;
      delay(1);
    }

   if (sta2 == HIGH && st2 == false){
    myserial.println("sw2 on");
    st2 = true;
    delay(1);
  }
    else if (sta2 == LOW && st2 == true){
      myserial.println("sw2 off");
       st2 = false;
      delay(1);
    }

   if (sta3 == HIGH && st3 == false){
    myserial.println("sw3 on");
     st3 = true;
    delay(1);
  }
    else if (sta3 == LOW &&  st3 == true){
      myserial.println("sw3 off");
       st3 = false;
      delay(1);
    }
   if (sta4 == HIGH &&  st4 == false){
    myserial.println("sw4 on");
    st4 = true;
    delay(1);
  }
    else if (sta4 == LOW&& st4 == true){
      myserial.println("sw4 off");
      st4 = false;
      delay(1);
    }

}

//////esp mqtt code///////
//ItKindaWorks - Creative Commons 2016
//github.com/ItKindaWorks
//
//Requires PubSubClient found here: https://github.com/knolleary/pubsubclient
//
//ESP8266 Simple MQTT light controller

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

int LED3 = D2;
int LED4 = D4;
int LED2 = D3;
int LED1 = D5;

String data ;
// the number of the pushbutton pin

//EDIT THESE LINES TO MATCH YOUR SETUP

#define MQTT_SERVER "192.168.43.223"
const char* ssid = "kuro";
const char* password = "qwertyui";

//LED on ESP8266 GPIO2

char* lightTopic = "/test/light1";
char* lightTopic1 = "/test/light2";
char* lightTopic2 = "/test/light3";
char* lightTopic3 = "/test/light4";

WiFiClient wifiClient;
void callback(char* topic, byte* payload, unsigned int length);
PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);

void setup() {
  //initialize the light as an output and set to LOW (off)
  Serial.begin(9600);
  pinMode(LED3 , OUTPUT);
  pinMode(LED4 , OUTPUT);
  pinMode(LED1 , OUTPUT);
  pinMode(LED2 , OUTPUT);

    delay(100);

    // We start by connecting to a WiFi network

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

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

  if (Serial.available()>0) /* If data available at serial port, enter if loop */
  {
    data = Serial.readStringUntil('\n'); /* Read data present at serial port */
    /* Print string with \r\n */
    Serial.println(data); /* Print data received */
  }
    Serial.println("");
    Serial.println("WiFi connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());

}

void loop(){
  //reconnect if connection is lost
  if (!client.connected() && WiFi.status() == 3) {reconnect();}

  //maintain MQTT connection
  client.loop();

  //MUST delay to allow ESP8266 WIFI functions to run
  delay(10);
}

void callback(char* topic, byte* payload, unsigned int length)
{
  //convert topic to string to make it easier to work with
  String topicStr = topic;

  //Print out some debugging info
  Serial.println("Callback update.");
  Serial.print("Topic: ");
  Serial.println(topicStr);

 if(topicStr.equals(lightTopic)||Serial.available()){

   if(payload[0] == '1' || data.equals ("sw1 on")){
      digitalWrite(LED1 , HIGH);
    }

    else if (payload[0] == '0'|| data.equals ("sw1 off")){
      digitalWrite(LED1 , LOW);
    }
 }
 if(topicStr.equals(lightTopic1)||Serial.available()){

   if(payload[0] == '1'|| data.equals ("sw2 on")){
      digitalWrite(LED2 , HIGH);
    }

    else if (payload[0] == '0'|| data.equals ("sw2 off")){
      digitalWrite(LED2 , LOW);
    }
 }
 if(topicStr.equals(lightTopic2)||Serial.available()){

   if(payload[0] == '1'|| data.equals ("sw3 on")){
      digitalWrite(LED3 , HIGH);
    }

    else if (payload[0] == '0'|| data.equals ("sw3 off")){
      digitalWrite(LED3 , LOW);
    }
 }
  if(topicStr.equals(lightTopic3)||Serial.available()){

   if(payload[0] == '1'|| data.equals ("sw4 on")){
      digitalWrite(LED4 , HIGH);
    }

    else if (payload[0] == '0'|| data.equals ("sw4 off")){
      digitalWrite(LED4 , LOW);
    }
  }

}

void reconnect() {

  //attempt to connect to the wifi if connection is lost
  if(WiFi.status() != WL_CONNECTED){
    //debug printing
    Serial.print("Connecting to ");
    Serial.println(ssid);

    //loop while we wait for connection
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }

    //print out some more debug once connected
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }

  //make sure we are connected to WIFI before attemping to reconnect to MQTT
  if(WiFi.status() == WL_CONNECTED){
  // Loop until we're reconnected to the MQTT server
    while (!client.connected()) {
      Serial.print("Attempting MQTT connection...");

      // Generate client name based on MAC address and last 8 bits of microsecond counter
      String clientName;
      clientName += "esp8266-";
      uint8_t mac[6];
      WiFi.macAddress(mac);
      clientName += macToStr(mac);

      //if connected, subscribe to the topic(s) we want to be notified about
      if (client.connect((char*) clientName.c_str())) {
        Serial.print("\tMTQQ Connected");
        client.subscribe(lightTopic);
        client.subscribe(lightTopic1);
        client.subscribe(lightTopic2);
        client.subscribe(lightTopic3);

      }

      //otherwise print failed for debugging
      else{Serial.println("\tFailed."); abort();}
    }
  }
}

//generate unique name from MAC addr
String macToStr(const uint8_t* mac){

  String result;

  for (int i = 0; i < 6; ++i) {
    result += String(mac[i], 16);

    if (i < 5){
      result += ':';
    }
  }

  return result;
}

Maybe you should add some code to the ESP8266 that reads from serial and does something depending on what has been read?

shouldn't the code for reading Serial be in loop(), not in setup()?

Majenko is right, you just don't have any code, that would read and process serial input on the ESP (besides the bit in setup, which is only called once at startup), thus it will not react to serial data. The solution: Program the ESP to read the serial data and process it. Then you can write code, that reacts to serial data

hi thank you everyone, so i wrote another code to just print and blink an led, its printing fine but not turning the led on/off ```String command;
int led = 3;
void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop() {
if(Serial.available()>0){
command = Serial.readString();
Serial.print(command);
    if(command.equals ('sw4 on')){
        digitalWrite(led , HIGH);
    }
    else if(command.equals ('sw4 off')){

        digitalWrite(led , LOW);
    }

}

}```

' is for char. use ". the text sent from atiny with println ends with \r\n so it is not equal to "sw4 on".

thank you so much juraj that must be it now i got it working

source: Stack Exchange

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

sort: votes


text:
Having problems with running two 74HC595 as a single 16bit shift register
I'm using two of these together to create a single 16bit register which will give me access to 16 outputs. I have gotten them to work but not exactly how I imagined them to work. The code written is for a 18650 cell charger/discharger. The first 6 bits (0-5) of the shift register will be connected to 6 NPNs which will turn on or off each of their tp4056s connected in series. The next 6 bits (5-11) will be connected to 6 different constant current loads. The user selects if they want to charge or discharge their cell and depending on the mode, that particular cell's charger or current sink is turned on (but both not on the same time). In reality, I have to firstly shift 6 bits manually by selecting a mode and then pressing select for all 6 cells in the register for it to show something and even after that it misses bits randomly. btw last 4 bits (12-15) will also get used in the final product. For experimenting, I've connected LEDs to all outputs.
#include <Arduino.h>
#include <LiquidCrystal_I2C.h>
#include <Encoder.h>

//initalisation
LiquidCrystal_I2C lcd(0x27, 20, 4);
Encoder encoder(2, 3);

//software constants
const int numOfCells = 6;
const int analogInput[numOfCells] = {A0, A1, A2, A3, A6, A7};
const float arduinoPowerLine = 4.80;
const long interval = 60000; //60 seconds
const char* functions [2] = {"CHARGE   ", "DISCHARGE"}; //mode select array
const int dataPin  = 12;//DS - pin 9
const int latchPin = 11;//ST_CP --pin12
const int clockPin = 8;//SH_CP --pin11

//Encoder setup
long oldPostion = -999;
long newPostion = 0;
long prevPostion;

//making battery arrays and setting their default flags
double batteryVoltage[numOfCells];
bool noBatteryFlag[numOfCells] = {LOW, LOW, LOW, LOW, LOW, LOW};
float minimum = 3.00; //Cutoff voltage
float capacity[numOfCells];

//mode variables
int modeState[numOfCells];
int confirmedModeState[numOfCells];

//button setup
int inputPin = 5;
int inputState;
int lastInputState = LOW;
int inputFlag = LOW;

//debounce timer
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

//lcd varuables
int currentCell = -1;

//Cell timers
unsigned long prevMillis[numOfCells];
int minute[numOfCells];
unsigned long currentMillis;

//shift resister variables
word outputs = 0B0000000000000000;

void updateShiftRegister(word bits){//takes bits from the resolvemode function and sets them appropriately
  byte resisterOne  = lowByte(outputs);//right most byte
  byte resisterTwo = highByte(outputs);//left most byte
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, resisterTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, resisterOne);
  digitalWrite(latchPin, HIGH);
}
void setup() {
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  pinMode(inputPin, INPUT_PULLUP);
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin,  OUTPUT);
  pinMode(clockPin, OUTPUT);
  updateShiftRegister(outputs);//Resets all shift resister output to LOW
}
void BatteryVoltage(){//reading each cells and converting the adc value into voltage
  for (int i = 0; i < numOfCells; i++){
    int reading = analogRead(analogInput[i]);
    batteryVoltage[i] = (reading * arduinoPowerLine) / 1023;
    //flagging stuff
    if (batteryVoltage[i] <= 0.50) {//checking if a battery is inserted in the holder
    noBatteryFlag[i] = HIGH;
    }else{
      noBatteryFlag[i] = LOW;
    }
  }
}
void ButtonDebounce(){//checking input state and flaggint button
  int reading = digitalRead(inputPin);
  if (reading != lastInputState){
    lastInputState = millis();
  }
  if ((millis() - lastInputState > debounceDelay)){//debouncing button
    if (reading != inputState){
      inputState = reading;
      if (inputState == HIGH) {
        inputFlag = HIGH;
      }
    }
  }
  lastInputState = reading;
}
void ResolveFlags(){
   if (inputFlag == HIGH){ //incrementing currentscreen
       if (currentCell == numOfCells - 1){ //if counter at its limit ,it wraps back to the start
        currentCell = 0;
      } else {
        currentCell++;
      }
      confirmedModeState[currentCell] = modeState[currentCell]; //mode selected in stored
      lcd.clear();//clears lab every time button is pressed
        inputFlag = LOW;
  }
}
void BatteryTimeKeeper(){//keeping track of battery time while it is discharging
for (int i = 0; i < numOfCells; i++){
  if (currentMillis - prevMillis[i] > interval){
    if (noBatteryFlag[i] == LOW){//if a battery is in the holder
      if (batteryVoltage[i] > minimum){//and if it is greater then 3v, it can be discharged
   minute[i]++;
   prevMillis[i] = currentMillis;
  }
  if (batteryVoltage[i] <= minimum){
    capacity[i] = (minute[i] / 60) * 500; //total time taken divided by 500mA (constant current load)
    minute[i] = 0;
    }
  }
}
    if (noBatteryFlag[i] == HIGH){//if a battery is removed, its timer is reset back to 0
      minute[i] = 0;
    }
  }
}
void EncoderFunctionNavigator(){//tracks encoder
  newPostion = encoder.read();
  if (newPostion != oldPostion){
    oldPostion = newPostion;
  }
  if(prevPostion < newPostion){
    modeState[currentCell]++;
  } else if(prevPostion > newPostion){
    modeState[currentCell]--;
  }
  if (modeState[currentCell] == 2){ //wraps back selection mode
    modeState[currentCell] = 0;
  } else if (modeState[currentCell] < 0){
    modeState[currentCell] = 1;
  }
}
void ResolveMode(){//sets shift resister output on or off depending on the mode selected
  for (int i = 0; i < numOfCells; i++){
    if (confirmedModeState[i] == 0){
      bitWrite(outputs, i, HIGH) && bitWrite(outputs, i+6, LOW);
    } else if (confirmedModeState[i] == 1){
      bitWrite(outputs, i, LOW) && bitWrite(outputs, i+6, HIGH);
    }
    updateShiftRegister(outputs);
  }
}
void PrintScreen(){//printing all the info in lcd
  lcd.home();
  int cellCounter = currentCell + 1; //this is here because I have ocd
  char buffer[25];
  sprintf(buffer, "Cell#:%d    %s", cellCounter, functions[modeState[currentCell]]);
  lcd.print(buffer);
  lcd.setCursor(0, 1);
  lcd.print("VOL:");
  lcd.setCursor(4, 1);
  lcd.print(batteryVoltage[currentCell]);
  lcd.setCursor(0, 2);
  lcd.print("Cap:");
  lcd.setCursor(4, 2);
  lcd.print(capacity[currentCell]);
}
void loop() {
 currentMillis = millis(); //main currentmillis variable
 BatteryVoltage();
 BatteryTimeKeeper();
 ButtonDebounce();
 EncoderFunctionNavigator();
 ResolveFlags();
 PrintScreen();
 ResolveMode();
 prevPostion = newPostion; //records the last postion of encoder
}

Its register, not resistor

Have you tried a simple test sketch with only the shift registers tl test, if they work as expected? Have you checked, if the data, that you want to shift out, is exactly what you expect it to be (through printing it over serial beforehand)? And why are you updating the shift registers for every bit, that you set in ResolveMode()? I would first set every bit in the data, that needs to be set, and then at the end update the shift registers only once with all new data at once

And what do you mean by "missing bits randomly"? Please explain exactly, what you were expecting and what actually happened

register* my bad.  Yes I have tried a simple sketch and I can toggle all the different bits and by missing bits I mean randomly one led stops working in the middle

That's a good idea, ill try it and report back my results. thankyou for your answer

@chrisl yep your solution worked a treat. With your solution and moving resolveMode() up made it all work.

To put the comments into an answer:
You are controlling the shift registers in this function
void ResolveMode(){//sets shift resister output on or off depending on the mode selected
  for (int i = 0; i < numOfCells; i++){
    if (confirmedModeState[i] == 0){
      bitWrite(outputs, i, HIGH) && bitWrite(outputs, i+6, LOW);
    } else if (confirmedModeState[i] == 1){
      bitWrite(outputs, i, LOW) && bitWrite(outputs, i+6, HIGH);
    }
    updateShiftRegister(outputs);
  }
}

Since the updateShiftRegister() call is inside the for loop, you are updating the shift registers for every bit, that you set. I guess this is the point, where you get your weird behavior. You don't need to update for every bit. Instead change all needed bits inside the outputs variable, and then at the end of ResolveMode() you can update the registers with all data at once.
So just move updateShiftRegister(outputs); one line down to outside of the for loop.

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


text:
How to interpret Serial data received by Bluetooth module
I'm experimenting with a hc-05 knockoff the JDY-30 and am confused about the Serial data I'm getting from it. I downloaded an app called BlueUino to send commands from my Android to my Arduino Uno via Bluetooth. I then print the data I get via Serial port using the code below:
  if(Serial.available() > 0){ // Checks whether data is comming from the serial port
    state = '1'; //Serial.read(); // Reads the data from the serial port0
    stateData = Serial.read();
    sprintf(data, "Data is %u", stateData);
    Serial.println(data);
    Serial.println();
 }

Here are some of the results I get in the log which I can't make sense of. For example, sending the string "def" doesn't contain the sequence of data from sending the command "e". Also, how does one convert these values to characters ?
Send Command "b"
Data is 128
Data is 0
Data is 248

Send Command "abc":
Data is 120 // doesn't contain the sequence of Data of "b"
Data is 120
Data is 120
Data is 0
Data is 120
Data is 0
Data is 248

Sounds like you have a baud rate mismatch.

you are correct from looking at datasheet. thank you!

seems to work now. But still wondering how to convert data to characters. Example: 'b' is received as '98'. Where do i look up the corresponding char for the data?

nvm ascii table

98 and b are the same thing. Just different ways of representing the data.

replace %u with %c

Or just storing the inbound data in a char type and use single quotes when parsing incoming bytes so that the compiler knows your dealing with ASCII, print them out on serial and they should be familiar characters, of course with the baud rate mismatch fixed

This might be sending the data in bytes so convert it and then try. You can convert it by doing String(data).


text:
Looping a defined function to show live variables printed on OLED screen
I have started a thread on the Arduino forum. If someone could have a look at the thread and give me some help either here or there that would be great. (I don't want to have to add all the information from that thread into this one).
https://forum.arduino.cc/index.php?topic=691659.15
The background of the code is that I am trying to call a function within the void loop() and make it loop so that it updates values on the OLED screen for temperature and humidity from a sensor. I have had this working before, but now I have a menu and cant run it straight from the void loop() as I have a menu structure.
Hi, I have been working on this project where I am monitoring and controlling humidity/temperature for a humidor I am going to build. I am using an OLED screen and right now i've been designing the menu/ UI. I know that the code right now isnt the best but I have just been trying to make it work then finalise the workings and details once its fully working. (sorry im not a big commentor in my code). I am using a rotary encoder to navigate the menu.
    if (value == 0){ //Encoder Position
Menu();
display.setTextSize(1);
display.setCursor(0,15);
display.print(">");
display.display();
  if(buttonState== LOW){ //If encoder is pressed
    value = 6;
    while (value == 6){
      MainDisplay(t,h);
    }
}

This is the problem I have, I want to call the MainDisplay() function which displays the temperature and humidity easily to read, I have tried to use a while loop while runs the function while the encoder value is equal to 6, but when I try to loop this function the OLED screen freezes and so does the serial readout in the IDE. This function calls fine when I don't try to loop it, however that isn't very useful because the screen will only display the temp & humidity from when the function is called and remains stationary.
I'm pretty new to arduino code and this is my first project, so any help or advice would be very much appreciated. Once again, I know the other parts of the code may not be the most efficient but I plan to fix this when I get the code to work and I will tidy it up.
I want this loop to run for long peroids of time because the mainDisplay() function will be on the display when not operating. I have tried changing it so when the encoder button is pressed it will exit the loop but the same thing is happening. The loop doesn't run with the code shown, the arduino just crashes and must be reset. For the other options in the menu they work fine to call the function when selected, however they aren't being looped, and they are exited when the encoder position is lowered.
Here is the full code.
#include <ClickEncoder.h>
#include <TimerOne.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "DHT.h"
#define DHTPIN 12     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE);

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define Pa 2 //Encoder Pin A
#define Pb 3 //Encoder Pin B
#define SW A1 //Encoder Button

ClickEncoder *encoder;
int16_t last, value;
const int buttonPin = SW; //Encoder Button
int buttonState;    // variable for reading the pushbutton status
int standby = 15;
int leftnumber;

float t;
float h;
float highT;
float lowT = 50;
float highH;
float lowH = 100;

void timerIsr() {
  encoder->service();
}

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

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

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  encoder = new ClickEncoder(Pa, Pb, SW);
  Timer1.initialize(1000);
  Timer1.attachInterrupt(timerIsr);
  last = -1;
    // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);

 Menu();
}

void MainDisplay(float t, float h){

  //RESET
  //delay(100);
  display.clearDisplay();

  //TEMP1
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("Temperature: ");
  display.setTextSize(2);
  display.setCursor(0,10);
  display.print(t);
  display.print(" ");
  display.setTextSize(1);
  display.cp437(true);
  display.write(167);
  display.setTextSize(2);
  display.print("C");
  //HUMIDITY1
  display.setTextSize(1);
  display.setCursor(0, 35);
  display.print("Humidity: ");
  display.setTextSize(2);
  display.setCursor(0, 45);
  display.print(h);
  display.print(" %");

  //ICON-*Flashes*
  display.fillRoundRect(100, 10, 20, 44, 2, WHITE);
  display.setCursor(105,15);
  display.setTextColor(BLACK);
  display.print("J");
  display.setCursor(105,35);
  display.print("B");
  display.display();
  //delay(20);
  //display.fillRoundRect(100, 10, 20, 44, 2, WHITE); //FLASH (copy Temp1 & Humidity1)

}
void Menu(){

    //TITLE
    display.clearDisplay();
    delay(50);
    display.setTextColor(WHITE);
    display.setTextSize(2);
    display.setCursor(40,0);
    display.print("MENU");
    //MENU1 Temp
    display.setTextSize(1);
    display.setCursor(10,25);
    display.print("Temperature Set");
    //MENU2 Humid
    display.setCursor(10,35);
    display.print("Humidity Set");
    //MENU3 Setting
    display.setCursor(10,45);
    display.print("Settings");
    //24HR Min/Max
    display.setCursor(10,55);
    display.print("Daily Min/Max");
    //RETURN
    display.setCursor(10,15);
    display.print("Main Display");

    display.setCursor(115,0);
    display.print(value);

    display.display();

}

void TempMenu(){ //Set Temperature
 value = 6;
 //ActualTEMP
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("Set Temperature =");
  display.setTextSize(1);
  display.cp437(true);
  display.write(167);
  display.setTextSize(2);
  display.print("C");
  display.display();
}
void HumMenu(){

}
void SetMenu(){

}
void MaxMenu(){ //Max/Min Temp&Hum
  value = 6;
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.setCursor(30,0);
  display.print("MIN/MAX");
  display.setTextSize(1);
  display.setCursor(0,25);
  display.print("Max Temperature=");
  display.print(highT);
  display.setCursor(0,35);
  display.print("Min Temperature=");
  display.print(lowT);
  display.setCursor(0,45);
  display.print("Max Humidity =");
  display.print(highH);
  display.setCursor(0,55);
  display.print("Min Humidity =");
  display.print(lowH);
  display.display();
}

void loop() {
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit
  float f = dht.readTemperature(true);

    if (t > highT){
      highT = t; //Highest Temperature
  }
    if (t < lowT){
      lowT = t; //Lowest Temperature
  }
    if (h > highH){
      highH = h; //Highest Humidity
  }
    if (h < lowH){
      lowH = h; //Lowest Humidity
  }

  value += encoder->getValue();
  if (value != last) {
    last = value;
    Serial.print("Encoder Value: ");
    Serial.println(value);
 }
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  // check if the pushbutton is pressed. If it is, the buttonState is LOW:

    if(value < 0){
      value = 0; // Doesnt allow encoder to go below 0
  }

    if (value == 0){ //Encoder Position
    Menu();
    display.setTextSize(1);
    display.setCursor(0,15);
    display.print(">");
    display.display();
      if(buttonState== LOW){ //If encoder is pressed
        value = 6;
        while (value == 6){
          MainDisplay(t,h);
        }
    }
  }

    if (value == 1){ //Encoder Position
    Menu();
    display.setTextSize(1);
    display.setCursor(0,25);
    display.print(">");
    display.display();
      if (buttonState == LOW){ //If encoder is pressed
        TempMenu();
      }
  }
    if (value == 2){ //Encoder Position
    Menu();
    display.setTextSize(1);
    display.setCursor(0,35);
    display.print(">");
    display.display();
      if (buttonState == LOW){ //If encoder is pressed
        HumMenu();
      }
  }
    if (value == 3){ //Encoder Position
    Menu();
    display.setTextSize(1);
    display.setCursor(0,45);
    display.print(">");
    display.display();
      if (buttonState == LOW){ //If encoder is pressed
        SetMenu();
      }
  }
    if (value == 4){ //Encoder Position
    Menu();
    display.setTextSize(1);
    display.setCursor(0,55);
    display.print(">");
    display.display();
          if (buttonState == LOW){ //If encoder is pressed
        MaxMenu();
      }
  }
}

I have had responses which have provided no solution. I came here to try and get some better advice as I have had better responses on stackoverflow in the past with other situations.

couple of things stand out ... the cursor movement code should be totally separate from the button press code .... all of the if (value == x) statements should be eliminated because the cursor position can be calculated display.setCursor(0,value * 10 + 15 ); .... put the button press code after the cursor code .... the button press code should run only once when the button transition happens .... it should not repeat if the button is held down .... use if (value == x) statements to choose the correct menu to display

look at the code where you update the highest/lowest ... if there is a change, then also set a flag, such as minmax_change = true; ... check if temperature and humidity have changed ... set flag temp_hum_change = true; .... further down in your code, check if the current screen should be refreshed


text:
Fast random booleans
I am looking for a way of generating booleans rapidly. For booleans, one usually uses random(0,2); but in my case I need about 250 booleans and calling random every time is slow.
So I thought about using all bits of a random number on the whole range as such:
randomSeed(100); // A seed to always keep the same sequence
long rdm = random(MIN,MAX);  // Generate a number in range MIN,MAX of type long
long mask = 1;
for(int i=0; i<32; i++){
    if((rdm>>i)&mask){
        //do something
    } else {
        //do something else
    }
}

But with this I have three questions:

What are MIN and MAX so that the LONG random uses all bits, with value ranging from -2,147,483,648 to 2,147,483,647 (arduino long type). I tried several MIN and MAX, also simply random(); but without success.
Is it a valid approach? Do I expect each bit to be uniformly distributed? Should I use fewer bits, e.g. random(0, 2^16); for a "better" distribution?
Is there some seed known to be good or bad at this?

My project
I am working on a device made of Neopixel LED strips. It is for a visual neuroscience experiment where each "pixel" is either ON or OFF. I need the speed to be able to reach high refresh rate (60-100Hz), with normal statistical distribution to avoid bias in neuron response analysis. With this approach, I can reach the desired speed but I'm concerned about the statistics. So I need a better understanding of random()'s behaviour to do it right!

are you sure it will be faster?

Good pseudorandom number generators are few and far between. I would not trust one from a microcontroller's library, which is optimized for speed rather than optimal statistic properties. On AVR, I would prefer the underlying no-parameter random(), which has 31 usable bits, over the one from the Arduino core, which only adds bugs. And I strongly recommend you test for the statistical properties you care about before committing to any PRNG.

@Juraj yes it's faster. Including the communication with Neopixel, when I was drawing one boolean per LED, I was displaying at around 30-40Hz. With this method I need only 8 random numbers to get the 250 bits, that allow me to display at 100Hz.
Quick benchmark (Arduino Uno) to assign value to each LED (237 total):
This method: 1.6ms  --
One rand per LED: 22ms --
(Neopixel communication: 2.05ms)

@EdgarBonet Thanks for the advice, I'll use just random() then to have the 31 bits. I'm using fixed seeds so I'm also checking how they distribute.

@Juraj I think this blog post is a relevant benchmark

I didn't try myself, but in the documentation it shows the MAX value is  2,147,483,647, which is 2^31-1. The MIN value I expect is -2^31, thus -2,148.483.648. Wondering what you mean by 'without success'.
Yes this is a valid approach. A 'perfect' random generator should be able to generate all values with an equal distribution. Since the values are within [-2^31, 2^31-1] this means all values within a 32 bit value is used, which automatically means all bits are also evenly distributed. So you can pick individual bits (as long as you use the entire MIN/MAX range).
In principle all seeds are good, as long as they are random. In the documentation it is advised to take an unconnected analog pin value. If you don't have one unconnected, you can use e.g. the millis function.

Arduino's two-parameter random() won't work as expected if max-min is larger than LONG_MAX.

@EdgarBonet Seems to me like a bug in the original Arduino (library). Using t hat library you refer to, or using 31 bits instead of 32 is than a solution. 8 instead of 7 calls needed, to get 250 booleans.

I wanted to show the weird output I got for MIN-MAX [-2^31, 2^31-1], but the source code say enough already. Thanks @Edgar

@Michel On the second point, I was more wondering specifically about the implementation in Arduino. Is it good enough to assume that all 31 bits are uniformly distributed? If not, taking for example only the first 24 bits should give better results, right? The previously assumed uniformity for these 24 bits is now an average of 2^7 values.

If the values returned are evenly distributed, it would not matter if you check bits one by one or the total value. Assume you use [0... max] and get a uniformly distributed 31-bit values, using 24 bits or 31 bits will not make the accuracy or results better.

After going around Wikipedia on pseudo-random generators, what I understand now is that the generator used in Arduino is a full-period generator. original paper. I thought differently. And please correct me if I'm wrong.

The random() function returns a number between 0 and RANDOM_MAX (0x7FFFFFFF). The random(min, max) function takes the value from random() and manipulates it to fit into the specified range (calculate the offset difference, modulus the random value by that difference, then add the lower offset).
That means that the widest range you can get is from random() directly, whilch is the same as random(0, RANDOM_MAX). However that is only ever going to be 31 bits, so your most significant bit will always be zero.
That's not what you want.
The best you can do to get 32 bits of random data is to take two random 31 bit values and combine them. Maybe left shifting one value by one bit and the XORing them together would be enough:
uint32_t rand1 = random();
uint32_t rand2 = random();
uint32_t fullrand = (rand1 << 1) ^ rand2;

Alternatively just working with 31 bits instead of 32 may be enough for your needs and would be faster than generating two numbers and combining them just to fill that one extra bit.

Thanks also for your answer, it adds to the comments of @Edgar. I was trying to understand why I was limited to 31 bits and now it's clear. 31 bits will do perfectly fine.

random(0, RANDOM_MAX) returns a random number between 0 and RANDOM_MAX-1 (inclusive), with 0 twice as likely as the other outputs.

Naaaasty. A good enough reason not to use Arduino's horrible overloaded versions of a standard library function.


text:
Radino40 Breakout Board
I would like to control the Radino40 breakout board with arduino. But i don't know if is it possible. I know that the single Radino40 DW1000 antenna could controlled by Arduino through SPI, but my board haven't this connection.

I think that the idea is you program the Radino40 directly with your own code. No reason you couldn't write code that accepts some data over serial from an Arduino.

I think so. The schematics of this board aren't clear and the documentation is bad. There are, available, more then 32 pin but i don't know how to connect.

It shows RX and TX pins, which implies that it has a UART, and it also has a micro USB connector. I don't see any indication of an SPI connection from the (scant) documentation.

it is a nRF52840 programmable over SWD. you can code for it with mbed or as Arduino with Arduino mbed package if you create a board definitions based on Arduino Nano 33 BLE board variant (it is nRF52840 too) and burn the Arduino bootloader


text:
Problem with gps.encode() using TinyGPS library
First, see the schematics (attached).
The GPS is working properly when I write code only for reading data from it as below:
//Connect with pin 18 and 19
#include <TinyGPS.h>
//long   lat,lon; // create variable for latitude and longitude object
float lat,lon; //notice herewhy lon is not ina   get same same
TinyGPS gps; // create gps

void setup()
{
  Serial.begin(57600); // connect serial    for TFT
Serial.println("The GPS Received Signal:");
Serial1.begin(9600); // connect gps sensor    for GPS
  }

void loop(){

    while(Serial1.available()){ // check for gps data

      delay(1000);

        Serial.println( Serial1.read());

    if(gps.encode(Serial1.read()))// encode gps data
    {
    gps.f_get_position(&lat,&lon); // get latitude and longitude

    Serial.print("Position: ");

    //Latitude
    Serial.print("Latitude: ");
    Serial.print(lat,6);
    Serial.print(",");

    //Longitude
    Serial.print("Longitude: ");
    Serial.println(lon,6);

   }
  }
}

In the above code, when I print serial data coming from GPS, it is like 44,65,46,48,57,44,13,10,84.... and then gps.encode() function encodes it properly and returns true and ultimately I get correct values of longitude and latitude.
Now, the problem is when I use that same code along with my TFT code, it does not read serial data correctly and prints like 0,44,0,57,0,10,0,44,0,50,0,44... and the gps.encode() function always returns false. and I am unable to get any values of longitude and latitude.
Here is the complete code of TFT + GPS:
#include <stdlib.h>
#include <SPI.h>
#include <Wire.h>      // this is needed even tho we aren't using it
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <Adafruit_STMPE610.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>

TinyGPS gps; // create gps

void Draw_Compass_Rose();
void display_item(int x, int y, String token, int txt_colour, int txt_size);
void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour);

// For the Adafruit TFT shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// The STMPE610 uses hardware SPI on the shield, and #8
#define STMPE_CS 8
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

/*** UI details */
#define BUTTON_X 40
#define BUTTON_Y 140
#define BUTTON_W 60
#define BUTTON_H 30
#define BUTTON_SPACING_X 20
#define BUTTON_SPACING_Y 10
#define BUTTON_TEXTSIZE 2

/* Back Button details */
#define BACK_BUTTON_X 40
#define BACK_BUTTON_Y 40

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

// text box where numbers go,position the text box/rectangle
#define TEXT_X 10
#define TEXT_Y 10
#define TEXT_X1 10
#define TEXT_Y1 50
#define TEXT_X2 10
#define TEXT_Y2 90
#define TEXT_W 220
#define TEXT_H 30
#define TEXT_TSIZE 3
#define TEXT_TCOLOR ILI9341_MAGENTA
// the data (phone #) we store in the textfield
#define TEXT_LEN 12
char latitude[TEXT_LEN+1] = "";
char longitude[TEXT_LEN+1] = "";
uint8_t latitude_i=0;
uint8_t longitude_i=0;
char STATUS_X;
char STATUS_Y;
float lat = 0.0;
float lon = 0.0;
float AZMTH = 0.0;
float add;

const int centreX  = 160;
const int centreY  = 120;
const int diameter = 100;
int last_dx, last_dy, dx, dy;

// 0 -> Keypad    1 -> Compass
unsigned int page_state = 0;

// 0 -> latitude     1 -> longitude
unsigned int cursor_state = 0;

/* create 15 buttons, in classic candybar phone style */
char buttonlabels[15][5] = {"ENT", "CLR", "NEXT", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", ">"};
uint16_t buttoncolors[15] = {ILI9341_DARKGREEN, ILI9341_DARKGREY, ILI9341_RED,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_ORANGE};
Adafruit_GFX_Button buttons[15];

char backButtonLable[1][5] = {"Back"};
uint16_t backButtonColors[1] = {ILI9341_DARKGREEN};
Adafruit_GFX_Button backButton[1];

// Print something in the mini status bar with either flashstring
void status(const __FlashStringHelper *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}
// or charstring
void status(char *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}

void setup() {
Serial.begin(57600); // connect serial
Serial.println("The GPS Received Signal:");
Serial1.begin(9600); // connect gps sensor

  // clear the screen
  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_MAGENTA);
  tft.print("      WELCOME TO AZIMUTH SYSTEM");
  // eep touchscreen not found?
  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");

  // create buttons
  for (uint8_t row=0; row<5; row++) {
    for (uint8_t col=0; col<3; col++) {
      buttons[col + row*3].initButton(&tft, BUTTON_X+col*(BUTTON_W+BUTTON_SPACING_X),
                 BUTTON_Y+row*(BUTTON_H+BUTTON_SPACING_Y),    // x, y, w, h, outline, fill, text
                  BUTTON_W, BUTTON_H, ILI9341_WHITE, buttoncolors[col+row*3], ILI9341_WHITE,
                  buttonlabels[col + row*3], BUTTON_TEXTSIZE);
      buttons[col + row*3].drawButton();
    }
  }

  // create 'text field'
  tft.drawRect(TEXT_X, TEXT_Y, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X1, TEXT_Y1, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X2, TEXT_Y2, TEXT_W, TEXT_H, ILI9341_WHITE);

  tft.setCursor(TEXT_X+2, TEXT_Y+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LAT:");

  tft.setCursor(TEXT_X1 + 2, TEXT_Y1+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LONG:");

  tft.setCursor(TEXT_X2 + 2, TEXT_Y2+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" AZMTH:");
}

void loop() {

  TS_Point p;

  /*
  while(Serial1.available()){ // check for gps data    //this has issue it is not written correctly
  if(gps.encode(Serial1.read()))// encode gps data
   Serial.print("Position: ");
  }
  */

  //lets try starts

  while(Serial1.available()){

    delay(1000);

      Serial.println( Serial1.read());

    bool res = gps.encode(Serial1.read());

    Serial.println(res);

    if(res)// encode gps data       //here is the problem lies    <<<<<<<<<===================================== it always return 0 thats why not working
    {
      gps.f_get_position(&lat,&lon); // get latitude and longitude

       Serial.print("Position: ");

    //Latitude
    Serial.print("Latitude: ");
    Serial.print(lat,6);
    Serial.print(",");

    //Longitude
    Serial.print("Longitude: ");
    Serial.println(lon,6);

      }

    }

  //lets try ends

  if (ts.bufferSize()) {
    p = ts.getPoint();
  } else {
    // this is our way of tracking touch 'release'!
    p.x = p.y = p.z = -1;
  }

  // Scale from ~0->4000 to tft.width using the calibration #'s
  if (p.z != -1) {
    p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
    Serial.print("("); Serial.print(p.x); Serial.print(", ");
    Serial.print(p.y); Serial.print(", ");
    Serial.print(p.z); Serial.println(") ");
  }

  switch(page_state){
    case 0: // Means Keypad
  // go thru all the buttons, checking if they were pressed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].contains(p.x, p.y)) {
      //Serial.print("Pressing: "); Serial.println(b);
      buttons[b].press(true);  // tell the button it is pressed
    } else {
      buttons[b].press(false);  // tell the button it is NOT pressed
    }
  }

  // now we can ask the buttons if their state has changed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].justReleased()) {
      // Serial.print("Released: "); Serial.println(b);
      buttons[b].drawButton();  // draw normal
    }

    if (buttons[b].justPressed()) {
        buttons[b].drawButton(true);  // draw invert!

        // ENT Button was clicked
        if (b == 0){
          lon = atof(longitude);
          lat = atof(latitude);
          status(F("  Searching and laser start rotating"));
          Serial.println("Searching ");
          Serial.print("Latitude : ");
          Serial.println(String(lat));
          Serial.print("longitude : ");
          Serial.println(String(lon));
          Serial.print("lat + lon = ");
          AZMTH=lat+lon;
          Serial.println(AZMTH);

            // just add this part in this location
          //----- AND REPLACE THE VALUE -----
          tft.setCursor(TEXT_X2 + 90, TEXT_Y2+10);
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              tft.print(AZMTH);
              Serial.print(AZMTH);

        }

        // CLR Button was clicked
        else if (b == 1) {
          switch(cursor_state){
            case 0:
              if (latitude > 0) {
                latitude_i--;
                latitude[latitude_i] = ' ';
              }
              break;

            case 1:
              if (longitude > 0) {
                longitude_i--;
                longitude[longitude_i] = ' ';
              }
              break;
          }
        }

        // NEXT Button was clicked
        else if (b == 2){
          page_state = 1;
          tft.fillScreen(BLACK);
          latitude[0]=0x00;
          latitude_i=0;
          longitude[0]=0x00;
          longitude_i=0;
          cursor_state = 0;

          tft.setRotation(1);
          Draw_Compass_Rose();
            double angle= 270; //use heading from compass
            dx = (diameter * cos((angle-90)*3.14/180)) + centreX;    // calculate X position
            dy = (diameter * sin((angle-90)*3.14/180)) + centreY;    // calculate Y position
            arrow(last_dx,last_dy, centreX, centreY, 20, 20,BLACK);  // Erase last arrow
            arrow(dx,dy, centreX, centreY, 20, 20,CYAN);             // Draw arrow in new position
            last_dx = dx;
            last_dy = dy;
          delay(25);
          tft.setRotation(0);

          }

        // '>' Button was clicked
        else if (b == 14){
          /* Toggle between latitude and longitude */
          if (cursor_state == 0){
            cursor_state = 1;
          } else if (cursor_state == 1){
            cursor_state = 0;
          }
        }

        // if a numberpad button, append the relevant # to the textfield
        else if (b >= 3) {
          switch(cursor_state){
            case 0:
              if (latitude_i < TEXT_LEN) {
                latitude[latitude_i] = buttonlabels[b][0];
                latitude_i++;
                latitude[latitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
            case 1:
              if (longitude_i < TEXT_LEN) {
                longitude[longitude_i] = buttonlabels[b][0];
                longitude_i++;
                longitude[longitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
          }

        }

       Serial.println("Value of cursor_state: ");    //where is written touch screen started? you there????
       Serial.print(cursor_state);

      switch(cursor_state){   //This condition is always false

            Serial.print("If successfully comes here then this line should print");  //This means

            case 0:
              // update the current latitude
              tft.setCursor(TEXT_X + 90, TEXT_Y+10);//set position of text when user key in the lat angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              Serial.print(latitude);
             // if (gps.f_get_position(&lat,&lon))    //<- this condition is wrong
              {
             // tft.print(String(gps.f_get_position(&lat));
              gps.f_get_position(&lat,&lon);
              Serial.println("Latitude on Serial: ");

              Serial.print(lat, 6);
              }
              break;

              // update the current longitude
            case 1:
              tft.setCursor(TEXT_X1 + 90, TEXT_Y1+10);//set position of text when user key in the long angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              Serial.print(longitude);
             // if (gps.f_get_position(&lat,&lon))
              {
             // tft.print(String(gps.f_get_position(&lon));
              gps.f_get_position(&lat,&lon);
              Serial.println("Longitude on Serial: ");
              Serial.print(lon, 6);
              }
              break;
          }

    }
//
      delay(50); // UI debouncing

     }
   }
}

void display_item(int x, int y, String token, int txt_colour, int txt_size) {
    tft.setCursor(x, y);
    tft.setTextColor(txt_colour);
    tft.setTextSize(txt_size);
    tft.print(token);
    tft.setTextSize(2); // Back to default text size
}

void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour) {
  float distance;
  int dx, dy, x2o,y2o,x3,y3,x4,y4,k;
    distance = sqrt(pow((x1 - x2),2) + pow((y1 - y2), 2));
    dx = x2 + (x1 - x2) * alength / distance;
    dy = y2 + (y1 - y2) * alength / distance;
    k = awidth / alength;
    x2o = x2 - dx;
    y2o = dy - y2;
    x3 = y2o * k + dx;
    y3 = x2o * k + dy;
    x4 = dx - y2o * k;
    y4 = dy - x2o * k;
    tft.drawLine(x1, y1, x2, y2, colour);
    tft.drawLine(x1, y1, dx, dy, colour);
    tft.drawLine(x3, y3, x4, y4, colour);
    tft.drawLine(x3, y3, x2, y2, colour);
    tft.drawLine(x2, y2, x4, y4, colour);
}
void Draw_Compass_Rose(){
  int dxo, dyo, dxi, dyi;
    tft.drawCircle(centreX,centreY,diameter,YELLOW);  // Draw compass circle
  for (float i = 0; i <360; i = i + 22.5) {
    dxo = diameter * cos((i-90)*3.14/180);
    dyo = diameter * sin((i-90)*3.14/180);
    dxi = dxo * 0.9;
    dyi = dyo * 0.9;
    tft.drawLine(dxi+centreX,dyi+centreY,dxo+centreX,dyo+centreY,YELLOW);
  }
    display_item((centreX-5),(centreY-85),"N",RED,2);
    display_item((centreX-5),(centreY+70),"S",RED,2);
    display_item((centreX+80),(centreY-5),"E",RED,2);
    display_item((centreX-85),(centreY-5),"W",RED,2);
}

Please help me. I shall be very thankful to the person who helps me.

i fail to understand how anyone would identify the problem to be the gps.encode()  function, when the problem is clearly the data from the GPS module being corrupted by the presence of the TFT module and/or the TFT program ... determine if the problem is caused by the presence of the TFT module alone, or if it caused by software ... try to narrow down what part of the program causes the fail

@jsotola Okay. but I mentioned earlier that if I run GPS standalone then it works properly but when it is used with TFT it does not give proper serial data.I don't know where is the problem. I am stuck on it for weeks now

Added: the TFT is connected when I run the GPS code (and excluding TFT code) and GPS works properly

now add simple hello world TFT code

Do you realise that you're discarding every other byte from the GPS? Serial.println(Serial1.read()); reads a byte, displays it, then you never get that byte back again.

@Majenko yes I know that, it was for testing purpose only.

@Majenko any suggestions what could be the problem?

And that "testing" breaks everything. Ditch that. Or put the read value into a variable so you can use it twice. At the moment you're seeing, instead of "Hello world" just "el od"


text:
Multiplexing HID and serial on ATMega32U4
I designed a custom ATMega32U4 based Arduino Leonardo board. I'm using MHeironimus/ArduinoJoystickLibrary to implement an HID joystick. I need to create also a virtual serial port to send NON joystick data to the USB host (Android device).
If I try to set use the usb serial the joystick device is not recognized.
If I stop the serial the joystick works fine.
This's the code:
#include <Arduino.h>
#include <Joystick.h>

#define JOYSTICK_PERIOD 20

const int BUTTON1_PIN = 4;
const int BUTTON2_PIN = 5;

int x = 0, y = 0, rx = 0, ry = 0, din = 0;
long time1, time2;

Joystick_ Joystick(
  JOYSTICK_DEFAULT_REPORT_ID,
  JOYSTICK_TYPE_GAMEPAD,
  2, 0,
  true, true, false,
  true, true, false,
  false, false,
  false, false, false
);

void setup()
{
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);

  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);

  Joystick.begin();
  Joystick.setXAxisRange(0, 1000);
  Joystick.setYAxisRange(0, 1000);
  Joystick.setRxAxisRange(0, 1000);
  Joystick.setRyAxisRange(0, 1000);

  time1 = millis();

  Serial1.begin(9600);
  Serial.begin(9600);
}

void SerialEvent()
{
  int _count = Serial.available();

  for(int _i=0;_i<_count;_i++)
    Serial1.write(Serial.read());
}

void Serial1Event()
{
  int _count = Serial1.available();

  for(int _i=0;_i<_count;_i++)
    Serial.write(Serial1.read());
}

void loop()
{
  time2 = millis();

  long _period = time2 - time1;

  time2 = time1;

  if(_period >= JOYSTICK_PERIOD)
  {
    din = (digitalRead(BUTTON1_PIN) << 1) | digitalRead(BUTTON2_PIN);

    x = analogRead(A0);
    y = analogRead(A1);
    rx = analogRead(A2);
    ry = analogRead(A3);

    Joystick.setButton(0, din);

    Joystick.setXAxis(x);
    Joystick.setYAxis(y);
    Joystick.setRxAxis(rx);
    Joystick.setRyAxis(ry);
  }
}

Anyone has hints?

Page not found. Please post your code here, not a link to it.

@Majenko ops the repository is private .. my fault.. I posted the code thnx.

it may be a limitation of android

this may help ... https://github.com/NicoHood/HID

https://github.com/NicoHood/HoodLoader2

@jsotola, HoodLoader is for 16u2 on Uno/Mega


text:
Connecting OV2640 with 17 Pins Binocular Camera module, to any microcontroller (System clock on module pin 18 -NC)
These pins are on the module:

3.3V
GND
VSYNC
SCL
SDA
HREF
D0-D7
DCLK
PWDN
I have tried many codes and connections of the OV7670 Monocular cameras, none seem to work(Instructables ,  Circuit Digest , Youtube).
The binocular cameras seem to be just daisy-chained using the I2C SCCB interface. I cant get any image reading on any of their codes provided. Some other guides mention programming the XCLK on board using SCCB PLL, but I'm not sure how to do it as I don't have much background in this domain.

Edit:-
1.Another resource
2.Wiki with datasheet and schematic (the module is a copy of this camera)

please add a link to the camera datasheet to your post ... do not put link into comments


text:
How does supply voltage affect `analogRead()` on AVR-based microcontrollers?
I'm using an ATmega328P based Arduino to prototype reading a TMP36 temperature sensor. I will eventually move this to an ATtiny85 based board with a battery supply. Both the TMP36 and ATtiny85 have a Vcc range from 2.7V to 5.5V so a battery that starts at say 4.5V and slowly drops to 2.7V should not be out of range.
I am expecting to read temperatures in the range -5°C to +30°C which should correspond to a TMP36 output between 0.5 to 0.9V. I am getting 0.74V at around 23°C so this sort of range seems plausible.
The TMP36 outputs 10 mV/°C regardless of Vcc (within 2.7-5.5v). But I suspect the AnalogRead() value will be scaled by the supply voltage and so will slowly change as the battery drains. Is this correct?
Do I need to include an external voltage-regulator / voltage-reference device to supply some fixed voltage (e.g. 2.5V) to AREF?

Solution
Following Edgar Bonet's Answer I successfully enabled the internal voltage reference for the ADC.
Initially I added a 100nF bypass capacitor to AREF and tried
#define REFS1 7
#define REFS0 6
#define REFS2 4

...
//ADMUX = (_BV(REFS1) | _BV(REFS2)); // 2.56V ATtiny85   datasheet §17.3 pp134
ADMUX = (_BV(REFS1) | _BV(REFS0)); // 1.1V  ATmega328P datasheet §23.9 pp217

but didn't get it to work, my code had no effect on values from analogRead(). So after a bit of further reading I instead used
analogReference(INTERNAL);

Which worked.

The ADC measures a voltage ratio. The conversion result is the rounded
value of 1024×V/Vref, where V is the voltage at the input and
Vref is the voltage reference.
In the default Arduino configuration, the reference is connected to Vcc.
This will not fit your use case, as the voltage you want to read does
not vary proportionately to Vcc. You could use an external reference.
However, the ATtiny85 has two internal voltage references at 1.1 and
2.56 V. Either of these may be well suited for you application,
which should save you having to add an extra part.
See the chapter on the ADC in the datasheet for details on
how to select the voltage reference.

Thanks, that quickly led me to a solution - new notes appended to question for those  interested.


text:
How to produce rolling count per minute?
I have a counter attached to ISR:
void ISR_impulse() {
  CNT++;
}

and I want to calculate rolling count per minute with arbitrary update rate.
However I can only get it to update every minute:
void loop() {
  if (t - t0 > 60000) {
    CPM = CNT - CNT0;
    t0 = t;
    CNT0 = CNT;
  }

  t = millis();
  delay(100);
}

Requirement:

Rolling count with a window of 1 minute, and arbitrary update rate like 1 second ?
CPU has other tasks to do, which might take a significant amount of time.
SAMD21 has pulse period measurement in TC, but I have no idea how to set it up.

Partial solution one by edgar bonet:
  static uint8_t buf[60];
  static uint8_t idx;
  static uint32_t t0;
  static uint16_t CNT0;
  static uint8_t cpm;

  if (millis() - t0 >= 1000) {
    t0 = millis();
    uint16_t cps = CNT - CNT0;
    CNT0 = CNT;
    cpm += cps - buf[idx];
    buf[idx] = cps;
    if (++idx >= 60) idx = 0;
  }

How ever this only works if the loop code finishes in less than 1ms.

set up a FIFO buffer ... the ISR pushes decimal 60 into the buffer .... every second, a separate program routine decrements each of the values in the buffer by one, counts non-zero values and returns the count

While rewriting the code of my answer, you introduced a couple of errors: 1. By updating t0 with t0 = millis();, you make the tiny timing errors cumulative. If you update it with t0 += 1000; they are not cumulative: they only create a small amount of jitter, which is somewhat averaged-out by the subsequent running average. 2. By reading CNT twice with interrupts enabled, you create a race condition. If CNT is updated by the ISR between the two reads, you miss one pulse.

If you want to update every second a one minute running average, you
have no choice but store in memory the counts you got the previous
60 seconds. You store them in a ring buffer, so that every new
reading replaces the oldest one. Then, every second:

you add to the CPM count the number of counts you got this second
you subtract the number of counts you got on the second that just got
out of the sliding window.

I would implement that logic this way:
const uint32_t ONE_SECOND = 1000;

uint16_t counts_per_minute;
uint16_t previous_counts[60];
size_t counts_pos;

void loop() {
    static uint32_t previous_second;
    if (millis() - previous_second >= ONE_SECOND) {
        previous_second += ONE_SECOND;
        noInterrupts();
        uint16_t CNT_copy = CNT;
        interrupts();
        static uint16_t CNT_previous;
        uint16_t second_count = CNT_copy - CNT_previous;
        CNT_previous = CNT_copy;
        counts_per_minute += second_count - previous_counts[counts_pos];
        previous_counts[counts_pos] = second_count;
        if (++counts_pos >= 60) counts_pos = 0;
    }
}

Note that:

The timing variable is updated with previous_second += ONE_SECOND
rather than previous_second = now in order to avoid the accumulation
of small timing errors.
The counter that is updated in the ISR has to be read only once,
with interrupts disabled. Otherwise the interrupt may change it while
you are in the middle of reading it.

So it's a moving average with count-per-update-period as elements ? Wouldn't the noInterrupts() cause the counter to miss some counts ?

It would be perfect of you could add code to account for millis() < 60000 situation.

@7E10FC9A: You cannot meaningfully compute a one minute rolling average in less than one minute.

@7E10FC9A: noInterrupts() will not make you miss an interrupt. If an interrupt request fires while interrupts are disabled, it is put on hold and served right after the interrupts() call. Only if two instances of the same request fire within this period do you miss an interrupt. But since they are been disabled for less than half a microsecond, this could only happen with an interrupt rate way above what the Arduino can handle.

The code does not work if CPU has other tasks to do. The sampling interval is not guaranteed to be 1000ms.

@7E10FC9A: If you program in a non blocking fashion, your loop() should always execute very fast. If it takes more than a millisecond, you are most likely doing something wrong. With a very fast loop(), the inaccuracies will be tiny, and likely irrelevant. If your accuracy requirement is really so high that a fraction of a millisecond does matter, then program a timer to fire an interrupt every millisecond, and update counts_per_minute within the ISR.

MCU only have one thread, so it's difficult to make the loop code non-blocking. Let's say what would you do if there are other tasks that require CPU time >>1ms at random?

@7E10FC9A: In such a case I would use a timer interrupt. My point is that it is uncommon to actually need 1 ms of CPU time at once. If loop() takes more than 1 ms, it is more than likely that most of these CPU cycles are waisted delaying or busy-waiting for some event (i.e. “blocking”). Then you can make it non blocking by using a finite state machine and/or the technique shown in the Blink Without Delay tutorial.

Q doesn't say, but Is uint16_t large enough for the count/sec? //  If the CNT interrupt is accurate, then any errors introduced by the timing of the  samples are balanced by corresponding errors in the following second.    If the loop takes more than a second it could fall behind and overcount the minute, but short of that, the jitters should take care of themselves.

You need a First-In, First-Out buffer (FIFO) so that the oldest data drops off to make room for the newest. This is usually done with a circular buffer - an array whose beginning / end point change as data is added. (For comparison, the simplistic way is an array whose contents gets moved down (toward i = 0) each time you need to add a datum. But moving data is slow, so remembering where the oldest entry is, replacing it with the newest one, and updating the remembered oldest-data location gives a huge permormance improvement.
Secondly, you need to define how responsive your counter needs to be - how many updates per minute you'll need. That's the number of elements you need in the array.
Evaluating the immediately-passed minute's count is as simple as summing the array, which can be done without caring where the begin/end point is. Sum from 0 to N-1; the result will be the same.


text:
Warm Atmega328p and weird power behaviour
I recently built a circuit with an atmega328p (which I have never used before standalone) and attached all the neccessary components (crystal, capacitors etc). However, when I powered it up with a regulated 5v input, I noticed the chip getting a little bit warm. Not hot, the temperature seems quite constant, and everything still works just fine. Another strange thing though, is when I connect the VCC to AVCC together as specified in the datasheet, the circuit doesn't work at all: The LCD screen just shows solid blocks at the top. When I disconnect the wire again, everything is back to normal. What went wrong? It is perfectly possible that there is a small solder bridge on my perfboard.

Please say more about your "circuit with an atmega328p", such as what is connected to the MCU and how. Running warm suggests you may be trying to supply to much current to other devices through the MCU. A schematic would help; so would  part numbers for the external devices, such as the LCD which you only mentioned in passing.

Do you have a multimeter, so you can measure the current usage? Could you post an image of your setup, or a schematic?

Current Usage at 10v (going into 5V regulator) is 0.01 milliamperes

LCD is just a generic 16x2 LCD I got on ebay, I have used it with an Arduino uno for a long time with no issues.

What kind of regulator did you use? Current input doesn't necessarily tell you about the current consumption of the board and, by itself, nothing about MCU current. In fact the regulator circuit on an Arduino board would disispate a great deal of the current drawn from a 10v supply. And 10 micro-amps? Really? Schematic please.

@JRobert  I cannot provide a schematic because I didn't make one. The atmega chip still heats up even when there is nothing connected at all. I have double checked that the crystal and ceramic capacitors are wired properly and they are. The voltage regulator is one that I salvaged from an old power supply. I provided it with 19v for about 10 minutes (which is the voltage that I will be using) and it heated up to the point that I couldn't touch it, even though the datasheet says this is well within its recommended range. The read on my bench psu said 0.01 amps.(not milliamps, my mistake)

I also tried powering it from an arduino uno board and although I can upload code and everything works properly, the chip still warms up.

I think you have to add more details about your circuit before anyone could see what's your problem, plus are you sure from that voltage regulator you salvaged? it can be a wrong value regulator, I recommend buying one or telling us it's name or number, lastly supplying a 19V to a 5V linear voltage regulator is BAD because those volts will be dissipated as heat that could rise dramatically till you couldn't touch, use lower voltage or just use a buck converter which will be ultimately better.

Sorry for late reply, I have hooked the board directly to 5V power supply and the chip draws 0.1 amps


text:
Can Bluetooth HC-05 Module detect other modules and relay data back to phone?
I want the following to happen:

The HC-05 is paired to a phone. The module is called "Amy". The module is worn, say, as a wristband by a person.
Amy passes another wristband-with-HC-05-module called "Bob".
Amy inquires about Bob, and if the RSSI signal received is strong, it relays the name "Bob" to the phone which will somehow store the information in an app.
The HC-05 will pass many other modules, each with different usernames. A list of names will be stored by the phone app.
All other HC-05 modules, i.e. Bob and co. , would be doing the same thing with their own phones.

How feasible is this?

From your last question I thought you wanted to go with BLE beacon.  Why now normal old bluetooth?

@chrisl I didn't realise that the HC-05 wasn't a BLE device. I am still researching things, and my choice of module isn't set in stone - I am still looking for better options. All I am interested in regarding this question is whether the module can be paired to a phone, but still collect information from inquiring into other nearby devices. I assume the answer would be the same for both Bluetooth and BLE? (Also both Bluetooth and BLE modules can provide an RSSI value, which is the important thing).

Correction - BLE devices give off RSSI, but not Bluetooth. BLE devices can be used as iBeacons. I have settled on the HM-19 Bluetooth 5.0 module. A phone acts as an iBeacon scanner.


text:
Arduino Yun receives UDP packets but prints them with gibberish
Arduino Yun is set to receive UDP packets. It receives those data with some gibberish.
How is all set up: Arduino Yun (acts as a server) is connected through Ethernet to a PC which is (through WiFi) connected to the router. Another PC (acts as client), is also connected to the router (through Wifi).
Client uses netcat to connect to Arduino Yun. I write something and press enter. The packets are received by the Arduino Yun with some gibberish. For example, I write "test" and press enter, but this is what I receive on the Arduino Yun:

Sometimes gibberish characters are different, but always exist. This is what Wireshark monitors when I send the "test" packet (with netcat) to my Arduino Yun:

It shows that indeed I send only "test", so the gibberish is created on the Arduino side, I suppose.
This is my sketch (not the entire code, but the important part):
void loop() {
  int udp_received = Udp.parsePacket();
  if (udp_received) {
    char udp_buffer[16];
    udp_buffer[15] = '\0';
    Udp.read(udp_buffer, 15);
    Serial.println(udp_buffer);
  }
}

I use BridgeUdp.h
Any insights appreciated.

udp_received is count of characters received. (and nice progress since previous question)

udp_buffer[udp_received ] = '\0'; you send only 5 or 6  characters "test\r\n". the rest is random memory content

If I'm not mistaken, UDP packets, when printed as strings, might look like gibberish because they are not ASCII but binary in format. You would need to check the documentation and find out what the packet format is or, lacking documentation, you'd need to try and get some idea what the data actually represents.

Thanks Juraj, I'm moving forward slowly. but steadily. So you say that I read more bytes than I actually receive?

@S.Imp, if you send "test", you receive "test"

you don't read more. the function fills only so much bytes as received. the rest of the buffer is uninitialized memory.

@Juraj if you look at his wireshark screenshot, you'll see that the UDP packet received is 47 bytes. "test" is probably only four bytes. So he's got another 43 bytes to figure out.

@S.Imp, it is the envelope

You are receiving a small packet of about 5 or 6 characters (depending on your line ending). That is being received into a 16 byte buffer which has contents unknown.  So the first 5 or 6 bytes of the array have valid data in it. The rest is whatever was already in there.
You need to use the return value of Udp.parsePacket() to tell you how many of the bytes in your buffer are actually valid received bytes and only print those.
The simplest way:
Serial.write(udp_buffer, udp_received);

int udp_received = Udp.parsePacket();
if (udp_received) {
char udp_buffer[udp_received];
Udp.read(udp_buffer, udp_received);
Serial.write(udp_buffer, udp_received); Is that what you mean?

Sounds about right

This doesn't work as expected. It prints only the first character of each line. For example if I send "test", ENTER, "test", ENTER", "hello", ENTER, Serial monitor prints "tth"

Maybe it's the return value from Udp.read() actually. I haven't used the Yun for UDP before...

And the packetSize is always printed as 1, that's weird

You send only 5 or 6 characters "test\r\n". the rest is random memory content.
The return value of parsePacket should be the count of received characters, but the implementation in BridgeUdp is wrong and returns always 1 on success.
You you can use BridgeUdp.available() to get the count.
void loop() {
  if (Udp.parsePacket()) {
    int udp_received = Udp.available();
    char udp_buffer[16];
    Udp.read(udp_buffer, udp_received);
    udp_buffer[udp_received] = '\0';
    Serial.println(udp_buffer);
  }
}


text:
esp32-pico-4d not working
My power supply is feeding the esp32-pico with 5v tho it says that there is 0 amps power drain, already there I know something isn't working since the power drain should be around 0.080amps, (it can be all the way up to 0.250amps if wifi on)
when I measure the vdda pin where the power goes into the chip it reads 3.3v which is perfect, but any of the other vdda power pins reads 0v, is the chip turned of cause I'm not powering the EN pin directly from the power supply?
in other words, do the other power pins turn off with the chip?
I have now tried pulling 3v straight from the power supply to the EN pin, and it then goes up to using around 0.160amps, but I still get nothing in the com port
a bit clueless for what is wrong?
other information:
I have a powerbumb turning the 5v into 3.3v
if EN = low: module is turned off if EN = high module is on
(don't leave EN floating)
https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf
(I know the antenna doesn't work)

Please show your schematic and PCB design.

i have added them now

You must connect all of the VDD pins of all types to the appropriate power supplies. These aren't like development boards. They are chips. And you must treat them as such.

Especially the CPU one - or nothing will ever be able to work.

so every single vdd pin also those named vdda3p3 needs to be connected to power supply?

(ofc only the amount of v they need)

DVVA3P3, VDDA, VDDA3p3_RTC, VDD3P3_CPU, VDD_SDIO - they all need connecting.


text:
How do you remove an item from array arduino?
Is there a way that can change {3, 5, 3, 6} to {3, 5, 6} with a function? I checked all the arduino forums but they don't give the answer i need (just delete 1 item from an array with a function like delete(myArray, 2)).

There is no such concept in C. Arrays are a fixed size and that size can never be changed. You can't "delete" an entry. You can replace one with something else, and you can introduce the concept of a variable that says how many entries the array has, but you can't delete one.
So you could:

Keep a count of how many entries are in the array
Shuffle down all the entries one space so the unused one is at the end
Decrement the count of entries

So in your example {3, 5, 3, 6} becomes {3, 5, 6, 6} and your "count" holds 3 to say the first three entries are valid and to ignore the last.
Alternatively you can introduce the concept of "end of array". C strings do this with the NULL character (0). Anything before that character is valid, and anything from that character onwards is ignored.  So say you nominated the value -1 to be "end of array" you could have, after again shuffling down the values: {3, 5, 6, -1}.
You could also have -1 (or whatever you chose) indicating an "invalid" entry, so your array would be {3, 5, -1, 6} and you would ignore the -1 entry in your code.

Using an invalid value (vs. an end-of-array value) saves shuffling values to over-write the vacated space, but adds some overhead in that array indexing would no longer work as expected but would require walking the array and counting valid values until the i-th one. Some applications may benefit (those that just store data but don't index to it, or not often, anyway), vs. those that do a lot of indexing but not much deleting.

In C++, arrays are fixed-length data structures. There is no way you could remove an item. You could replace it with an invalid item, though.

So is there a data array-like type witch can be modifiable?

Dynamic objects are not a good idea on a memory-starved device like an Arduino. Come up with a "this space intentionally left blank" value and store that into a location to remove an item. (0 and -1 are common choices for an empty entry, as Majenko mentions in their answer.)


text:
Any limitation on array size in Arduino Mega 2560?
I am writing an Arduino code with 3 arrays.
Two of those are double and other one is int. Further first two arrays have nearly 420 elements for each.
Now I noticed that with more that 89 elements on 3rd array the program stall, and stuck executing. But with 89 or less number of element it runs with out an issue.
What would be the issue?

That's hard to tell without seeing your code.

The limit is 32767 elements. Anything else is a problem with your code.

Also be sure to not be too close to the max memory. If there is not enough space left to put variables on the stack, the program will crash some way

Are these arrays declared by size at compile time? what does the IDE report as far as your memory use is concerted when it compiles the program. As stated before, kinda hard to help without seeing your code.

A Mega has 8 KB of memory.
You are using:

double (same as float on an Arduino, see double) , 4 bytes * 420 elements * 2 arrays = 3,360 bytes
int (2 bytes) * 89 = 178 bytes

In total this is 3,538 bytes
This is about 50%, so I'm unsure what the 'rest' is.
You can take a look at the other related question that may show some answers (like using dynamic memory, memory gaps, or local/stack variables): What are the traditional ways to optimize program memory usage?


text:
Joining several PIR sensors
I wish to use some PIR (HC-SR501) sensors and give some response if at least one of them detects human movements.
For simplicity I wish to use only one input pin in an Arduino UNO. My idea is to connect all the output wires into a single Arduino digital input. Should it work?
I am in doubt because the following two reasons:

The sensors must be far away from each other (about 5 sensors partially covering an area of about 200 m^2). That implies that wires are long and I do not know if this can have some adverse effect.
I do not know if it is bad to supply the 3.5V of some sensor that is currently detecting movement to the output of the sensors that are not detecting anything.

Thanks in advance

Don’t know about the first question but your second concern can be solved by a simple diode one each line to make sure current only goes one way.

The BISS0001 that your unit uses provides an "active high" output. To connect multiple devices together you just need to "OR" the signals.
There's many ways of doing that.
The simplest method is the "wired OR" circuit, which just involves one pulldown resistor plus one diode per device:

simulate this circuit – Schematic created using CircuitLab
You could also use a multiple-input OR gate chip. You can get these in 2- (74HC32), 3- (74HC4075), 4- (74HC4072) input versions.

Thank you! Could you comment why a resistor is needed and how to calculate its resistance as a function of the number of PIR employed?

The resistor is simply a pull-down. When all the inputs are LOW the diodes are reverse / not-at-all biased. When one goes high they become forward biased by the current through the diode and the resistor to ground. The value is pretty meaningless. The BISS0001 can source up to 10mA, so it wants to be larger than 500Ω. The number of PIR modules is irrelevant. If you have very long wires you might want to reduce the pull-down a little.

Thank you! I just read about pull-down. In practical terms, the resistor is needed to avoid false positives due to noise. Right?

It is needed to form part of the circuit. It's what provides the LOW when none of the PIRs are providing a HIGH.


text:
ESP8266 CCLOCK Odd behavior
I'm trying to write some extremely fast code for the ESP8266, so I'm trying to figure out how to time things.  I've discovered CCLOCK, a register that reflects the number of clock cycles since startup. (https://github.com/esp8266/Arduino/issues/4632#issuecomment-380632906, and other references.) In testing it out, though, I've encountered some weird behavior.  Consider the following code:
static inline volatile uint32_t asm_ccount(void) {
    uint32_t r;
    asm volatile ("rsr %0, ccount" : "=r"(r));
    return r;
}

char outgoingPacket[4];

...

void loop() {

  // ... some stuff ...

  uint32_t startTime = asm_ccount();
  uint32_t stopTime = asm_ccount();
  uint32_t elapsed = stopTime-startTime;

  outgoingPacket[0] = (elapsed >> 24) & 0xff;
  outgoingPacket[1] = (elapsed >> 16) & 0xff;
  outgoingPacket[2] = (elapsed >> 8) & 0xff;
  outgoingPacket[3] = elapsed & 0xff;
  Udp.beginPacket(targetUdpIp, targetUdpPort);
  Udp.write(outgoingPacket, 4);
  Udp.endPacket();
}

(On my computer, I have basically the following Java code running to receive these messages:)
    while (true) {
      DatagramPacket packet = new DatagramPacket(buf, buf.length);
      socket.receive(packet);

      byte[] data = packet.getData();
      StringBuilder sb1 = new StringBuilder();
      StringBuilder sb2 = new StringBuilder();
      for (int i = 0; i < packet.getLength(); i++) {
        sb1.append(String.format("%8s", Integer.toString(((int) data[i]) & 0xFF, 2)).replace(' ', '0'));
        sb2.append(String.format("%2s", Integer.toString(((int) data[i]) & 0xFF, 16)).replace(' ', '0'));
      }
      System.out.println(sb1 + " " + Integer.parseInt(sb2.toString(), 16));
    }

(Yes, it's a little hacky, I know, but the results have seemed correct.)
Now, most of the time, the output looks like
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000000000001 1

But about 5 times in 77000, I'll get lines like
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000110101000 424
00000000000000000000000000000001 1
00000000000000000000000000000001 1
...
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000010010100001 1185
00000000000000000000000000000001 1
00000000000000000000000000000001 1
...
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000010001001100 1100
00000000000000000000000000000001 1
00000000000000000000000000000001 1

I ran the code for 1 minute 4 seconds, and got 3 counts of 424, 1 of 1100, and 1 of 1185.  It seems particularly odd that 424 would show up three times.
Given that, as far as I understand, the relevant lines of code (the two calls to asm_ccount) would have been compiled to a given set of instructions, I'd have expected it to take exactly the same number of cycles every time.
Why is this not happening?
Is it interrupts?  Something something caching?  Does that register not actually work as claimed or as I understand?  Have I done something dumb in the transmission or logging code?  Something else?

You've got interrupts running and interrupting your code.  Those take some cycles to run.

aHAH!  I think you're right.  When I disable interrupts around the critical code, its timing becomes almost perfectly stable.  ...But then it stops working after a few dozen loops, so I guess I can't do that, haha.  If you want to make your comment an answer, I'll accept it.

You've got interrupts running and interrupting your code. Those take some cycles to run.


text:
74HC595 to 5v pin shuts down uno
I'm new to using the SN74HC595 shift register, and trying to follow this tutorial: https://www.arduino.cc/en/tutorial/ShiftOut based on this configuration:

When my arduino Uno R3 is plugged in by USB to my Windows-7 x64 PC, it works (in general etc.), but right when I attach pin 16 or pin 10 of the 74HC595  to the 5V pin on the Uno, as it says to do, the entire arduino shuts off and the computer no longer recognizes it, until I disconnect the jumper wire from pin 16 or 13, from the 5v pin on the Uno, then it starts up again
Also just tested, and the same thing happens when I try to connect any of the 74HC595  pins to the 5v Uno pin (after pin 8 of the 74HC595  is connected to the Uno's GND), the whole Uno shuts off and disconnects from the computer
Am I missing something here?

It sounds like you have a short somewhere on the breadboard with the HC595. Could you describe the simplest way to reproduce the problem?

i tried pluggging the pins directly to the ruino pins, only pins  8 and 16, when the register   was at diferent points on the breadboard (and the breadboard works with other things too), am I getting the configuration right ? does my register match th kind at the tutorial?

So the problem occurs just connecting the HC595 to its power supply? Did you correctly identify pin 1?

Photos, or it didn't happen.

Sound like there is a short somewhere. But it also sound like you are putting in jumper wires while the Arduino is plugged in. Which you shouldn't do in most cases. Also connecting 5v to any of the 74HC595 pins, while no supplying the power to it's Vcc pin (16) is not great, and can damage both the 595 and possibly the Arduino.

when I attach pin 16 or pin 10 of the 74HC595 to the 5V pin on the Uno ... the entire arduino shuts off

This sort of thing usually happens to me when I have made a mistake in the wiring.
This is easy to do as the 595 needs a lot of connections in a small space and it is easy to make a mistake.
In your case it seems you have a wiring mistake that is pulling Vcc low and the ATmega328 IC etc can't run.

I would

Re-check the orientation of the 595
Re-check each wire paying particular attention to the ground wires, especially the one that pulls 595 OE to ground (it's pin 13 on the 595).
If necessary, pull everything off the breadboard and start again with things in a completely different position (turn the IC's round etc) to make me re-think everything.

For fun, I set this up on a Uno clone. I made some mistakes in the wires linking the 595 to the Uno but careful inspection found the problem. I found it easy to mix up the pin-number on the 595 with that on the Uno. Using the same wire colours mentioned in the guide may help.
Here's it working


text:
Node MCU Wifi connection problem
I'm trying to connect my nodeMCU to my WiFi network also i have provided ip address  but it keeps printing ........ it is not connecting to the network. Below is my code.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

// Configration Parameter for Access Poin
char * ssid_ap = "";
char * password_ap = "";
IPAddress ip(192, 168, 1, 158);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255,255,255,0);

// Set up the server object
ESP8266WebServer server (80);

// Keep track of sensor data that's going to be sent by the client
float sensor_value = 0.0;

void setup()
{
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(ip,gateway,subnet);
  WiFi.softAP(ssid_ap,password_ap);

  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid_ap);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");

  server.begin();
  Serial.println("Server started");
  Serial.print("IP Address:");
  // Serial.print(WiFi.localIP());
  // Configure Server Router
  server.on("/",handleIndex); // use the top root path to report the last sensor value
  server.on("/update",handleUpdate);
  // server.begin();
}

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

}

void handleIndex()
{
  server.send(200,"text/plain",String(sensor_value)); //we'll need to refresh the page for getting the latest value

}

void handleUpdate()
{
 sensor_value = server.arg("value").toFloat();
 Serial.println(sensor_value);
 server.send(200,"text/plain","Updated");

}

softAP is for acting as an access point, not being a station in a pre-existing network.

You are creating a SoftAP (in essence creating a separate Wifi network). In this configuration, the ESP8266 will not "connect" to anything so polling WiFi.Status for the WL_CONNECTED status is meaningless.
To see if the SoftAP instance was created successfully, you should look at the output of WiFi.SoftAP() when you create the SoftAP instance, which returns a boolean indicating success (true) or failure. Or you should see the SSID of your newly created access point appearing on your PC or phone.
I suggest you look at the ESP8266 examples included in the Arduino IDE when you install device support for the ESP8266 to get some ideas about what you can do with a SoftAP.