text:
Arduino doesnt seem to be reading my pin states
I seem to have an unbelievable thing. My code was working perfectly on one arduino, when i upload the same sketch to another one, it is behaving strangely, it seems like it is not reading any of my pin states:
The code is ment to drive a simple stepper motor with driver. depending on the state of several pins in which direction it moves or moves at all.
What is happening now is when i upload the sketch the motor starts to turn, nomatter what pinstate any of the input pins have, the motor just turns on uploading and even if i apply 5v to any of the pins, it just keeps turning the same direction.
Following the code. I hope someone could tell me what i am doing wrong, i am a newbie to programming:
int PUL=7; //define Pulse pin
int DIR=8; //define Direction pin
//int ENA=5; //define Enable Pin
int up = 2;
int down = 3;
int limitpin=1;
int limitpinup=4;
int i=0;

int buttonupstate = 0;
int buttondownstate = 0;
int limitstate=0;
int limitstateup=0;

void setup() {
  pinMode(PUL, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(up, INPUT);
  pinMode(down, INPUT);
  pinMode(limitpin, INPUT);
  pinMode(limitpinup, INPUT);
}

void loop() {
  buttonupstate = digitalRead(up);
  buttondownstate = digitalRead(down);
  limitstate = digitalRead(limitpin);
  limitstateup = digitalRead(limitpinup);
  i = 0;
  switch (limitstateup){
  case LOW:
    switch (limitstate){
    case LOW:
      if (buttondownstate==HIGH){
        do
        {
          digitalWrite(DIR,LOW);
          // digitalWrite(ENA,HIGH);
          digitalWrite(PUL,HIGH);
          delayMicroseconds(20);
          digitalWrite(PUL,LOW);
          delayMicroseconds(20);

          buttondownstate = 0;
          buttondownstate = digitalRead(down);
          limitstate == 0;
          limitstate = digitalRead(limitpin);
          limitstateup == 0;
          limitstateup = digitalRead(limitpinup);
        } while (buttondownstate == HIGH && limitstate == 0 && limitstateup == 0);
      }
      if (buttonupstate == HIGH){
        do
        {
          digitalWrite(DIR,HIGH);
          // digitalWrite(ENA,HIGH);
          digitalWrite(PUL,HIGH);
          delayMicroseconds(20);
          digitalWrite(PUL,LOW);
          delayMicroseconds(20);

          buttonupstate = 0;
          buttonupstate = digitalRead(up);
          limitstate == 0;
          limitstate = digitalRead(limitpin);
          limitstateup == 0;
          limitstateup = digitalRead(limitpinup);
        } while (buttonupstate == HIGH && limitstate == 0 && limitstateup == 0);
      }
      break;
    case HIGH:
      do{
        digitalWrite(DIR,HIGH);
        digitalWrite(PUL,HIGH);
        delayMicroseconds(20);
        digitalWrite(PUL,LOW);
        delayMicroseconds(20);
        limitstate = 0;
        limitstate = digitalRead(limitpin);
      }while (limitstate == HIGH );
      break;
    }
    break;
  case HIGH:
    do{
      digitalWrite(DIR,LOW);
      digitalWrite(PUL,HIGH);
      delayMicroseconds(20);
      digitalWrite(PUL,LOW);
      delayMicroseconds(20);
      limitstateup = 0;
      limitstateup = digitalRead(limitpinup);
    }while (limitstateup == HIGH );
    break;
  }
}

Do you have pull-up or pull-down resistors on the inputs?  If they’re floating when the button isn’t pressed then they are free to read presses whenever they pick up noise.

Well to be honest nothing is connected to the input pins for the moment. If they are in low state they shouldn't do anything right?  When I uploaded to an original Arduino and connected the pins to the rest of the wiring it worked perfectly. When I upload it now to an Arduino clone it starts turning without stop.

Wenn nothing is connected to an input pin, it is not in a low state. It is floating. Google arduino floating pin. You need to connect either a pullup or a pulldown resistor. The Arduino has an internal pullup resistor, that you can activate

Actually, I just looked at the schematics of my relay board. All input pins are with pull down resistors . When connected to that the motor also just started spinning. Without stopping. It's +5v to relay to resistor to ground. So I guess that is the correct way to work for a pull down. When relay is activated it should get a high state. Correct?

We aren’t talking about your relays.  You need pull-up or pull-down on the input pin for the buttons and switches.  When nothing is connected to a pin it is in a random state sometimes reads high and sometimes low.  You need something to keep it in a defined state while the button isn’t pressed.  Google “Arduino floating input” and you should get lots of information on the topic.

Thanks all of you,
Indeed there is nothing wrong with my code. The problem is indeed in the pull-down resistors, I rebuild the connection on a breadboard and works perfectly. I will have to check my PCB that contains all relays and resistors, the problem has to be on that board, bad connection or something like that.
However I would like to state that on the Osoyoo Uno board, the whole thing worked perfectly, so there has to be something different between Osoyoo Uno board and another Arduino board.

Here is the schematic to my PCB board. I checked it again, but i think all the digital pins have actually pull-down resistors active.

No, there doesn’t have to be anything different.  The code appeared to work on the other board.  But at any random time one of those inputs could have read a spurious press if it picked up the right noise.  The only difference was luck.  Floating input pins are almost never a good idea.

Post a wiring schematic.   It kind of sounds like you might not be completely understanding what we’re talking about here.  And if it seems to work now that’s no sign that it’s fixed.  If I puts are still floating then you’ve still got a problem.

By the way, the arduino has internal pull-ups.  The more normal way to arrange things is to have the button wired to read LOW when pressed and then you can use the internal pull-ups and don’t need external resistors.

I see pull downs on the relays.  But I don’t see any for the inputs to the arduino.  It’s hard to tell because the arduino isn’t in the picture but I think I see where the lines go back to the input pins and there aren’t pull-downs in those.

Or are the relays the inputs?  Usually a relay is on an output.  I’m more confused by your drawing than I was before.  How does all of this connect to arduino?

I am sorry. This was made with circuitmaker to create my own PCB for it. Actually pin number 10 on every relay leads to an input on the Arduino. You can see that in The exact middle of the schematic there are 4 terminals each lead to a digital input and are connected to a resistor and to pin 10 of every relay.

The resistors connect to pin 10 of the relay and what ground?  Is it connected to Arduino ground?

Yes all go to Arduino ground. They are grouped all together. (Also the ground from my stepper driver. Dir- and PUL-) so there is one cable for ground going from this PCB to the Arduino ground


text:
What happens to the board if you connect the +5V pin directly to a digital input configured as input
I have maybe a very stupid question but connecting the +5V pin to a digital input pin programmed as input ( let's say pin2) . Will it destroy the board? Cause after i did this my board doesn't work anymore and i can also not upload a sketch to it. it does nothing anymore, yet nothing has burned or no smoke.
??
Thanks

Will it destroy the board?

No, it will just read HIGH. That's what HIGH is - 5V.

Cause after i did this my board doesn't work anymore

Then you probably did something else.

OK. in that case, what happens if you would add +5V from an external supply that is also powering the arduino by +12V . Meaning connecting +12V to Vin and 0V to Ground and than connecting a +5V to an input pin? Cause one way or another i fried these boards but i just don't understand how. I managed to break 2

Ok. I just measured. I have feeded +12V to the digital pin set as input. So will this frie the board irreperably or can i get the board to work again by replacing a part?

You may be able to replace the main mcu

Yes, if you feed +12V into an input pin you will likely damage or destroy the board. I did this with 9V on an Arduino Mega 2560 and it only destroyed that one input pin. The higher the voltage, the more likely it is to damage something, and the more severe that damage is going to be.

source: Stack Exchange

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

sort: votes


text:
Displaying Keypad Input on TFT Display
For a project of mine I have always wanted to build an electronic load and I am mostly done. However I have found myself stuck at one part that I thought would be simple but has thus only caused headache.
The problem is that I have a keypad connecting along with a TFT display to an Arduino. I want to enter for example my current for the electronic load and display the value that I set on my display. I have tried the simple code for keypads that is available on tutorials all over the web but what happens is that it displays the key I press but if I press another one it erases the first and displays the second in the same spot. I want to be able to have 4 or 5 digits that can all show up in order. I have found some different code and modified it. I can now display multiple digits but the issue is that if I press for example 4 a 4 will show up but if I press a 5 another 4 will show up and then if I press a 5 again then a 5 will show up on and on.
Additionally it resets the screen even though I don't have a reset function in my code. So every time I press a key the screen will reset to white and then show the numbers. If anyone has time to help me out it would be greatly appreciated.
EDIT: Thank you for everyone's help and I have solved the problem. However I haven't found a way to incorporate a decimal point into it. This code is the code that works except for the decimal point.

  #include <Keypad.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

String v1;
String num;

const byte ROWS = 4;
const byte COLS = 4;

char hexaKeys[ROWS][COLS] = {
  {'1', '4', '7', '*'},
  {'2', '5', '8', '0'},
  {'3', '6', '9', '.'},
  {'A', 'B', 'C', 'D'}
};

byte rowPins[ROWS] = {31, 22, 23, 24};
byte colPins[COLS] = {25, 26, 27, 28};

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

#define BLUE    0x001F
#define WHITE   0xFFFF

#define DATAOUT 11//MOSI
#define DATAIN 12//MISO
#define SPICLOCK  13//sck
#define SLAVESELECT0 10//ss

void setup()
{
  uint16_t id = tft.readID();
  tft.begin(id);
  tft.setRotation(1);
  tft.fillScreen(WHITE);
  tft.setTextColor(BLUE, WHITE);
}

void loop() {
  v1 = GetNumber();
  v1.toInt();
}
String GetNumber()
{
  char key = kpd.getKey();
  // while (key != '#')
  {
    switch (key)

    {
      case NO_KEY:
        break;

      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
        num = num + key;
        tft.setTextSize(5);
        tft.setCursor(10, 50);
        tft.print(num);
        break;
    }
    key = kpd.getKey();
  }
  return num;

}

Print your number tft.print(num); AFTER you append the key num=num + key, not before.

Your String num; is a local variable within the function, it get out of the scope when exit the function, you want to keep the value, declare it as a global variable.

do not combine keypress handling with display handling ... pressing a key should only update the value of a variable, nothing else ... the display function should only get its data from the variable

i think that you are not paying attention to what is in your code ... you complain about the screen turning white, and yet you have code like tft.fillScreen(WHITE); ... don't you think that you should be running the tft setup code like textColor and textSize only once?

Thank you for all who helped me. It is now working perfect. I only have one question: How would I implement a decimal point? I can't simply make another case for it because that would have to be a number. This is my new code

I couldn't put my new code in the comment so I updated the original code in the question. Thanks everyone!

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


text:
Custom build of arduino on a pcb
I am running my Arduino based from the ATMEGA328P-PU chip from a 4v battery with this setup:

Everything works great and now I will like to make my project permanent building a custom PCB from easyeda.com. Anyways this question is not about how to create the custom PCB I have already made one and it works great. This is the PCB that I created:

Because I liked it so much now I want to build it even better. For example now I will like to combine the crystal with the 22pf ceramic capacitors into one small part.
Question
Can I use ----THIS---- part instead of the basic 22pf capacitor and the big 16Mhz crystal? In other words I want to replace the left picture with the right picture:

If its possible to use part 7325-1600A2210-00 then where can I find information on what pins to connect to the atmega328 chip and what pins to connect to ground? 7325-1600A2210-00 has 4 pins. To me it makes sense to connect 2 of the pins to pins 9 and 10 and the other 2 pins to ground. Will this work?

Can I use ----THIS---- part instead of the basic 22pf capacitor and the big 16Mhz crystal?

No. That is just a crystal. You still need the capacitors.  If you want a single device then you need a ceramic resonator.
Also you're lacking any decoupling capacitors in your circuit. You may find it works for now, but it will become flaky when you start getting it to do things.


text:
ESP8266-01 & Arduino Uno Problem
I am having a problem when I want to run code like this on a Arduino Uno with esp8266-01. It's not working. In serial monitor nothing about esp.

#include <SoftwareSerial.h>
SoftwareSerial esp8266(2,3);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  esp8266.begin(9600);
  esp8266.print("AT+RST");
  delay(1000);
  esp8266.print("AT+CWMODE=1");
  esp8266.print("AT+CWJAP=\"ssisd\",\"pass\"");

}

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

}

But when I load to Arduino empty code and to serial monitor write "AT" it working or I can connect to
my wifi, but only with empty code.

RX is in pin 2 and TX is in pin 3.
And i flashing esp with this Tutorial

It should be a cross-connection like TX -> RX, RX -> TX, your wiring is wrong.

The wiring also doesn't match the code.  The code is using SoftwareSerial on pins 2 and 3 to talk to the ESP8266.  In the drawing it is connected to the hardware serial pins 0 and 1.

to communicate with the esp-01, if you have an empty sketch in Uno, you connect the esp-01 to RX/TX of the USB chip on Uno. this chip is connected with TX to RX pin of Uno and with RX to Tx pin of Uno.

I had before TX and RX conected to pin 2 nad 3 i wrote this under picture. I tryed switch RX and TX still nothing.  I tryed RX in pin 0 and TX in pin 1 and change code, but still nothing.

Try changing baud to 115200 ?? Sometimes it's not 9600, I talk about esp8266.begin ...


text:
Why HDOP in TinyGPS++ is less than 1?
HDOP is supposed to be greater than 1: https://en.wikipedia.org/wiki/Dilution_of_precision_(navigation)
But I get HDOP about 0.7. What does it mean?

Where can I found explanation of the output parameters?

HDOP can be less than 1 - See this article

Make the answer and I will mark it as the best

HDOP can be less than 1 according to this article.. I am no expert in this area, but according to the article, the HDOP=1 limit is based on 4 satellites; visibility and use of more than 4 satellites can reduce HDOP below this limit. When you think on it, this makes sense.
GPS specifications limit the inherent accuracy of a position solution through timing errors and vagaries in rf propagation through our atmosphere. Imagine drawing a vector from a GPS satellite to your receiver. The length of that vector represents the distance from the satellite to your receiver, but we depend on signal timing to infer distance/vector magnitude. In other words, we can only measure distance as accurately as we can measure time.
Now think about the accuracy of a position solution based on a single satellite. If we assume the receiver is confined to the surface of the earth (and the satellite is geostationary), the single vector of length L1 will intersect the surface of the earth forming a circle. Your position could be anywhere on that circle - which could be quite a large range of values!
Now imagine a 2nd satellite, a 2nd vector of length L2 tracing a second circle. Now your position is constrained to be those points where the two circles intersect - two points! With a third satellite, a 3rd vector of length L3, one of these two points will be eliminated.
Now replace those sharp lines with bands or swaths of some width D. In this case, the intersection describes a polygon instead of a point. We know our position is within the polygon, but with only three satellites that is the best we can do.
As you can see, adding more satellites will begin to "slice off" sections of the original polygon, making it progressively smaller. So: HDOP=1 represents the limit with 4 satellites; more satellites yield a smaller polygon, and smaller HDOP.

While writing this, I found a video that does a far better job than my words at describing the position solution process with multiple satellites.
This video is quite good also!


text:
How can I increase the responsiveness/speed of my stepper motor?
I'm trying to control the positioning of a NEMA17 bipolar stepper motor by turning the knob of a potentiometer, using an EasyDriver board.  The control part is solved.  My problem is that if I quickly turn the knob to one end of its range and then back, the stepper motor lags behind by about 1/5 of a second.
All the spec sheets for the motor says I should be able to expect a lot more responsiveness (based on max RPM, acceleration, etc...). I'd like to speed up the responsiveness of the motor to shorten the lag. My code is as follows:
//Declare pin functions on Arduino
#define stp 2
#define dir 3  //LOW => forward, HIGH => backward
#define MS1 4
#define MS2 5
#define EN  6

//Declare variables for functions
int x;
int const potPin = A0;
long potval; // current analog read of A0 voltage
int potrotsteps = 166; //num of stepper motor steps for 300-degree rotation
int cur_step_pos = 0; //current position in terms of stepper steps
long cmd_step_pos = 0; //step-position to command stepper motor to go to
int tomove; //num steps to move

void setup() {
  //stepper motor setup
  pinMode(stp, OUTPUT);
  pinMode(dir, OUTPUT);
  pinMode(MS1, OUTPUT);
  pinMode(MS2, OUTPUT);
  pinMode(EN, OUTPUT);
  resetEDPins(); //Set step, direction, microstep and enable pins to default states
  Serial.begin(9600); // initialize serial communication at 9600 bits per second
  Serial.println("\n\n\n#################    setup completed     #################");
}

void loop() {

  //map analog voltage read from pot to a step-position (0-166) of the stepper motor
  potval = analogRead(potPin);
  cmd_step_pos = potval * potrotsteps / 1023; // find where stepper motor should be in terms of step-position
  tomove = abs(cur_step_pos - cmd_step_pos);

  if (cmd_step_pos > cur_step_pos) { //if should-be position greater than current position
    digitalWrite(dir, LOW); // move forward
    CommandStepperMotor(tomove); //move forward by the diff in position
  } else { //if should-be position is lower
    digitalWrite(dir, HIGH); //move backward
    CommandStepperMotor(tomove); //move backward by diff in position
  }
  cur_step_pos = cmd_step_pos; //current position is now former should-be position

}

//GLOBAL FUNCTIONS

//Reset Easy Driver pins to default states
void resetEDPins() {
  digitalWrite(stp, LOW);
  digitalWrite(dir, LOW);  //default "forward" movement
  digitalWrite(MS1, LOW); // L-L => full steps, H-L => 1/2 step
  digitalWrite(MS2, LOW); // L-H => 1/4 steps, H-H => 1/8 step
  digitalWrite(EN, LOW); //Enable motor control
}

void CommandStepperMotor(int numsteps) {
  for (x = 0; x < numsteps; x++) {
    digitalWrite(stp, HIGH); //Trigger one step forward
    delay(1);
    digitalWrite(stp, LOW); //Pull step pin low so it can be triggered again
    delay(1);
  }
}

I understand that changing delay(1) to delayMicroseconds(100) in the CommandStepperMotor function should help, but as it turns out, anything smaller than a delay of 1 millisecond stalls the motor.  I've tried to Google other's solutions to the problem, but it seems they had no problem at all lowering the delay in sending the HIGH/LOW signals to the stepper pin to <1 ms.
Any ideas?  Thanks in advance!

Your problem is that you want to go from a standstill to full speed instantly. That just isn't going to happen. As you have seen there is a limit to how fast you can go from stationary.
If you want to go faster you will have to accelerate up to that speed.
The simplest way to do that is to use a library that is designed for it, such as the popular AccelStepper.h library.


text:
What do the TinyGPS++ output parameters mean?
TinyGPS++ give many output parameters. Where can I find explanation what do all output parameters mean? I don't understand what is the meaning of the following parameters:

Course Speed Card  Distance Course Car

UPD
2365 is distance to London
wnw is the direction to London: https://en.wikipedia.org/wiki/Points_of_the_compass#Compass_point_names
0.00 - Vertical speed?
0.06 - Horizontal speed?
294.06 - ???

As you can see when you look at the source code of the FullExample.ino that is part of the TinyGPS++ library, the values you marked are:

Course Speed Card*: The current speed (in km/h), course (in degrees) and cardinal course (which is the course translated to a cardinal direction on a compass, i.e. N,S,E,W, NE, NNW, etc.) of the GPS receiver (i.e. you).
Distance Course Card**: The distance (in km) and course and cardinal course to some location or waypoint (London in this example).

After the information you added in your edit, this means the following:

0.00 is your current course over ground (i.e. due North)
0.06 is current current speed over ground (i.e. as good as stationary)
N is your current cardinal course
2365 is the distance to London (km)
294.06 is the bearing to London from your location
WNW is the cardinal bearing to London

* this is also known as SOG (Speed Over Ground) and COG (Course Over Ground, which is used in (aero)nautical navigation) or Bearing.
** this is also known as DTG and CTS (Distance to Go and Course to Steer) when navigating to a GPS waypoint.

Thank you! The only thing I don't understand is why my GPS module is always moving to North and current course over ground is always 0. My GPS module doesn't move at all, so I understand that variable slow speed 0.06 is due to some errors. In this case the course and direction supposed to change randomly, but they are remain constant: 0.00 and N.

It might be your GPS module is only able to calculate a course if it moves more than a certain distance/speed. What I have seen from various GPS systems, this is normal behaviour.


text:
how to get file date and time (Timestamp) from a file on sd card with SD.h?
i want to get the date and time (Timestamp) of a specific file on sd card.
How can i do this?
I use the sd.h and can not use any other like SdFat.h

an old version of SdFat is under the hood of the SD library. the wrapper classes don't make the timestamp accessible. you would have to open the file SdFat way and then process it as in ls function in SdFile.cpp


text:
Is there any way to connect my old phone camera with an arduino?
I have an esp8266 wifi module, arduino uno and an old mobile. I was wondering if there is any way by which i could remove the camera from the mobile and connect it with my arduino in order to view video captured by the camera.
Is this possible by the hardware which i currently have? Or i will have to buy more hardware?
Please let me know if more information is required also give the link of helpful articles.

No. Just... no.

By the use of any additional hardware.

The phone and a WiFi/bluetooth connection and some software to perform the camera sharing?

It's not a question of hardware. It's a question of documentation. You will NOT be able to find anything anywhere about what the camera is or how it works. Without that there is ZERO chance of you doing anything.

is there any cheap way to perform the above task?

Buy an ESP32-CAM

Ok then please guide me if i buy an ESP32-CAM then will i be able to show the content captured to the browser using some web application?

Yes. There is an example in the ESP32 core. It even does facial recognition.

Is there any way to connect my old phone camera with an arduino?

Yes, but it may be a huge amount of work requiring expensive equipment and skills that take decades to acquire.
See Mike's Electric - Interfacing a cheap phone camera module to a PIC32 microcontroller. which is a great video and will give you an idea of what is involved. Note that he's using a 32-bit microcontroller with relatively large RAM on the chip. You might need to use a 32-bit Arduino (Due etc) not one of the 8-bit Arduinos (Uno etc).
Mike is the kind of person who could reverse-engineer a random camera module from an old phone but this isn't a project for a typical Arduino user like you or I.
Since these camera modules cost about $1, it is probably best to look for a camera breakout for Arduino that comes with documentation and software libraries.

An Uno is undersized and underpowered (speed) for this job. Without even considering how to transfer the image, an Uno has nowhere for it to go. The most modest cell phone cameras' images were probably 3 Megapixels, and even assuming 2 bytes of storage per pixel (allowing 5 bits for each of 3 colors), you'd need 6 MB  or 6000 KB to store the image. An Uno's RAM is 2K bytes before you subtract whatever RAM its program needs besides room to store the image. Based on those assumptions, an Uno would need another memory, 3000 times the size of its RAM, to hold the image.
Update:

Is there any possibility that the image is not stored in the arduino
  rather sent to the server in stream (i.e in small packets)?

I can't imagine why not - at least in theory - but I have no idea what kind of communication hardware might be built into the camera, or if you'd need to develop something on your own. But somehow you'll need to get the image data to the Arduino and in some kind of format you understand and can work with, at least once it gets to the web application. At this point, the critical piece of knowledge would be to know the specs of how the camera delivers image data - how fast, in what format, must the Arduino and the camera interact or does the data just pour out in a flood once started, ... ?
Your first steps will probably need to be to learn how some typical cameras handle this, and to figure out what specific camera you have and how that camera works. Then you'll have a much better idea about what it will take to complete your project.

Is there any possibility that the image is not stored in the arduino rather sent to the server in stream (i.e in small packets)?(because i am trying to develope a realtime web application)


text:
Arduino communication to Raspberry Pi using HC-05
I'm using two HC-05 modules on two Arduino UNO boards. One of my modules connected successfully to a raspberry pi port. However the other doesn't want to connect, but sometimes it does and then randomly disconnects. When I did manage to connect both modules to port on the pi I had code written to send data to the pi and display it in the terminal but only one Arduino data would show up on the pi terminal even though both were sending data. Is there an easier way to connect the modules? I've been using the bluetooth manager tool on the pi
void setup() {
 Serial.begin(9600);
 pinMode(8, INPUT); // first sensor input
 pinMode(7, INPUT); // second sensor input
 pinMode(6, INPUT); // third sensor input
 pinMode(5, INPUT); // fourth sensor input

}

void loop()
{

    int sensordata_1 = digitalRead(8); // read status and store it into variable
     {
          if(sensordata_1 == LOW)        //  CAGE 1
          {
            Serial.println("Arduino 1 s1: 1");  //
          }
          else
          {
            Serial.println("Arduino 1 s1: 0");
          }
          delay(200);

    }
}

void setup() {
 Serial.begin(9600);
 pinMode(8, INPUT); // first sensor input
 pinMode(7, INPUT); // second sensor input
 pinMode(6, INPUT); // third sensor input
 pinMode(5, INPUT); // fourth sensor input

}

void loop()
{

    int sensordata_1 = digitalRead(8); // read status and store it into variable
     {
          if(sensordata_1 == LOW)        //  CAGE 1
          {
            Serial.println("Arduino 2 s1: 1");  //
          }
          else
          {
            Serial.println("Arduino 2 s1: 0");
          }
          delay(200);

    }
}

import serial
import time

port = serial.Serial("/dev/rfcomm2", baudrate=9600)
port_2 = serial.Serial("
port.flush() # This wil flush any input and output buffer, so it will
#avoid receiving or sending bad data

while True:

    if(port.in_waiting > 0):
        data = port.readline().decode('utf-8').rstrip() # decode will translate
        #the data from unicode to byte
        print(data)

port_2 = serial.Serial(" is most likely a copy and paste error on your part, but needs to be fixed if you want 2 serial ports to deal with
You only read from port in your Python while loop without touching port_2. This is the reason you only see output from one serial port
You should use a robust serial data packet-system. Right now you have no way of ensuring that the data received in Python is corrupt or not. You can easily use the pip-installable Python package pySerialTransfer and compatible Arduino library SerialTransfer.h (installable via the Arduino IDE's Libraries Manager).

For theory behind robust serial communication, check out the tutorials Serial Input Basics and Serial Input Advanced.


text:
Arduino parsing Double is incorrect
Im having some problems with parsing gps coordinates with the arduino ide.
To be honest I want to process the data without a library.
From my sensor I get this String: 4815.98450
The result of String.toDouble(): 4815.9843750
I also parsed it on my own, but i got the same result: (yes this code is not nice ;))
char buf[10];
  msg.toCharArray(buf, 19);
  double num = 0.0;

  int c;

  c = buf[0] - '0';
  double num0 = (c * 1000);
  c = buf[1] - '0';
  double num1 = (c * 100);
  c = buf[2] - '0';
  double num2 = (c * 10);
  c = buf[3] - '0';
  double num3 = (c * 1);
  c = buf[5] - '0';
  double num5 = (c * 0.1);
  c = buf[6] - '0';
  double num6 = (c * 0.01);
  c = buf[7] - '0';
  double num7 = (c * 0.001);
  c = buf[8] - '0';
  double num8 = (c * 0.0001);
  c = buf[9] - '0';
  double num9 = (c * 0.00001);
  num = num + num0;
  num = num + num1;
  num = num + num2;
  num = num + num3;
  num = num + num5;
  num = num + num6;
  num = num + num7;
  num = num + num8;
  num = num + num9;

Does somebody have a solution for my problems?
Thank you very much :=)

There is no easy solution. The Arduino you are using does not support
double precision floating point. The type double is just an alias for
float, which has 24-bit accuracy.
Your program is actually giving you the correct result, as the float
closest to 4815.98450 is exactly 4815.984375.

Thank you for your answer! You helped me a lot because now i know it is no bug. But now im searching for a workaround :)

@Benjamin_Ellmer: Maybe store the integer and fractional parts separately?

double (or float) is just an inappropriate data type.
Perhaps you take int(4815) and float(0.98450) as two numbers?

And BTW, I bet from your sensor you don't get a String object.

Im reading the output from the TX of my sensor, so im pretty sure this is a string ;)      i figured out that i can do my calculation without the first 2 digits of the number.   there are some cases where it does not work but those cases are very unlikely

You can convert this to a long, do your arithmetic, and convert it back to an ASCII-Decimal number:
Remove the decimal point from the string. Convert the remaining string of digits to a long. Now you have the coordinate in binary, in units of the least significant decimal digit; 1 lsb == 0.00001, if you used 5 decimal places.
Manipulate your data however you need to using long integer arithmetic.
Divide the value by 10^ -(# of fraction digits you used). The quotient is the whole number part; the remainder is the fractional part. Print the quotient and a decimal point. Print the remainder padding with zeros to the left as necessary to result in your printing (# of fraction digits you used) total fraction digits.
The output conversion is even easier if you're willing to use sprintf():
Divide the value by 10^ -(# of fraction digits you used), as above. Let's assume 5 places as in your example:
char buffer[BIGENOUGH+1];
sprintf(buffer, "%ld.%05ld", value/100000, value%100000);

Note that I made two divisions to get the quotient and the remainder and assumed you could tolerate the performance hit. If you're expecting to crank out a lot of values and speed is a factor, you could look up or write a division routine that can return both the quotient and the remainder results from a single division.
Update: @edgar_bonet points out that the compiler is smart enough to notice this fragment uses both results of the numerically same division and avoids dividing twice after all.

Re the “routine that can return both the quotient and the remainder results from a single division”: this is exactly what avr-gcc does when compiling the example you provided.


text:
trying to make wemos d1 code modular causes collect2: error: ld returned 1 exit status exit status 1
#include "connection.h"

void setup() {
  Serial.begin(115200);
  Funcs::Connect conn;
  conn.connectWifi();
}

void loop() {

}

then connection.h file:
// connection.h

namespace Funcs
{
  class Connect
  {
    public:
      void connectWifi();
  };
}

and then connection.cpp
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "connection.h"
const char* ssid     = "ssid";
const char* password = "password";

namespace Funcs
{

  void connectWifi() {
    // Connect to WiFi network
    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
      delay(10);
      Serial.print(".");
    }
    Serial.println("");
    Serial.print("WiFi connected with ip ");
    Serial.println(WiFi.localIP());

  }
}

On compiling I get this error:
/Library/Arduino15/packages/esp8266/hardware/esp8266/2.5.2/cores/esp8266/HardwareSerial.h:76:
undefined reference to `Funcs::Connect::connectWifi()'

collect2: error: ld returned 1 exit status
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board WeMos D1 R1.

But I do not have Funcs::Connect::connectWifi() in my code, it was in old code.

Your connection.cpp is incorrect. Take a look Class code and header files to see how class methods should be defined.

You are calling Funcs::Connect::connectWifi() right here:
conn.connectWifi();

since conn is of type Funcs::Connect
But you defined a function Funcs::connectWifi():
namespace Funcs
{

  void connectWifi() {

where I think you meant to have connectWifi be a member of that Connect class.
namespace Funcs
{

  void Connect::connectWifi() {

That's not the only issue with your code, you also create the instance in setup and let it go out of scope after calling just the one function.  But that's a different kind of error.  It's legal code, just probably doesn't do what you want.


text:
IR signal: different libs, different bit/byte ordering?
For IR sender at Nano Every (ATMega4809-based) I am using infrared4arduino to send simple remote control codes. I am double-checking those with a Nano-based receiver with IRrecvDumpV2 example from IRremote library but I am receiving something else what I am sending (I think):
The sender has the following code using Infrared4Arduino:
   IrSignal* sig=Nec1Renderer::newIrSignal(0,0x906f); // cmd 0x90
   IrSenderPwm::getInstance(true)->sendIrSignal(*sig,1);

but the receiver dumps (besides some garbage like 0-bit JVC and SANYO frames):
Encoding  : NEC
Code      : FFF609 (32 bits)
unsigned int  data = 0xFFF609;

0x00 and 0xff (first 2 bytes of the "packet") are device and its logical complement, those are fine.
The command sent as 0x90 (followed by its logical complement 0x6f) is decoded as 0xF6 (plus its logical complement 0x09). Why? Is it an accident that 906f is f609 backwards?
What's going on here?
I will try to run both sender and receiver with the same lib (IRremote is not ported to Nano Every) but before I go ahead, better ask. Perhaps I am only doing some IR-beginner's mistake.

The command sent as 0x90 (followed by its logical complement 0x6f)  ... how do you know this?

you picked data that reads the same no  matter which is the bit order ... 1001 is same both directions ... transmit code, such as 1000

@jsotola That's the way the protocol works, as far as I understand. Device ID (0x00 in this case), its bit complement 0xff (for redundancy) and then command 0x90 (0b10010000) and its bit complenment 0x6f (0b01101111, again for redundancy).

you chose symmetrical data ... 10010000 reads 0x90 in one bit order and 0x09 in the other bit order, so it is not obvious how the data is being transmitted and received ... instead choose something like 11000100 which reads 0xC4 in one bit order and 0x23 in the other bit order

Solved, see the answer below.

It is the receiver (IRremote-based) which is decoding bits in reverse order. IRremote and IRLib2 implement the NEC protocol incorrectly (both on sending and receiving sides). More details in the issue report https://github.com/bengtmartensson/Infrared4Arduino/issues/52 .


text:
Possibility of clean the code?
Good night! Based on stuff I get a bit here and there, came up with a program for an Arduino Audio Selector with shift registers and some features. Working as expected, only missing connecting the relay boads, but that's for future. Since I have a few devices, instead of having to write all, is there anyway of I change for instance a line and then on display show that line?
Thanks. Here's my code, realy big, try to short the part of the shift registers but seems to me it was unstable.
Arduino selector 4x20

Please explain what you mean when you say "is there anyway of I change for instance a line and then on display show that line?". Which line are you talking about?

Sorry, forgot to mention... i was thinking in something like: line1 = mp3 player, cd 1 = sony, cd2 =pioneer, and when writing the sources, only need tho change at the begginning instead of having to scroll trough entire code. 73’s CT1JQJ

In traditional C they use #define / #ifdef . In C++ there are more possibilities but interpreting/guessing your question's background that might help already.

I see a lot of 'almost' repetitions like :
  if (RelaySourceDigi == 7) {
    shifter.setPin(16, LOW);
    shifter.setPin(17, LOW);
    shifter.setPin(18, LOW);
    shifter.setPin(19, LOW);
    shifter.setPin(20, LOW);
    shifter.setPin(21, LOW);
    shifter.setPin(22, HIGH);
    shifter.setPin(23, LOW);
    shifter.write();
    lcd.setCursor(0, 2);
    lcd.write(8);
    lcd.setCursor(2, 2);
    lcd.print("Coaxial 3");
  }

Move this to a separate function, and make an argument (or more) of items that vary.
This will greatly reduce your code, making it more managable/maintainable.
Below I changed the entire program. Note I didn't check for runtime errors, and it is highly possible I made some copy/paste errors, but it will give you a clue what you can change. As you can see, the program is radically shortened (and more maintainable).
What you need to do is:

Check each change
Check for copy/paste errors
Read a little bit about pointers (e.g. the &RelaySource and *t constructs)
Also I highly suggest not to use so many constants, but use enums, to denote the value for each different mode you have. So instead of case 1, you can write case TAPE_1.
Split loop in smaller functions (e.g. one function per mode).
I didn't install your libraries but used e.g. #include "LiquidCrystal_I2C.h" and stubbed all functions (meaning I can call them but they don't do anything, just to check for compiler errors in the main program).
Also instead of Aux, use a boolean (true, false).
You see I use a lot of (state - 1) constructs. It's common practice to start counting at 0, not at 1, it will make your life easier. Only when displaying a value for a user, add +1.
Below the program.
//Libraries
#include "LCD.h"
#include "LiquidCrystal_I2C.h"
#include "Shifter.h"

#define SER_Pin 8 //SER_IN 14 on 74HC595
#define RCLK_Pin 9 //L_CLOCK 12 on 74HC595
#define SRCLK_Pin 10 //CLOCK 11 on 74HC595
#define NUM_REGISTERS 3 //how many registers are in the chain
//initaize shifter using the Shifter library
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

const int ButtonPinUp = 2;
int ButtonPinUpState = 0;
const int ButtonPinDn = 3;
int ButtonPinDnState = 0;
const int MuteButtonPin = 5;
int MuteButtonPinState = 0;
const int AuxButtonPin = 4;
int AuxButtonPinState = 0;
const int fbutton = 6;
int RelaySource = 1;
int RelaySourceDigi = 1;
int RelayRec = 1;
int RecDigi = 1;
int Mute = 0;
int Mode = 0;
int Aux = 1;
int state = 0;
int old = 0;
int ButtonPoll = 0;

byte opt[8] = {
  0b00000,
  0b01110,
  0b11011,
  0b10001,
  0b10001,
  0b10001,
  0b11111,
  0b00000
};

byte coax[8] = {
  0b00100,
  0b01110,
  0b11111,
  0b10001,
  0b10001,
  0b01110,
  0b00100,
  0b00100
};

byte mut[8] = {
  0b00001,
  0b00011,
  0b00111,
  0b11111,
  0b11111,
  0b00111,
  0b00011,
  0b00001
};

byte outp[8] = {
  B00000,
  B00100,
  B00110,
  B11111,
  B11111,
  B00110,
  B00100,
  B00000
};

byte upp[8] = {
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111
};

byte inpp[8] {
  0b10000,
  0b10000,
  0b10100,
  0b10110,
  0b11111,
  0b00110,
  0b00100,
  0b00000
};

byte ann[8] {

  0b11111,
  0b10001,
  0b10101,
  0b10101,
  0b10001,
  0b10101,
  0b10101,
  0b11111
};

byte dnn[8] = {
  0b11111,
  0b10011,
  0b10101,
  0b10101,
  0b10101,
  0b10101,
  0b10011,
  0b11111
};

byte too[8] = {
  0b00000,
  0b00100,
  0b00110,
  0b11111,
  0b00110,
  0b00100,
  0b00000,
  0b00000
};

void printAtCursor(int a, int b, const char* c)
{
  lcd.setCursor(a, b);
  lcd.print(c);
}

void setup() {
  lcd.begin(20, 4);
  lcd.backlight();

  byte* list[] = {outp, coax, mut, opt, upp, inpp, ann, dnn, too };
  for (int n = 0; n < 9; n++)
  {
    lcd.createChar(n + 1, list[n]);
  }

  pinMode(fbutton, INPUT);
  pinMode(ButtonPinUp, INPUT);
  pinMode(MuteButtonPin, INPUT);
  pinMode(ButtonPinDn, INPUT);
  pinMode(AuxButtonPin, INPUT);

  for (int n = 11; n < 14; n++)
  {
    pinMode(n, OUTPUT);
  }

  printAtCursor(3, 0, "Digital/Analog");
  printAtCursor(3, 1, "Audio Selector");
  printAtCursor(4, 2, "Built-In DAC");
  printAtCursor(2, 3, "V2.0f (23052020)");
  delay(4000);
  lcd.clear();
}

void setPin(int first, int last, int pin)
{
  for (int n = first; n < last + 1; n++)
  {
    shifter.setPin(n, pin == n ? HIGH : LOW);
  }

  shifter.write();
}

void setLines(int a, int b, const char* t, int x = -1, const char* u = "")
{
    lcd.setCursor(0, a);
    lcd.write(b);
    lcd.setCursor(2, a);
    lcd.print(t);
    if (x != -1)
    {
      lcd.write(x);
      lcd.print(u);
    }
}

void loop()
{
  // shifter.clear(); //set all pins on the shift register chain to LOW
  shifter.write(); //send changes to the chain and display them
  //check button states
  ButtonPinUpState = digitalRead(ButtonPinUp);
  ButtonPinDnState = digitalRead(ButtonPinDn);
  MuteButtonPinState = digitalRead(MuteButtonPin);
  AuxButtonPinState = digitalRead(AuxButtonPin);
  ButtonPoll = digitalRead(fbutton);

  if (AuxButtonPinState == HIGH && RelaySource == 1 && state == 1) {
    lcd.clear();
    Aux           = ~Aux;
    digitalWrite(13, Aux == 0 ? LOW : HIGH);
  }

  if (ButtonPoll == HIGH) {
    state = old + 1;
  }

  lcd.clear(); // Happens in all cases
  switch (state) {
    case 1: // Fall through
    case 2: // Fall through
    case 3: // Fall through
    case 4:
      lcd.setCursor(1, state - 1);
      lcd.write(5);
      old = state;
      break;

    default:
      old = 0;
      break;
  }

  // Assuming state = 1..4
  if (ButtonPinUpState == HIGH)
  {
    lcd.clear();
    int* t = NULL;
    int maxValue = -1;

    switch (state)
    {
      case 1: t = &RelaySource;     maxValue = 8; break;
      case 2: t = &RelayRec;        maxValue = 5; break;
      case 3: t = &RelaySourceDigi; maxValue = 8; break;
      case 4: t = &RecDigi;         maxValue = 4; break;
      default: break;
    }

    *t = min(1, max(maxValue, *t + (ButtonPinUpState == HIGH ? 1 : 0) + (ButtonPinDnState == HIGH ? -1 : 0)));
  }

  if (MuteButtonPinState == HIGH) {
    lcd.clear();
    Mute = (Mute == 0 ? 1 : 0);
    digitalWrite(12, Mute == 0 ? HIGH : LOW);
  }

  // RelaySource
  setPin(0, 7, RelaySource - 1);
  if (RelaySource == 1 && Aux == 0)
  {
    setLines(0, 7, "D", 9, "A:");
  }
  else
  {
    const char* rs1[] = { "Line 1", "Line 2", "CD 1", "CD 2", "Tape 1", "Tape 2/DCC", "Tape 3/DAT", "MD", "MD" };
    setLines(0, 7, rs1[RelaySource - 1]);
  }

  if (RelaySource == 8)
  {
    shifter.setPin(0, LOW); //set pin 1 in the chain(second pin) HIGH
  }

  // RelayRec
  int         rr1[] = { 8      , -1   , 9       , 10      , 11       };
  const char* rr2[] = {"Source", "OFF", "Tape 1", "Tape 2", "Tape 3" };
  const int   rr3[] = { -1     , -1   , 9       , 9       , 9        };
  const char* rr4[] = { ""     , ""   , "2,3"   , "1,3"   , "1,2"    };

  setPin(8, 11, rr1[RelayRec - 1]);
  setLines(1, 6, rr2[RelayRec - 1], rr3[RelayRec - 1], rr4[RelayRec - 1]);

  // RelaySourceDigi
  setPin(16, 23, 17 - RelaySourceDigi);
  if (RelaySource == 1 && Aux == 0)
  {
    lcd.setCursor(7, 0);
    const char* t[] = { "Optical 1", "Optical 2", "Optical 3", "Optical 4", "Coaxial 1", "Coaxial 2", "Coaxial 3", "Coaxial 4" };
    lcd.print(t[RelaySource - 1]);
  }

  const char* t1[] = { "Sony 5-CD", "Sony MD[", "Optical 3", "Optical 4", "Philips CD-R [", "Coaxial 2", "Coaxial 3", "Coaxial 4" };
  const int   t2[] = { 4          , 4         , -1         , -1         , 2               , -1        , -1         , -1          };
  const char* t3[] = { "]"        , "]"       , ""         , ""         , "]"             , ""        , ""         , ""          };
  setLines(2, 8, t1[RelaySourceDigi - 1], t2[RelaySourceDigi - 1], t3[RelaySourceDigi - 2]);

  // RecDigi
  const char* t[] = { "Optical Out1", "Optical Out 2", "Coaxial Out 1", "Coaxial Out2" };
  setPin(12, 15, 11 + RecDigi);
  setLines(3, 6, t[RecDigi - 1]);

  delay(150);
}

Update
I wanted for myself to see how to clean it fully, so I tried below.
Still check for copy/paste problems, as I didn't execute the sketch (but it compiles without warnings).
Original sketch: 2746 bytes (8%) program storage space, 142 bytes (6%) of dynamic memory
Sketch below   : 1546 bytes (4%) program storage space,  40 bytes (2%) of dynamic memory.
Conclusion:

25% less program storage space used
67% less dynamic memory used
Less lines of code
Better readability
Better maintainability
No (or less) code duplication
Smaller function complexity
Less statements (added more to initialization)

Code:
//Libraries
#include "LCD.h"
#include "LiquidCrystal_I2C.h"
#include "Shifter.h"

const uint8_t SER_Pin = 8; //SER_IN 14 on 74HC595
const uint8_t RCLK_Pin = 9; //L_CLOCK 12 on 74HC595
const uint8_t SRCLK_Pin = 10; //CLOCK 11 on 74HC595
const uint8_t NUM_REGISTERS = 3; //how many registers are in the chain

Shifter _shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);
LiquidCrystal_I2C _lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

enum EMode
{
  RELAY_SOURCE,
  RELAY_REC,
  RELAY_SOURCE_DIGI,
  REC_DIGI,
  LAST_MODE
};

static const uint8_t _buttonPinUp = 2;
bool _buttonPinUpState = false;
static const uint8_t _buttonPinDown = 3;
bool _buttonPinDownState = false;
static const uint8_t _muteButtonPin = 5;
bool _muteButtonPinState = false;
static const uint8_t _auxButtonPin = 4;
bool _auxButtonPinState = false;
static const uint8_t _forwardButton = 6;
uint8_t _relaySource = 0;
uint8_t _relaySourceDigi = 0;
uint8_t _relayRec = 0;
uint8_t _recDigi = 0;
bool _mute = false;
bool _aux = true;
EMode _mode = RELAY_SOURCE;
bool _buttonPoll = false;

static const byte OPT[8]  PROGMEM = {  0b00000,  0b01110,  0b11011,  0b10001,  0b10001,  0b10001,  0b11111,  0b00000 };
static const byte COAX[8] PROGMEM = {  0b00100,  0b01110,  0b11111,  0b10001,  0b10001,  0b01110,  0b00100,  0b00100 };
static const byte MUT[8]  PROGMEM = {  0b00001,  0b00011,  0b00111,  0b11111,  0b11111,  0b00111,  0b00011,  0b00001 };
static const byte OUTP[8] PROGMEM = {  B00000 ,  B00100 ,  B00110 ,  B11111 ,  B11111 ,  B00110 ,  B00100 ,  B00000  };
static const byte UPP[8]  PROGMEM = {  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111 };
static const byte INPP[8] PROGMEM = {  0b10000,  0b10000,  0b10100,  0b10110,  0b11111,  0b00110,  0b00100,  0b00000 };
static const byte ANN[8]  PROGMEM = {  0b11111,  0b10001,  0b10101,  0b10101,  0b10001,  0b10101,  0b10101,  0b11111 };
static const byte DNN[8]  PROGMEM = {  0b11111,  0b10011,  0b10101,  0b10101,  0b10101,  0b10101,  0b10011,  0b11111 };
static const byte TOO[8]  PROGMEM = {  0b00000,  0b00100,  0b00110,  0b11111,  0b00110,  0b00100,  0b00000,  0b00000 };

static const byte* const CHAR_LIST[] PROGMEM = {OUTP, COAX, MUT, OPT, UPP, INPP, ANN, DNN, TOO };
static const uint8_t PINS[] PROGMEM = { _forwardButton, _buttonPinUp, _muteButtonPin, _buttonPinDown, _auxButtonPin };

static uint8_t* const    MODE_VALUES[] PROGMEM = { &_relaySource, &_relayRec, &_relaySourceDigi, &_recDigi };
static const uint8_t     MAX_VALUES[] PROGMEM = { 7             , 4         , 7                , 3         };

static const char* const RELAY_SOURCES[] PROGMEM = { "Line 1", "Line 2", "CD 1", "CD 2", "Tape 1", "Tape 2/DCC", "Tape 3/DAT", "MD", "MD" };

static const char* const RELAY_SOURCE_DIGI_1[] PROGMEM = { "Sony 5-CD", "Sony MD[", "Optical 3", "Optical 4", "Philips CD-R [", "Coaxial 2", "Coaxial 3", "Coaxial 4" };
static const int         RELAY_SOURCE_DIGI_2[]         = { 4          , 4         , -1         , -1         , 2               , -1        , -1         , -1          };
static const char* const RELAY_SOURCE_DIGI_3[] PROGMEM = { "]"        , "]"       , ""         , ""         , "]"             , ""        , ""         , ""          };

static const int         RELAY_REC_1[] PROGMEM = { 8      , -1   , 9       , 10      , 11       };
static const char* const RELAY_REC_2[] PROGMEM = {"Source", "OFF", "Tape 1", "Tape 2", "Tape 3" };
static const int         RELAY_REC_3[] PROGMEM = { -1     , -1   , 9       , 9       , 9        };
static const char* const RELAY_REC_4[] PROGMEM = { ""     , ""   , "2,3"   , "1,3"   , "1,2"    };

static const char* const DIGI_RELAY_SOURCES[] PROGMEM = { "Optical 1", "Optical 2", "Optical 3", "Optical 4", "Coaxial 1", "Coaxial 2", "Coaxial 3", "Coaxial 4" };

void printAtCursor(int a, int b, const char* c)
{
  _lcd.setCursor(a, b);
  _lcd.print(c);
}

void setup()
{
  _lcd.begin(20, 4);
  _lcd.backlight();

  for (int n = 0; n < 9; n++)
  {
    _lcd.createChar(n + 1, (byte*) CHAR_LIST[n]);
  }

  for (int n = 0; n < sizeof(PINS) / sizeof(uint8_t); n++)
  {
    pinMode(PINS[n], INPUT);
  }

  for (int n = 11; n < 14; n++)
  {
    pinMode(n, OUTPUT);
  }

  printAtCursor(3, 0, "Digital/Analog");
  printAtCursor(3, 1, "Audio Selector");
  printAtCursor(4, 2, "Built-In DAC");
  printAtCursor(2, 3, "V2.0f (23052020)");
  delay(4000);
}

void setPin(int first, int last, int pin)
{
  for (int n = first; n < last + 1; n++)
  {
    _shifter.setPin(n, pin == n ? HIGH : LOW);
  }

  _shifter.write();
}

void setLines(int a, int b, const char* t, int x = -1, const char* u = "")
{
    _lcd.setCursor(0, a);
    _lcd.write(b);
    _lcd.setCursor(2, a);
    _lcd.print(t);

    if (x != -1)
    {
      _lcd.write(x);
      _lcd.print(u);
    }
}

void ResetShifter()
{
  // _shifter.clear(); //set all pins on the shift register chain to LOW
  _shifter.write(); //send changes to the chain and display them
}

void ReadButtons()
{
  _buttonPinUpState = digitalRead(_buttonPinUp) == HIGH;
  _buttonPinDownState = digitalRead(_buttonPinDown) == HIGH;
  _muteButtonPinState = digitalRead(_muteButtonPin) == HIGH;
  _auxButtonPinState = digitalRead(_auxButtonPin) == HIGH;
  _buttonPoll = digitalRead(_forwardButton) == HIGH;
}

void HandleAuxButton()
{
  if (_auxButtonPinState && (_relaySource == 0) && (_mode == EMode::RELAY_SOURCE))
  {
    _aux = !_aux;
    digitalWrite(13, _aux ? HIGH : LOW);
  }
}

void HandlePollButton()
{
  if (_buttonPoll)
  {
    _mode = (EMode) ((_mode + 1) % EMode::LAST_MODE);
  }
}

void StartLcd()
{
  _lcd.clear(); // Happens in all cases
  _lcd.setCursor(1, (int) _mode);
  _lcd.write(5);
}

void HandleButtonPinUp()
{
  if (_buttonPinUpState)
  {
    static uint8_t* const modeValue = MODE_VALUES[_mode];
    static uint8_t maxValue = MAX_VALUES[_mode];
    *modeValue = min(0, max(maxValue, *modeValue + (_buttonPinUpState ? 1 : 0) + (_buttonPinDownState ? -1 : 0)));
  }
}

void HandleMuteButton()
{
  if (_muteButtonPinState)
  {
    _mute = !_mute;
    digitalWrite(12, _mute ? HIGH : LOW);
  }
}

void ProcessRelaySource()
{
  // RelaySource
  setPin(0, 7, _relaySource);
  if (_relaySource == 0 && !_aux)
  {
    setLines(0, 7, "D", 9, "A:");
  }
  else
  {
    setLines(0, 7, RELAY_SOURCES[_relaySource]);
  }

  if (_relaySource == 7)
  {
    _shifter.setPin(0, LOW); //set pin 1 in the chain(second pin) HIGH
  }
}

void ProcessRelayRec()
{
  setPin(8, 11, RELAY_REC_1[_relayRec]);
  setLines(1, 6, RELAY_REC_2[_relayRec], RELAY_REC_3[_relayRec], RELAY_REC_4[_relayRec]);
}

void ProcessRelaySourceDigi()
{
  setPin(16, 23, 17 - _relaySourceDigi);
  if (_relaySource == 0 && !_aux)
  {
    _lcd.setCursor(7, 0);
    _lcd.print(DIGI_RELAY_SOURCES[_relaySource]);
  }
  setLines(2, 8, RELAY_SOURCE_DIGI_1[_relaySourceDigi - 1], RELAY_SOURCE_DIGI_2[_relaySourceDigi - 1], RELAY_SOURCE_DIGI_3[_relaySourceDigi - 2]);
}

void ProcessRecDigi()
{
  static const char* const t[] PROGMEM = { "Optical Out1", "Optical Out 2", "Coaxial Out 1", "Coaxial Out2" };
  setPin(12, 15, 12 + _recDigi);
  setLines(3, 6, t[_recDigi]);
  delay(150);
}

void loop()
{
  ResetShifter();
  ReadButtons();

  HandleAuxButton();
  HandlePollButton();
  StartLcd();
  HandleButtonPinUp();
  HandleMuteButton();

  ProcessRelaySource();
  ProcessRelayRec();
  ProcessRelaySourceDigi();
  ProcessRecDigi();
}

Hello. Still trying to figure that, newbbie to arduino, thanks for the info

upvote for a very nice answer ... you can further simplify your code ...
lcd.setCursor(0, 2);
lcd.write(8);
lcd.setCursor(2, 2);
lcd.print("Sony MD [");
lcd.write(4);
lcd.print("]");
.... is same as this ....
lcd.setCursor(0, 2);
lcd.print("\x08 Sony MD [\x04]");

@jsotola thanks ... however, in my optimized code I'm not sure if I can use it as positions for the cursor are variable.

Thank you very much, after seeing this I realized I’m in fact a newbbie! I’ll try it tomorroy, meanwhile tried with a rotary encoder and menu but dont like that much.

I'm a professional software engineer, so this is kind of 'normal stuff' fo rme, although I still don't know much about many Arduino specific details. (btw the sketch can be improved more, but these are the 'low hanging fruit' items. If you next time try to make your loop as simple as I did know,  your overall design will be much easier in general.


text:
How to read data from ThingSpeak for esp8266
I am trying to read data from thingspeak for esp8266 but I couldn't do that. There is a link:
GET https://api.thingspeak.com/channels/123456/fields/1.json?api_key=***********&results=2
But how can I use it?

are you able to connect to some other website like stackexchange.com?

I don't know. But probably I can.

I believe Thingspeak supports MQTT. That would be preferable in my opinion.

How are you doing that? Please post your code

@StarCat What is MQTT.

MQTT is a message protocol for sending small messages to and from IoT devices like sensor values, status messages or receiving commands. It's simple to implement and very reliable. Here is an introduction to using an ESP8266 with Thingspeak and MQTT. It might work for you.

use ESP8266HttpClient library. see the examples.

check out https://shiftr.io/try to get an idea what MQTT is about

I directly code the esp8266 with thingSpeak library. Anyone who is interested look here:How to read data from thingspeak. And it worked. Thanks for your replies.


text:
Fading LED with different frequencies
I have a potentiometer attached to one analog port of arduino (assume A0)
I'm reading the value of that using input_voltage = analogRead (A0); which is a value between 0-1023.
So I want to map this value to frequency from 1Hz to 20Hz. Then I want to fade my LED using this frequency.
Tried to doing this map using int frequency = map (input_voltage, 0, 1023, 1, 20);
But how can i apply this frequency to LED?
I mean PWM has a constant frequency (about 500Hz). How should I apply frequencies from 1 to 20 to this LED in order to fade it?

Do you want to blink or flicker instead of dimming the led ? Or does 1Hz mean you want to fade for 1 sec between ON and OFF (20 Hz = 50 ms between On and Off will be no visible difference to immediate switching)

What is your goal? Do you want to change the rate at which you flash an LED? PWM (Pulse width modulation) doesn't to vary the  frequency of the output - it varies the duty cycle (ratio of on-time to off-time) of a fixed frequency output. If you want to dim the output of your LED based on the input pot, it seems to me you should map 0-1023 to 0-255 , an use the 0-255 output to control a PWM output pin. If you want to control the flashing rate of the LED, you need to use something other than PWM.

@DuncanC Thanks for your help. What is that "something other than PWM" ? For example timers?

There is a library in which you can change the frequency
Here is my example code I did long time ago I had the same problem
Get the library from here
Go ahead and try example code there and try to understand too.
Include the library first to code
my code
void setup() {
  pinMode(13, OUTPUT);
  pinMode(8, OUTPUT);
  digitalWrite(8,LOW);
  Serial.begin(115200);
  InitTimersSafe();
}
void loop() {
  //mapping
  long x = map(analogRead(A0),0,1023,1,20);
  bool b = SetPinFrequencySafe(9,x);
  digitalWrite(13,b);
  pwmWrite(9,127);
  Serial.print(x);
  Serial.print(" Hz ");
  Serial.println(b);
  delay(100);
}

Built in led will turn on if the frequency is stetted.
By the way led will turn on in 50% on and 50% off in one cycle in pin 9.
Use only the PWM pins in Arduino 3,9,6 etc.
Now you can change the PWM frequency...
I just put a led in the female socket in for easiness + terminal in 9 and - terminal in 8 to go to ground that's why I did put pin 8 to low.

Thank you for this complete and helpful answer!

Wouldn't it be easier to modulate the duty cycle of the PWM for fading a LED? By adapting the frequency between 1Hz and 20Hz, you'll just get changing flashing rates, unless you integrate the PWM output with a (rather large) capacitor.

@imalipusram I understand but the question asked me to do this using frequency...


text:
Arduino Atmega32U with nRF51 BLE by Adafruit limited to 5 second update rate?
Would like to ask for assistance with the code below.  It's the Adafruit Bluefruit Atmega32U LE module with Adafruit's Arduino IDE example "heart-rate monitor" sketch.   The code uses the hardware SPI setup with Adafruit's BLE code between the Atmega32U and the nRF51822 using AT Commands built into a BLE stack by Adafruit.
It works at the same speed in real-time on the PC's Arduino IDE USB serial terminal and also on the Android phone's nRF Connect app or any other BLE app that can read "notifications".
Problem:  If remove the module from the PC's USB (thus the serial stopped and only using BLE) the update rate on the BLE Android app slows down to 5 second intervals compared to the near real-time speed while connected to USB.   I tried many things, including commenting out the Serial commands  in the void loop() and also the delay(), but no change.  As if the BLE stack by Adafruit would have a update period limitation.  According to Adafruit, they do not give access to to their BLE stack.  But I could possibly load another BLE stack on this nRF51822 chip.   Also I do have the Adafruit Sniffer with Wireshark, but not an expert using it.
How can I get less than 1 second update rates?  The data stream is not in 1 second intervals. Maybe 10-15 seconds between readings, but I need it updated within 1 second of being read from the sensor.
https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le?view=all
#include <Arduino.h>
#include <SPI.h>
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"

#include "BluefruitConfig.h"

#if SOFTWARE_SERIAL_AVAILABLE
  #include <SoftwareSerial.h>
#endif

// Create the bluefruit object, either software serial...uncomment these lines
/*
SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);

Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN,
                      BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);
*/

/* ...or hardware serial, which does not need the RTS/CTS pins. Uncomment this line */
// Adafruit_BluefruitLE_UART ble(BLUEFRUIT_HWSERIAL_NAME, BLUEFRUIT_UART_MODE_PIN);

/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

/* ...software SPI, using SCK/MOSI/MISO user-defined SPI pins and then user selected CS/IRQ/RST */
//Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_SCK, BLUEFRUIT_SPI_MISO,
//                             BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS,
//                             BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

// A small helper
void error(const __FlashStringHelper*err) {
  Serial.println(err);
  while (1);
}

/* The service information */

int32_t hrmServiceId;
int32_t hrmMeasureCharId;
int32_t hrmLocationCharId;
/**************************************************************************/
/*!
    @brief  Sets up the HW an the BLE module (this function is called
            automatically on startup)
*/
/**************************************************************************/
void setup(void)
{
  while (!Serial); // required for Flora & Micro
  delay(500);

  boolean success;

  Serial.begin(115200);
  Serial.println(F("Adafruit Bluefruit Heart Rate Monitor (HRM) Example"));
  Serial.println(F("---------------------------------------------------"));

  randomSeed(micros());

  /* Initialise the module */
  Serial.print(F("Initialising the Bluefruit LE module: "));

  if ( !ble.begin(VERBOSE_MODE) )
  {
    error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
  }
  Serial.println( F("OK!") );

  /* Perform a factory reset to make sure everything is in a known state */
  Serial.println(F("Performing a factory reset: "));
  if (! ble.factoryReset() ){
       error(F("Couldn't factory reset"));
  }

  /* Disable command echo from Bluefruit */
  ble.echo(false);

  Serial.println("Requesting Bluefruit info:");
  /* Print Bluefruit information */
  ble.info();

  // this line is particularly required for Flora, but is a good idea
  // anyways for the super long lines ahead!
  // ble.setInterCharWriteDelay(5); // 5 ms

  /* Change the device name to make it easier to find */
  Serial.println(F("Setting device name to 'Bluefruit HRM': "));

  if (! ble.sendCommandCheckOK(F("AT+GAPDEVNAME=Bluefruit HRM")) ) {
    error(F("Could not set device name?"));
  }

  /* Add the Heart Rate Service definition */
  /* Service ID should be 1 */
  Serial.println(F("Adding the Heart Rate Service definition (UUID = 0x180D): "));
  success = ble.sendCommandWithIntReply( F("AT+GATTADDSERVICE=UUID=0x180D"), &hrmServiceId);
  if (! success) {
    error(F("Could not add HRM service"));
  }

  /* Add the Heart Rate Measurement characteristic */
  /* Chars ID for Measurement should be 1 */
  Serial.println(F("Adding the Heart Rate Measurement characteristic (UUID = 0x2A37): "));
  success = ble.sendCommandWithIntReply( F("AT+GATTADDCHAR=UUID=0x2A37, PROPERTIES=0x10, MIN_LEN=2, MAX_LEN=3, VALUE=00-40"), &hrmMeasureCharId);
    if (! success) {
    error(F("Could not add HRM characteristic"));
  }

  /* Add the Body Sensor Location characteristic */
  /* Chars ID for Body should be 2 */
  Serial.println(F("Adding the Body Sensor Location characteristic (UUID = 0x2A38): "));
  success = ble.sendCommandWithIntReply( F("AT+GATTADDCHAR=UUID=0x2A38, PROPERTIES=0x02, MIN_LEN=1, VALUE=3"), &hrmLocationCharId);
    if (! success) {
    error(F("Could not add BSL characteristic"));
  }

  /* Add the Heart Rate Service to the advertising data (needed for Nordic apps to detect the service) */
  Serial.print(F("Adding Heart Rate Service UUID to the advertising payload: "));
  ble.sendCommandCheckOK( F("AT+GAPSETADVDATA=02-01-06-05-02-0d-18-0a-18") );

  /* Reset the device for the new service setting changes to take effect */
  Serial.print(F("Performing a SW reset (service changes require a reset): "));
  ble.reset();

  Serial.println();
}

/** Send randomized heart rate data continuously **/
void loop(void)
{
  int heart_rate = random(50, 100);

  //Serial.print(F("Updating HRM value to "));
  //Serial.print(heart_rate);
 // Serial.println(F(" BPM"));

  /* Command is sent when \n (\r) or println is called */
  /* AT+GATTCHAR=CharacteristicID,value */
  ble.print( F("AT+GATTCHAR=") );
  ble.print( hrmMeasureCharId );
  ble.print( F(",00-") );
  ble.println(heart_rate, HEX);

  /* Check if command executed OK */
 // if ( !ble.waitForOK() )
 // {
   // Serial.println(F("Failed to get response!"));
  //}

  /* Delay before next measurement update */
 // delay(1000);
}

/////////////////AND BELOW IS THE BluefruitConfig.h TAB in ARDUINO IDE --This is a separate file under a new tab in the IDE////////////////..

    // COMMON SETTINGS
// ----------------------------------------------------------------------------------------------
// These settings are used in both SW UART, HW UART and SPI mode
// ----------------------------------------------------------------------------------------------
#define BUFSIZE                        128   // Size of the read buffer for incoming data
#define VERBOSE_MODE                   true  // If set to 'true' enables debug output

// SOFTWARE UART SETTINGS
// ----------------------------------------------------------------------------------------------
// The following macros declare the pins that will be used for 'SW' serial.
// You should use this option if you are connecting the UART Friend to an UNO
// ----------------------------------------------------------------------------------------------
#define BLUEFRUIT_SWUART_RXD_PIN       9    // Required for software serial!
#define BLUEFRUIT_SWUART_TXD_PIN       10   // Required for software serial!
#define BLUEFRUIT_UART_CTS_PIN         11   // Required for software serial!
#define BLUEFRUIT_UART_RTS_PIN         8    // Optional, set to -1 if unused

// HARDWARE UART SETTINGS
// ----------------------------------------------------------------------------------------------
// The following macros declare the HW serial port you are using. Uncomment
// this line if you are connecting the BLE to Leonardo/Micro or Flora
// ----------------------------------------------------------------------------------------------
#ifdef Serial1    // this makes it not complain on compilation if there's no Serial1
  #define BLUEFRUIT_HWSERIAL_NAME      Serial1
#endif

// SHARED UART SETTINGS
// ----------------------------------------------------------------------------------------------
// The following sets the optional Mode pin, its recommended but not required
// ----------------------------------------------------------------------------------------------
#define BLUEFRUIT_UART_MODE_PIN        12    // Set to -1 if unused

// SHARED SPI SETTINGS
// ----------------------------------------------------------------------------------------------
// The following macros declare the pins to use for HW and SW SPI communication.
// SCK, MISO and MOSI should be connected to the HW SPI pins on the Uno when
// using HW SPI.  This should be used with nRF51822 based Bluefruit LE modules
// that use SPI (Bluefruit LE SPI Friend).
// ----------------------------------------------------------------------------------------------
#define BLUEFRUIT_SPI_CS               8
#define BLUEFRUIT_SPI_IRQ              7
#define BLUEFRUIT_SPI_RST              4    // Optional but recommended, set to -1 if unused

// SOFTWARE SPI SETTINGS
// ----------------------------------------------------------------------------------------------
// The following macros declare the pins to use for SW SPI communication.
// This should be used with nRF51822 based Bluefruit LE modules that use SPI
// (Bluefruit LE SPI Friend).
// ----------------------------------------------------------------------------------------------
#define BLUEFRUIT_SPI_SCK              13
#define BLUEFRUIT_SPI_MISO             12
#define BLUEFRUIT_SPI_MOSI             11

Thank you @Edgar Bonet for helping with the code format edit. Appreciate it. I was a bit late figuring it out.

first remove while (!Serial);

I removed the "while (!Serial)" and still has the 5 second lag on both Android and iOS apps receiving data. It's quite regular 5 seconds, not random intervals. Also, there is nothing left in the void loop() that can slow things down.  If I open the serial terminal box in the Arduino IDE then the data streams at full-speed in real-time.   I wonder, if there is some bug in the Adafruit BLE stack?  No source code is given out.  Wondering, if there is any way to add in the code to run the serial terminal (or something to that effect) without actually having the USB cable plugged in the PC?

How can I test the BLE for max speed?  I ran an Adafruit BLE example program that tested the UART side of the BLE and had about 1-2 Kbs datastream, but this heartrate program uses GATT BLE and not UART.

try to remove Serial.begin or add Serial.end() at the end of setup()

Uncommented Serial.begin  and added Serial.end() and same 5 second delay, but when the Arduino IDE serial terminal is active on the PC the data flows fast.  I added a 10 second delay in the void loop(), and the data came in at 10 sec intervals on the iOS app, Then I activated the Arduino IDE serial.terminal window on the PC and the data remained at 10 sec intervals. I think the delay is in the Adafruit BLE stack. The BLE uses hardware SPI, not familiar with SPI...going to check into it.

I am also going to reinstall the Adafruit BLE support Arduino library files.

Looks like it's working now.  I am going to verify it, but it seems that the "verbose" error check mode slowed down the flow of BLE data. I changed it from "true" to "false" to turn it off.

@Juraj, thank you for your assistance. It helped me narrow down what to focus on and eventually led to the solution.

The "verbose" error check mode for debug in the "BluefruitConfig.h" tab slowed down the flow of BLE data. I changed it from "true" to "false" to turn it off.
#define VERBOSE_MODE true  // If set to 'true' enables debug output


text:
I'm trying to use a E18-D80NK but the output is always 1
i'm trying to use a E18-D80NK sensor with arduino but the output is always at 1, i really don't understand why
This is my code :
int irPin2 = 8;// define pint 2 for sensor

void setup() {
  Serial.begin(9600);// setup Serial Monitor to display information
  pinMode(irPin2, INPUT);// define pin as Input  sensor
}

void loop() {
  int out = digitalRead(irPin2);// read the sensor

    Serial.println(out);

  delay(250);
 // E18-D80NK Obstacle Sensor
}

and circuit:

What do you see when you attach an oscilloscope or a volt meter to the sensor? Does the LED on the sensor flash when you place an object in front of the sensor?

Unfurtunately i have not this facility but on arduino terminal i see all the time 1 in output

A cheap digital voltmeter (better: estimator) or an inexpensive DSO138 style oscilloscope will save your head from time to time...

do you see any error in my project? this is the datasheet http://www.energiazero.org/arduino_sensori/wiring%20the%20e18-d80nk%20infrared%20distance%20ranging%20sensor.pdf

There are a few possibilities for what is wrong:
1) The wiring may be wrong: the datasheet you reference lists two types (red,black,yellow) and (blue,brown,black) but in your pic it looks like you have (blue, grey, black).  I wouldn't assume the color coding of the sensor wires are correct.
2) The "pull-up" resister mentioned in the data sheet referenced (and included schematic) is not functioning as a pull-up resistor.  I would get rid of the resistor and plug the digital-output wire of the sensor directly into the arduino input.   Also, try configuring the input with pull-up like:  pinMode(irPin2, INPUT_PULLUP);
The Arduino inputs are high impedance and typically do not need a series resistor.

Your second point is probably the problem. The wiring diagram in the datasheet is wrong. The signal line needs a pull-up (either internal or external).

Thank you for your help, i tried to plug the digital-putput wire directly into the arduino input but it doesn't work, the output is still at "1" every time i put an object in front of the sensor

Then possibility 1) above is likely the issue.   There are not that many combinations so with trial and error you should be able to find the correct wiring arrangement.

i tried different combinations but that doesn't work.. i think that my sensor could be defective

Or perhaps the sensitivity adjustment on the sensor needs adjustment.

Your sensor pull low and not high, normally they pull high , I did however buy a few that is permanently on and then switch of ( pull low) when object in range.


text:
how to implement AES in LoRa Module with Hardware Flow control using ESP8266?
I am working on project where I have to do  AES encryption of plain text  received through normal UART port of ESP8266 create a cipher text and sending it to LoRa module (EByte E32 868T30D) through Software Serial port and recieve on the other end decrypt and get the plain text back. the problem I am facing is when I try to sendlarge array of bytes more than 300 or so I am getting garbled values on the other end. I am well aware of the 512 byte limit in LoRa module and so I tried using Hardware flow control by AUX pin that is available. Eventhough I am not successfull in implementing a working code. I have a grey area in how to implement such a hardware flow control in ESP8266. since its my first time I am seeking for help from experts in this field. My project requires me to send about 10kB of data over LoRa with minimum possible delay between each 512 byte transmission

/*===========================================================================================================================================================================
   ---------------------------------------------------- ESP8266 EByte 32 Lora Encryption Test ----------------------------------------------------
   Author: Mister.B
   Date: 10 May 2020
   Objective: To test AES256 ECB Encryption on LoRa Modules
   Third-Party ibraries used:
   1) aes256 - https://github.com/qistoph/ArduinoAES256
  ===========================================================================================================================================================================*/
#include "aes256.h"
#include <SoftwareSerial.h>

//EByte E32 Pin Configuration

#define M0 D5
#define M1 D6
#define AUX D2 // AUX HIGH means BUSY LOW means READY
#define RX_Pin D3
#define TX_Pin D4

//BaudRate Selection

#define E32_BAUD 9600
#define SERIAL_BAUD 9600

//AES Parameters
#define BUFFER_SIZE 2048 //2kB buffer to store the values
#define BLOCK_SIZE 16

//Timeout selection
#define UART_SERIAL_TIMEOUT 5000
#define E32_SERIAL_TIMEOUT 5000

//Debug Selection
#define DEBUG_CONSOLE true

//Class Instances
aes256_context ctxt;
SoftwareSerial E32(RX_Pin, TX_Pin);
//#define E32 Serial
//======Global Variables Declaration======
uint8_t key[] = {
  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
};
uint8_t data_buffer[BUFFER_SIZE] = {};
int i = 0, in_count = 0, out_count = 0;
unsigned long last_packet_arrival = 0;

//MACROS
#define ARRAY_SIZE(arr) ((sizeof(arr))/(sizeof(arr[0])))
#if DEBUG_CONSOLE == true
#define DUMP(str,i,buf,sz){Serial.println(str);\
    for(i=0;i<sz;++i){if(buf[i]<0x10)Serial.print('0');Serial.print(char(buf[i]),HEX);}\
    Serial.println();}
#else
#define DUMP(str,i,buf,sz)
#endif

void setup()
{
  Serial.begin(SERIAL_BAUD);
  E32.begin(E32_BAUD);
  pinMode(M0, OUTPUT);
  pinMode(M1, OUTPUT);
  pinMode(AUX, INPUT);
  /*
     Setting Ebyte 32 in Normal Mode (M0=LOW and M1=LOW)
  */
  digitalWrite(M0, LOW);
  digitalWrite(M1, LOW);
  delay(1000);
  DUMP("\nKey:", i, key, sizeof(key));
  aes256_init(&ctxt, key); // Send key for key scheduling
}
void loop()
{
  int frame_count = 0;
  out_count = 0;
  in_count = 0;
  last_packet_arrival = millis();
  /*
     RECEIVE DATA FROM EBYTE E32 LoRa
  */
  if (E32.available()) {
    out_count = 0;
    last_packet_arrival = millis();
    frame_count = (int)E32.read();
    while ((millis() - last_packet_arrival < E32_SERIAL_TIMEOUT) or (frame_count > out_count)) {
      out_count += E32.readBytes(data_buffer+out_count,58);
      if (out_count >= BUFFER_SIZE)Serial.printf("\n Input Buffer[%d] full :(", BUFFER_SIZE); break; //Prevent buffer overflow
    }
    Serial.printf("\nFc:%d", frame_count);
    frame_count = 0;
    Serial.printf("\nReceiveCount:%d\n", out_count);
    DUMP("\nRecived Data:", i, data_buffer, out_count);
    for (int n = 0; n <= (out_count / BLOCK_SIZE); n += BLOCK_SIZE)aes256_decrypt_ecb(&ctxt, data_buffer + n);
    DUMP("\nDecrypted Data:", i, data_buffer, out_count);
    for (int i = 0; i < out_count; i++)Serial.print((char)data_buffer[i]); yield();
    memset(data_buffer, 0x00, BUFFER_SIZE);
    out_count = 0;
  }
  /*
     RECEIVE DATA FROM UART Port
  */
  if (Serial.available()) {
    in_count=0;
    last_packet_arrival = millis();
    while ((millis() - last_packet_arrival) < UART_SERIAL_TIMEOUT) {
      in_count += Serial.readBytes(data_buffer + in_count, 58);
      if (in_count >= BUFFER_SIZE)Serial.printf("\n Output Buffer[%d] full :(", BUFFER_SIZE); break; // Prevent buffer overflow
    }
    /*
       Padding with zeros
    */
    if (in_count < 58) { // if Serial data entered is smaller than 58
      for (int i = in_count; i < 58; i++)data_buffer[i] = 0x00;
    }
    if (in_count > 58 && (in_count % 58 != 0)) { // if the Serial data is not multiple of 58 do padding with 0x00
      for (int i = in_count; i < in_count + (in_count % 58); i++)data_buffer[i] = 0x00;
    }
    Serial.printf("\nSendCount:%d", in_count);
    DUMP("\nData Entered:", i, data_buffer, in_count);
    //for (int n = 0; n <= (in_count / BLOCK_SIZE); n += BLOCK_SIZE)aes256_encrypt_ecb(&ctxt, data_buffer + n); // Encrypting whole data by 16 byte blocks
    //DUMP("\nEncrypted Data:", i, data_buffer, in_count);
    /*
       Add the length number of 512 byte in data frame
    */
    //uint8_t data_frame[BUFFER_SIZE + (BUFFER_SIZE % 58)] = {};
    //for (int i = 0; i <= BUFFER_SIZE; i++) data_frame[i + 1] = data_buffer[i];
    //data_frame[0] = (in_count / 58) + 1;
    //DUMP("\nSent Data:", i, data_frame, in_count + 1);
    /*
       Prevent buffer overflow in LoRa module using Hardware Flow control
    */
    uint8_t buff[58] = {};
//    for (int i = 0; i < (in_count / 464)+1 ; i++) //divide the data buffer into 464 byte frames
//    {
//      for (int j = 464 * i; j < (464 * i) + 464; j += 58) { //divide the 464 byte frames into 58 byte frames
        byte* f_count=(in_count<58) ? in_count : (in_count / 58) + 1;
        E32.write(f_count,1);
        for (int j = 0 ; j < in_count ; j+=58){
        memcpy(buff, data_buffer + j, 58);
        aes256_encrypt_ecb(&ctxt,buff);
        DUMP("\nEncrypted Data:", i, buff, 58);
        while (digitalRead(AUX) == HIGH) yield(); // wait for the pin to get LOW
        if (digitalRead(AUX) == LOW) { //if the module is READY send
          E32.write(buff, 58);
//          E32.flush();
        }
      }
//    }
    in_count = 0;
    memset(data_buffer, 0x00, BUFFER_SIZE);
    //memset(data_frame, 0x00, ARRAY_SIZE(data_frame));
  }
}

The ESPSoftwareSerial bundled with the esp8266 Arduino boards package supports transmit flow control with setTransmitEnablePin

@Juraj can we use this pin as an input in ESP8266 and hold say 10kB data in buffer until the pin is asserted to given logic and send data as chunks of 512 byte?

yes the transmit enable pin is an input. you can test availableForWrite to check if you can write more data to SoftwareSerial instance

@Juraj will test this tommorow and will revert back

sorry, I was wrong. the transmit enable has other purpose (as for RS485) and availableForWrite doesn't work as it should on ESPSoftwareSerial

Thanks for disclosing @Juraj. Luckily I didn't start test otherwise I would have been breaking my head. I would appreciate If you could help me with defining a function or a statergy to overcome this issue

it looks like the ESPSoftwareSerial doesn't have internal buffer. so you can simply check the state of the lora pin to decide if you can send.

@Juraj thats where I am facing a problem The User Manual saysWhen the module receives the first package from user, the AUX outputs low level. After all the data are transmitted into RF chip and transmission start, the AUX outputs high level At this time , it means that the wireless data package transmission is started, which enables the user to input another 512 bytes continuously. from this what I understand is I can send data whenever the AUX pin is LOW (in my case is it is HIGH bcoz of transisitor in between).

So, I tried sending a large byte array say more than 2kB and sniffed with a logic analyzer and I noticed the AUX pin stay continuously LOW even after the first 512 byte and aserts HIGH only 500ms after the TX transmission stopped

so you should send 512 bytes and then wait until the AUX pin changes from LOW to HIGH, before sending next 512 bytes?

@Juraj Thats what I understood from the statement given in User manual and tested the hypothesis with logic analyzer but the AUX pin stays low even after sending 512 bytes to the module and only returns HIGH only after 500ms from stopping transmission to the LoRa Module. I don't know is it what its supposed to be then I there is not point in checking at AUX pin and I have to work on something to stop the buffer overflow inside LoRa module and also I need a way for the receiving module to wait until all the send bytes are received and the receive has to send the data all at once through UART


text:
How to modify values inside a file
I am writing a wav file to an SD card on a ESP32 and that requires that every time I append data to the the end of the file I modify the header to set the right size in some fields.
I cannot find how to replace a value inside a file, I tried to write the new values with the seek function but unless I'm missing something looks like this deletes everything after the new value added.
I do not want to create a new file and to delete the old one as I will storing potentially large wav files and looks like wasting resources.
Is there a way to overwrite one value inside a file. I'm using SDlib but I'm open to others too.
Here the code I use to create the file and to update it:
#include "WavFileWriter.h"

void WavFileWriter::createFile(char const* filename, WavFileHeader* wavFileHeader)
{
  byte headerBuffer[44];
  wavFileHeader->getHeaderData(headerBuffer);
  File file = SD.open(filename, FILE_WRITE);
  file.write(headerBuffer, 44);
  file.close();
}

void WavFileWriter::appendData(char const* filename, WavFileHeader* wavFileHeader, byte* data, int dataLength)
{
  File file = SD.open(filename, FILE_WRITE);
  file.write(data, dataLength);

  byte headerBuffer[44];
  wavFileHeader->setFileSize(file.size());
  wavFileHeader->getHeaderData(headerBuffer);

  file.seek(0);
  file.write(headerBuffer, 44);
  file.close();
}

After calling appendData I end up with a file with just the header size (with the right header for a file with data but the data is gone).

why do you need to store the sound data in wav format?

can you identify the position of the sector on the SD card where the header is stored, keep a copy of it in RAM, keep this copy updated and write it to SD from time to time?

just store the raw data ... if you need a wav file then use something like Audacity to convert raw to wav

show your code.

added the code. I should have done from the beginning, my bad.

issue: if I have an fixed size file (8MB in my case), and I seek somewhere
an the file and do a write, the file size is truncated to the end of the block that I write. I am emulating a disk using a file and trying to write "sector data"
at various locations. Read using the same strategy works fine, but the writes destroy any data after the sector I write by truncating the file size. // running on an ESP32 using arduino IDE 1.8.13 environment // start with a file called CPM000.DSK on an SD card that is 25664512 bytes #include "FS.h" // file system support #include "SD_MMC.h" // uSD card suppo

The FILE_WRITE in SD library is 'append' (for historical reasons)
#define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)

so use
 File file = SD.open(filename, O_WRITE);

Looks like the ESP32 uses a different library and the definitions are different: #define FILE_READ       "r"
#define FILE_WRITE      "w"
#define FILE_APPEND     "a"

Should I use SPIFFS instead of SD?

SD.seek() is the API you're looking for.  It allow you to position the read/write pointer within a file.   In standard C++ the fseek() API is used.

OP is using seek()

I added the code so you can see if this is the expected usage.

It looks like you're not seek'ing to the end of the file when you attempt to append data.  Try:  file.seek(file.size()) between the SD.open() and file.write() in the WavFileWriter::appendData() method.