text:
Overhead of using 'new' to create object in dynamic ram vs automatic to create on stack
Let's suppose I have a class named Foo, and sizeof(Foo) is 10 bytes.
As I understand it, creating a Foo with 'automatic' scope (on the stack) has zero overhead. If the Object occupies 10 bytes, it consumes 10 bytes on the stack. Period.
I'm kind of fuzzy about how creating objects with 'new' works on an 8-bit AVR. I know that 'new' ultimately calls malloc(), and that on Windows/Linux, malloc() ultimately asks the operating system for memory whose management is up to the OS itself. But... with 8-bit AVR, there is no operating system. So, presumably, something else has ultimate responsibility for managing its heap. And presumably, there's some kind of overhead involved so it can keep track of which bytes have been returned to it by a destructor, and which ones are still in use.
So... using the hypothetical 10-byte Foo as an example... if I make 7 sequential calls in a row to new Foo(), how many bytes will it actually burn through (including overhead)?
For objects that have to be instantiated via new, but will persist "forever" (until the next reset), is there any special syntax that tells the compiler/malloc()/whatever, "This object will never be destroyed, so there's no need to preserve any information that would otherwise be necessary to release its memory eventually"?

Giving this a bit of context, assume View is a class with multiple templated subclasses (let's say, TemperatureView<int, int, int, int> and LabelView<int, int, int, const char*>), and I'm doing something like this:
const PROGMEM char* pLABEL = "Foo:";
View* views[] = {
    (new TemperatureView<0,3,0,2>{}),
    (new LabelView<1,4,0,pLABEL>{})
};

I'm trying to figure out just how big of a penalty hit (in terms of wasted ram from overhead) I'm taking by rolling it all into one nice, neat combined declaration instead of doing something like:
const PROGMEM char* pLABEL = "Foo:";
TemperatureView<0,3,0,2> firstTemp {};
LabelView<1,4,0,pLABEL> firstLabel {};
View* views[] = {
    &firstTemp,
    &firstLabel
};

(I originally wanted to put the objects whose addresses were being added to views[] in automatic/stack, but apparently, that's taboo because the compiler thinks the array will outlive the objects whose addresses would otherwise be stored there)

If you make an automatic variable, its lifetime is the lifetime of the function it is inside, so it won't persist forever, unless it is at global scope, or it is declared static.
The overhead of using new is the size of the object you allocate plus a couple of bytes to keep track of what that bit of memory is used for.

if I make 7 sequential calls in a row to new Foo(), how many bytes will it actually burn through (including overhead, which appears to be two bytes, see test below)

Seven times the size of the object plus the overhead I mentioned.
Normally you would release that memory with delete unless you want it kept forever.

For objects that have to be instantiated via new, but will persist "forever" (until the next reset), is there any special syntax that tells the compiler/malloc()/whatever, "This object will never be destroyed ...

No. It persists until you call delete which there is no compunction to do.
I wrote a test program for my Uno to see what the overhead was, to use new.
#include "memdebug.h"

void showFreeMemory ()
  {
  Serial.print (F("Free memory = "));
  Serial.println (getFreeMemory ());
  } // end of showFreeMemory

typedef struct {char s [20]; } foo;

void setup ()
  {
  Serial.begin (115200);
  Serial.println ();
  showFreeMemory ();   // 1664
  foo * bar = new foo;
  showFreeMemory ();   // 1642
  strcpy (bar->s, "Hello, world");
  Serial.println (bar->s);
  delete bar;
  showFreeMemory ();   // 1664
  }  // end of setup

void loop () { }

I'm trying to figure out just how big of a penalty hit (in terms of wasted ram from overhead)

Two bytes, by the looks, for each allocation.

(I originally wanted to put the objects whose addresses were being added to views[] in automatic/stack, but apparently, that's taboo because the compiler thinks the array will outlive the objects whose addresses would otherwise be stored there)

I'm not sure what you mean by that, can you give a concrete example?

I think you will save more memory by using PROGMEM, which you seem to be doing, a bit.
See my post here for ideas about doing that.

Reference
I got memdebug.h (and memdebug.c) from Andy's workshop - Debugging AVR dynamic memory allocation

Just as a small complement to the previous answer... The documentation
of the avr-libc has a whole page discussing the workings of malloc().
The section titled Implementation details states:

Dynamic memory allocation requests will be returned with a two-byte
header prepended that records the size of the allocation. This is
later used by free(). The returned address points just beyond that
header.

This is consistent Nick Gammon's experimental finding.

Very good. I was wondering why the overhead was only two bytes, since I thought you might need a length and a pointer, but only storing the length means you can deduce the address of the next chunk. Then when you free up chunks apparently there is a "free list", and they use the (now abandoned) part of memory to record where the next free chunk is. Presumably therefore the minimum amount that gets allocated is two bytes (plus the length).


text:
How does the motor shield determines how much voltage to supply to a motor?
Can i connect 6v DC motor and 12v DC motor, or 6v DC and 12V stepper to adafruit motor shield v1, and an external 12v power supply?
also, how does it determine how much voltage needs to be supplied to a motor? is it done by code, when we set the speed of the motor, or the frequency?
do i have to take care of how much voltage i am supplying to the motor shield?

Can i connect 6v DC motor and 12v DC motor to adafruit motor shield v1, and an external 12v power supply?

No.

how does it determine how much voltage needs to be supplied to a motor?

It doesn't. It supplies whatever voltage you supply through the power input.
You must match the power supply to the motor. The motor shield is merely a switch that turns the power on and off in the right way to change the speed and direction of the motor.

can i ask one more thing, when we set the speed and frequency of the motor in the code, what is the motor shield actually doing, is it changing the voltage, or the pwm signal?

It's turning the power on and off very rapidly. The speed at which it turns the power on and off is set by the PWM frequency. The on and off times are set by the PWM duty cycle. Due to the low-pass filter-like nature of an inductive load like a motor the end result is the appearance of a reduction of both voltage and current to the motor, resulting in a change in the overall power and thus speed of the motor. However I would not recommend relying on low PWM duty cycles as a way of "underpowering" a 6V motor from 12V as it is all too easy to get it wrong and smoke the motor.

got it. does it mean that i can't connect a dc motor and stepper at the same time, if the voltage ratings are different?

That is correct. For a 12V power supply you need 12V motors. Or a 12V to 6V voltage regulator (switching regulator ideally) and a second motor shield that you would then run at 6V.

source: Stack Exchange

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

sort: votes


text:
How I can divide information stream from bluetooth hc-06?
All good afternoon or evening. I am having a problem writing a sketch for Arduino using Arduino UNO and Bluetooth HC - 06.
My program does not divide the input stream of information into several variables. No matter how many variables I specify, they are considered as one.
Maybe I do not know all subtleties of the use of Serial.read(). Apparently from a sketch given below I get through Bluetooth two variables of color and var. A microcontroller perceives these two variables as one and as a result does not execute before him task. As a result we will be able to choose the color and change delay of blinking by this color.
If anybody knows how to correct this problem or can point me to a similar project I will be very thankful for any rendered help
const int rPin = 3;
const int gPin = 5;
const int bPin = 6;
int chosed_color;
int val;
int color;

void setup()
{
  Serial.begin(9600);
  pinMode( rPin, OUTPUT );
  pinMode( gPin, OUTPUT );
  pinMode( bPin, OUTPUT );

}

void loop()
{
while(Serial.available()>0)
  {
     color = Serial.read();
   if(color==1)
      {
       chosed_color = rPin;
      digitalWrite( rPin, HIGH );
      digitalWrite(rPin, LOW);
       return chosed_color;
      }
        else if(color==2)
      {
       chosed_color = bPin;
       digitalWrite( bPin, HIGH );
      digitalWrite(bPin, LOW);
       return chosed_color;
      }
         else if(color==3)
      {
        chosed_color = gPin;
       digitalWrite( gPin, HIGH );
       digitalWrite(gPin, LOW);
       return chosed_color;
      }
  }
if(Serial.available()>0)
{
  val = Serial.read();
}

      digitalWrite( rPin, HIGH );
      delay(val);
      digitalWrite(rPin, LOW);
      delay(val);
}

You have a misconception, how serial communication works. The data is transmitted one byte at a time and not in one bunch (even if you type it in the Serial Monitor in as one string). So, when you use distinct if- or while-statements for each variable, the data may arrive at any step in these statements, without any possibility to distinguish between the variables.
You have to ways dealing with serial messages (I prefer the latter for it is more flexible):

Constant message length: You can always send messages with the same length. This is suitable for small projects with only one functionality, so that you always send the same amount of data. In this case you can wait for all bytes of a message to arrive and then treat the message as a whole:

if(Serial.available() >= 2){
  variable1 = Serial.read();
  variable2 = Serial.read();
}

Using a delimiter character for each message: After each message you can send an extra byte, which value you treat as a delimiter for a message. Normally with this method you save each available byte in an extra buffer, until you receive your delimiter character (often the newline character is used '\n'):

void setup(){
  String message="";
}

void loop(){
  while(Serial.available>0){
    char c = Serial.read();
    if(c == '\n'){
      // Message is complete in buffer variable
      // Extract values from it
      if(message.length>0){
        byte variable1 = message[0];
      }
      if(message.length>2){
        int variable2 = (message[1] << 8) | message[2];
      }
      // Reset buffer variable
      message = "";
    } else {
      // Message is not complete, add byte to buffer variable
      message += c;
    }
  }
}

As said in the other answers you have to decide, how to send numerical data.

You can send direct byte data as I used in the code above. When you are sending a bigger value to the Arduino than 1 byte, you can take the corresponding number of bytes from the buffer and put them into one variable (<< 8 shifts the byte data 8 bytes to the left (in the direction of the MSB); | makes a bytewise or, that puts the bytes together in this code).
If you want to type in values in the serial monitor, you have to consider, that these are simple ASCII encoded strings. In this case you can use the String.toInt() function and it's siblings on a substring of your message, that contains the numerical value.

Communication is done only with bytes. A byte is ALWAYS a numerical value and you cant' transmit more than one byte at a time.
Saying that, you have two points to understand:
1) how do you want to "see" the result, from a human point of view?
2) how can you transmit more than one byte?
Just test this little sketch:
 void setup() {
Serial.begin(9600);
Serial.println(65);
Serial.println("65");
Serial.println("A");

Serial.write(65);
Serial.write('A');
}

void loop()
{
}

You will get on the serial monitor:
65
65
A
AA
Check for ASCII table on the internet and you'll see a list of code for letters representation.
Now: Serial.println("65"); don't print the number 65. It prints the "letters" for human representation of this number. In fact, 65 is a number but here is the "human word".
If you have 65 potatoes in a bag, a french will say "soixante cinq". An Englisman will say "sixty five" and a portuges will say "sesenta y cinquo". But they have all the same number of potatoes.
So the computer has the number but the human has the visual representation of the number.
Serial.print convert automaticly the numerical value in a "letter value". So when you do Serial.print(65) you don't print ONE byte... but TWO! First one is the human representation of 6 (which has the ASCII value of 54) and the the human representation of 5 (which has the ASCII value of 53)
Then the next line also print 65 because I have had "quote". So Serial.print dsplay this as a text.
The third write "A" which is a "text"
Then we use Serial.write(). Serial.write don't try to create a "human" point of view. So it uses directly the number as an ASCII value.
As 65 is the ASCII value for A, Serial.write(65) send only ONE byte and show it as the ASCII letters so A.
And of course Serial.write('A') give the same result.
For transmission, this is the very first point to understand: if you transmit a byte with value of 65 you'll get this same value on the other side. But depending on the way you display, you can be fooled and believe transmission was wrong ("I send 'A' and receive 65!")
For the second point ("how can I transmit more than a byte"): if you have 2 values to send and each one is on one byte, you have to send two bytes.
While receiving, you put the first byte coming in, in a variable, and the second in an other.
If you have to transmit a values using an INT so two bytes, you have to "break" the INT into bytes.
Eg the INT as a value of 3154 (in décimal). Its Hexa representation is 0x0C52.
You can break this in two blocks: 0x0C it the value of half of the INT and 0x52 is the other part.
So you can transmit 0x0C (higher part of the INT), then 0x52 (lower part of the INT) and while receiving you use the two bytes to "build again" the INT value.
To send 0x0C52 (INT) and 0xF345AC12 (LONG) you must send:
0x0C, 0x52, 0xF3, 0x45, 0xAC and 0x12 so a total of 6 bytes. Then while receiving you "build back" the value.
Of course, if you don't remember the way you "break for sending", you can be confused.
Because 0x0C, 0x52, 0xF3, 0x45, 0xAC and 0x12 can be seen as:

six bytes
three INT (0x0C52, 0xF345 and 0xAC12),
one long and two bytes (0x0C52F345, 0xAC and 0x12)
etc...

So you must "rebuild" according to the way you "break" the data while sending!
Hope this will help understanding.

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


text:
Arduino uno audio output quality improvement
I am new to electronics. I am going to play a sound truck from SD card when user push a button, Well This is very easy and there are lots of methods and codes to play it. the problem is with sound quality. I want to output sound into an speaker using 2.5 mm jack. here the problem appears. Is there any module which outputs Arduinos to speakers?
To me more clear in this tutorial https://www.instructables.com/id/Audio-Player-Using-Arduino-With-Micro-SD-Card/ we can play sound using simple speakers, is it possible to connect it to a higher quality speaker? like those pc speakers using 2.5 mm jack?
In fact I want to get better sound quality than the above tutorial using adrino.
thanks

The problem isn't the speakers, but that an Arduino is a terrible sound generator regardless of what you drive with it.  You can ironically do quite a bit better with an ATtiny85.  Otherwise you need something with an actual DAC.  Not sure who dowvnoted your question, but they have a point - there are many project writeups out there online, no need to ask a question here, especially when it is one which is too broad to fit the mission of this site.

I did not down vote your question.  However it is likely that it was down voted because you are not asking about a specific problem.  I would suggest you delete this question, go out and try something (your link is an excellent starting point) then come back with a well formed question about a specific problem or improvement.  Remember, none of the stackexchange web sites are good for discussions.   They are designed to create a data base of well defined questions and concise answers.

...I've changed my mind.  Instead of deleting your question - ask a more specific question about how to get better sound quality than is possible from the example you linked to.

@st2000 thanks very much. I updated my question

If a beginner, it is always better to copy then invent.  That said, I would recommend using this arduino.cc Simple Audio Player tutorial.  There are many different types of Arduino boards.  The Arduino Due uses a Microchip/Atmel SAM3X8E ARM Cortex-M3 CPU which contains at least one DAC.  It is assumed this will produce better sound than the PWM output of the slower ATmega328P processor found on an Arduino Uno.

thanks, how can I improve its quality? for example output the audio to an amplifier ?is there any key words which I can search?

The Simple Audio Player example I linked to in the answer uses an Arduino Due which contains at least 1 DAC.  This likely is an improvement in sound quality over the Arduino Uno which has no DAC, only PWM.  Futher, the Simple Audio Player example uses an OpAmp which appears to be driving a small speaker.  The example I linked to in the answer should have better sound quality then the example you linked to in your question.

I've re-read your question.  If you want to stick with the Arduino Uno and still want good quality sound you will likely need to push all sound related hardware and processing off the Arduino Uno board as the Arduno Uno is not powerful enough to handle the necessary data nor does it have a DAC.  Consider this board.

can't I simply connect the speakers output to an external amplifier? for example connect it using a jack to an speaker with internal amplifier?

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


text:
card.init(SPI_FULL_SPEED,SD_CS_PIN) returns false for Arduino Mega
I am working with a music shield, I have got my code from this site https://www.waveshare.com/Music-Shield.htm it works fine with arduino UNO but when I try to use it on MEGA it give me errors, Well I found that the problem is with this line
card.init(SPI_FULL_SPEED,SD_CS_PIN)

in uno SD_CS_PIN=10 I tried to change it to 53 based on this map
SPI   Uno   Mega
SS   10   53
MOSI   11   51
MISO   12   50
SCK   13   52

which is available on https://forum.arduino.cc/index.php?topic=165170.30 but still it returns false. What other options do I have to make it work on MEGA?
Thing that I am trying
#define SD_CS_PIN=10
#define VS_XRESET A0
#define VS_DREQ   A1
#define VS_XDCS   A2
#define VS_XCS    A3
void VS10XX::init(void)
{
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  pinMode(53, OUTPUT);

  pinMode(VS_XRESET, OUTPUT);
  pinMode(VS_DREQ, INPUT);
  pinMode(VS_XDCS, OUTPUT);
  pinMode(VS_XCS, OUTPUT);
  digitalWrite(VS_XDCS, HIGH);
  digitalWrite(VS_XCS, HIGH);

  reset();
}

In setup I added used this code but still does not work
void setup()
{
  Serial.begin(115200);
  pinMode(53, OUTPUT);//setting pin 53 to input
  player.begin();
}

the error code when I attempt to init sd card is 0 which says
/** timeout error for command CMD0 */

did you try the examples of the shields library? 'your' code is from insides of the library

@Juraj yes it is exactly that code, I am just changing parametrs to find out where is the problem

I think nothing needs to be changed for Mega. only set the pin 53 mode to output in .ino

@Juraj I removed all modifications from library and added pinMode(53, OUTPUT);//setting pin 53 to input to setup() but still does not work

from SD library comment of card.init: "The value one, true, is returned for success and the value zero, false, is returned for failure.  The reason for failure can be determined by calling errorCode() and errorData()."

@Juraj The error code is 1 and error data is 0 I tried to look it up in this source https://github.com/arduino-libraries/SD/blob/master/src/utility/Sd2Card.h but could not find it yet

53 is a SS pin if the Mega is SPI slave. Pin 10 is connected to shield to select it as a listening slave. So let the parameter set to pin 10. Additionally on Mega set pin 53 to output, otherwise the Mega can 'fall' into SPI slave mode.
SPI pins 50, 51 and 52 are connected to the ICSP header too. The 6 pin ICSP header is on the same place relative to Uno an Mega common pin headers.

thanks very much, Sorry for my noob question, I am new to arduino, So you mean I must set SD_CS_PIN to 10 and only add pinMode(53, OUTPUT); after SPI.begin(); ?  I updated the question

if it worked with 10 on Uno, then let it 10. for the shield the pin 10 is on the same place on Mega and Uno. 10 is a logical choice for SS on Uno. it must be an output (for the same reason 53 must be output on Mega) if SPI library is used

I tried based on what you said but it still returns false. I showed my code in question


text:
What causes Serial.available() to become false after Serial.read() gets data?
As serial data bytes are being read from the serial buffer by Serial.read(), are they removed from the Arduino's 64-byte serial buffer altogether?
In my current situation I'm using SoftwareSerial, but this question applies to both software and hardware serial connections.
EDIT: Based on a comment from @dandavis, I'd like to further clarify my question
How does Serial.read() interact with Serial.available()? Let's say that I have the usual setup:
while( Serial.available() ) {
    Serial.read();
}

What causes Serial.available() to become false?
EDIT 2: Changed question title for even further clarification...

the only way you can "remove" a byte, is to overwrite it. ... i do not think that the library code does that, because that would be a waste of resources. ... i'm sure that the pointer into the buffer is the only thing that has changed.

yes, you read() until available() is false, at which point the buffer is considered empty.

See the Wikipedia article Circular buffer. It has some figures and an animation that should help you understand how it works.

If they weren't, you would only ever be able to receive 64 bytes. Does that sound logical?

@dandavis Thank you for that clarification - That was pretty much what I was asking, but couldn't figure out how to ask (terribly sorry).I suppose it would have been best to phrase the question as 'How does Serial.available() go from true to false?

It is an internal buffer and only the pointer gets increased. It it visible in the source code off the project, located on github:
// Read data from buffer
int SoftwareSerial::read()
{
  if (!isListening())
    return -1;

  // Empty buffer?
  if (_receive_buffer_head == _receive_buffer_tail)
    return -1;

  // Read from "head"
  uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
  _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
  return d;
}

This third line from the bottom is the important part, it wraps back to the beginning if the buffer space has run out. If you call Serial.read(), the pointer is moved to the next position. So with the next Serial.read(), you'll get the next byte, if available. The byte itself gets overwritten only after the wrap (circular buffer).

You wrote: “The byte itself gets never overwritten”. It does, eventually, when that buffer cell is reused for storing a new incoming byte.


text:
ESP8266 sends data to the website but doesn't return status
I have problem with my esp8266 it connects to my site and sends 89 bytes of data but does return a confirmation status all i get is SEND OK but i don't get any confirmation from my server
This is my code below
 #include <SoftwareSerial.h>
#include<time.h>

SoftwareSerial ESP8266(3, 2); // RX, TX
//DEFINE ALL GLOBAL VAARIABLES HERE
unsigned int timeout_start_val;
char scratch_data_from_ESP[20];//first byte is the length of bytes
char payload[150];
byte payload_size=0, counter=0;
char ip_address[16];
char youtube_subs[10];
char youtube_views[13];
char current_temp[5];
char hi_temp[5];
char lo_temp[5];

//MODES
const char CWMODE = '3';//CWMODE 1=STATION, 2=APMODE, 3=BOTH
const char CIPMUX = '1';//CIPMUX 0=Single Connection, 1=Multiple Connections
//PASS word

const char SSID_ESP[]="Xamel";//"AOTEA TZ";//from constant

const char SSID_KEY[]="cewu5103";//"wyrnC592";

//DEFINE KEYWORDS HERE
const char keyword_OK[]="OK";
const char keyword_FAIL[]="FAIL";
const char keyword_Ready[] = "Ready";
const char keyword_no_change[] = "no change";
const char keyword_blank[] = "#&";
const char keyword_ip[] = "192.";
const char keyword_rn[] = "\r\n";
const char keyword_quote[] = "\"";
const char keyword_carrot[] = ">";
const char keyword_sendok[] = "SEND OK";
const char keyword_linkdisc[] = "Unlink";
const char keyword_CHECKCWMODE[] = "+CWMODE:3";
const char keyword_URL_CONNECTION_ERROR[]="Link typ ERROR";
const char TEST_URL[]="";

const char GET_URL[]="GET /ESP8266_BackEnd/SaveDetail.php?Name=";
int str1=strlen(GET_URL);
const char Name[]="Alex ";
int str2=strlen(Name);

const char TRAILING_URL[]="HTTP/1.1 \\r\\nHost: www.pick2get.com\\r\\n\\r\\n";
int str3=strlen(TRAILING_URL);
int strTotal=str1+str2+str3;

const char AT_CIPSTART[]="AT+CIPSTART=4,\"TCP\",\"pick2get.com\",80 \r\n";
const char AT_CIPSEND[]="AT+CIPSEND=4,";
//function prototype
boolean read_until_ESP(const char keyword1[], int key_size, int timeout_val, byte mode);
void serial_dump_ESP();
boolean setup_ESP(const char SSID_ESP[],const char SSID_KEY);
String url="&School=4D616B6F6E676F";
void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  //.print("Total string length");Serial.println(strTotal);

  // set the data rate for the SoftwareSerial port
  ESP8266.begin(9600);
  //

  //Serial.println(read_until_ESP(keyword_URL_CONNECTION_ERROR,sizeof(keyword_URL_CONNECTION_ERROR),5000,0));
  setup_ESP(SSID_ESP,SSID_KEY);

  ESP8266.print(AT_CIPSTART);
  ESP8266.print("");
  delay(1000);

  ESP8266.print(AT_CIPSEND);
  ESP8266.print(strTotal);
  ESP8266.print("\r\n");
  delay(1000);
  ESP8266.print("");
  ESP8266.print(GET_URL);
  ESP8266.print(Name);
  ESP8266.print(TRAILING_URL);
  delay(1000);
  ESP8266.print("");
  //ESP8266.println("&Grade=466F726D204F6E65");
  //ESP8266.println("&DeviceIP=3139322E3136382E302E31");
  //ESP8266.println(TRAILING_URL);

}

void loop() { // run over and over
  byte buffer[300];
  if (ESP8266.available()) {
   Serial.write(ESP8266.read());
  }
  if (Serial.available()) {
    ESP8266.write(Serial.read());
  }
}

This is the output generated on the serial monitor
ESP CHECK OK
ESP RESET OK
ESP RESET OK
timeout
ESP CWMODE SET FAILED
CWMODE ALREADY SET
SETTING SSID_ESP: Xamel
SETTING SSID_KEY: cewu5103
ESP SSID SET OK DEVICE CONNECTED
CHECKING FOR AN IP ADDRESS
IP ADDRESS = 192.168.4.1
ESP CIPMUX SET
AT+CIPSTART=4,"TCP","pick2get.com",80

OK
Linked
AT+CIPSEND=4,89

> GET /ESP8266_BackEnd/SaveDetail.php?Name=Alex HTTP/1.1 \r\nHost: www.pick2get.com\r\n\r\n
SEND OK

OK
Unlink

Can any one please help here.
When adding ESP8266.print("+IPD\r\n"); this is the output i get
    ESP CHECK OK
ESP RESET OK
ESP RESET OK
timeout
ESP CWMODE SET FAILED
CWMODE ALREADY SET
SETTING SSID_ESP: Xamel
SETTING SSID_KEY: cewu5103
ESP SSID SET OK DEVICE CONNECTED
CHECKING FOR AN IP ADDRESS
IP ADDRESS = 192.168.4.1
ESP CIPMUX SET
AT+CIPSTART=4,"TCP","pick2get.com",80

AT+CIPSEND=4,89

busy p...

OK
Linked
GET /ESP8266_BackEnd/SaveDetail.php?Name=Alex HTTP/1.1 \r\nHost: www.pick2get.com\r\n\r\n

wrong syntax

ERROR
AT+IPD

ERROR

I have managed to fix the lack of server response by removing the \r\n \nd replacing them with regular \r\n\r\n
enter code here
const char TRAILING_URL[]="HTTP/1.1 \r\nHost: www.pick2get.com \r\n\r\n";
int str3=strlen(TRAILING_URL);
int strTotal=str1+str2+str3;

const char AT_CIPSTART[]="AT+CIPSTART=4,\"TCP\",\"pick2get.com\",80 \r\n";
const char AT_CIPSEND[]="AT+CIPSEND=4,";

At this lines and was able to get a server response
+IPD,4,392:HTTP/1.1 400 Bad Request
Date: Tue, 15 May 2018 12:07:08 GMT
Server: Apache
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1

400 Bad Request
Bad Request
Your browser sent a request that this server could not understand.

finally i have debugged and fixed all the errors and the code works just fine
This and server returns a status 200
turns out it was just me pointing GET request in the wrong folder path with this line code at in the GET_URL variable
const char GET_URL[]="GET pick2get.com/ESP8266_BackEnd/SaveDetail.php?Name=";
I replaced with this
const char GET_URL[]="GET /ESP8266_BackEnd/SaveDetail.php?Name=";
And got the desired result
+IPD,4,166:HTTP/1.1 200 OK
Date: Tue, 15 May 2018 12:2249 GMT
Server: Apache
Upgrade: h2
Connection: Upgrade
Transfer-Encoding: chunked
Content-Type: text/html
2
OK
+IPD,4,191:16
Connected successfully
5c
 DATA TRANSMITTED SUCSSEFULLYSTUDENT NAME RECIVED: AlexSTUDENT SCHOOL NAME RECIVED:
3b
STUDENT GRADE RECIVED: DEVICE IP ADDREESS RECIVED:
OK
+IPD,4,42:1f
New record created successfully
0
Thanks a lot guys below is the complete working code
    /*
  Software serial multple serial test

 Receives from the hardware serial, sends to software serial.
 Receives from software serial, sends to hardware serial.

 The circuit:
 * RX is digital pin 10 (connect to TX of other device)
 * TX is digital pin 11 (connect to RX of other device)

 Note:
 Not all pins on the Mega and Mega 2560 support change interrupts,
 so only the following can be used for RX:
 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

 Not all pins on the Leonardo and Micro support change interrupts,
 so only the following can be used for RX:
 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

 created back in the mists of time
 modified 25 May 2012
 by Nolawi solomon

 */
#include <SoftwareSerial.h>
#include<time.h>

SoftwareSerial ESP8266(3, 2); // RX, TX
//DEFINE ALL GLOBAL VAARIABLES HERE
unsigned int timeout_start_val;
char scratch_data_from_ESP[20];//first byte is the length of bytes
char payload[150];
byte payload_size=0, counter=0;
char ip_address[16];

//MODES
const char CWMODE = '3';//CWMODE 1=STATION, 2=APMODE, 3=BOTH
const char CIPMUX = '1';//CIPMUX 0=Single Connection, 1=Multiple Connections
//PASS word

const char SSID_ESP[]="Xamel";//"AOTEA TZ";//from constant

const char SSID_KEY[]="cewu5103";//"wyrnC592";

//DEFINE KEYWORDS HERE
const char keyword_OK[]="OK";
const char keyword_FAIL[]="FAIL";
const char keyword_Ready[] = "Ready";
const char keyword_no_change[] = "no change";
const char keyword_blank[] = "#&";
const char keyword_ip[] = "192.";
const char keyword_rn[] = "\r\n";
const char keyword_quote[] = "\"";
const char keyword_carrot[] = ">";
const char keyword_sendok[] = "SEND OK";
const char keyword_linkdisc[] = "Unlink";
const char keyword_CHECKCWMODE[] = "+CWMODE:3";
const char keyword_URL_CONNECTION_ERROR[]="Link typ ERROR";
//const char TEST_URL[]="";

const char GET_URL[]="GET /ESP8266_BackEnd/SaveDetail.php?Name=";
int str1=strlen(GET_URL);
const char Name[]="Alex ";
int str2=strlen(Name);

const char TRAILING_URL[]="HTTP/1.1\r\nHost: www.pick2get.com \r\n\r\n";
int str3=strlen(TRAILING_URL);
int strTotal=str1+str2+str3;

const char AT_CIPSTART[]="AT+CIPSTART=4,\"TCP\",\"pick2get.com\",80 \r\n";
const char AT_CIPSEND[]="AT+CIPSEND=4,";
//function prototype
boolean read_until_ESP(const char keyword1[], int key_size, int timeout_val, byte mode);
void serial_dump_ESP();
boolean setup_ESP(const char SSID_ESP[],const char SSID_KEY);
//String url="&School=4D616B6F6E676F";
void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  //.print("Total string length");Serial.println(strTotal);

  // set the data rate for the SoftwareSerial port
  ESP8266.begin(9600);
  //

  //Serial.println(read_until_ESP(keyword_URL_CONNECTION_ERROR,sizeof(keyword_URL_CONNECTION_ERROR),5000,0));
  setup_ESP(SSID_ESP,SSID_KEY);

  ESP8266.print(AT_CIPSTART);
  ESP8266.print("");
  delay(1000);

  ESP8266.print(AT_CIPSEND);
  ESP8266.print(strTotal);
  ESP8266.print("\r\n");
  delay(1000);
  ESP8266.print("");
  ESP8266.print(GET_URL);
  ESP8266.print(Name);
  ESP8266.print(TRAILING_URL);
  //delay(3000);
  //ESP8266.print("");
  //delay(2000);
  //ESP8266.print("\r\n");
  //delay(2000);
  //ESP8266.print("");
  //ESP8266.print("AT+IPD\r\n");
  //ESP8266.println("&Grade=466F726D204F6E65");
  //ESP8266.println("&DeviceIP=3139322E3136382E302E31");
  //ESP8266.println(TRAILING_URL);

}

void loop() { // run over and over
  byte buffer[300];
  if (ESP8266.available()) {
   Serial.write(ESP8266.read());
  }
  if (Serial.available()) {
    ESP8266.write(Serial.read());
  }
}

boolean read_until_ESP(const char keyword1[], int key_size, int timeout_val, byte mode){
  timeout_start_val=millis();//for the timeout
  char data_in[20];//this is the buffer - if keyword is longer than 20, then increase this
  int scratch_length=1;//the length of the scratch data array
  key_size--;//since we're going to get an extra charachter from the sizeof()

 //FILL UP THE BUFFER
 for(byte i=0; i<key_size; i++){//we only need a buffer as long as the keyword

            //timing control
            while(!ESP8266.available()){//wait until a new byte is sent down from the ESP - good way to keep in lock-step with the serial port
              if((millis()-timeout_start_val)>timeout_val){//if nothing happens within the timeout period, get out of here
                Serial.println("timeout");
                return 0;//this will end the function
              }//timeout
            }// while !avail

    data_in[i]=ESP8266.read();// save the byte to the buffer 'data_in[]

    if(mode==1){//this will save all of the data to the scratch_data_from
      scratch_data_from_ESP[scratch_length]=data_in[i];//starts at 1
      scratch_data_from_ESP[0]=scratch_length;// [0] is used to hold the length of the array
      scratch_length++;//increment the length
    }//mode 1

  }//for i

//THE BUFFER IS FULL, SO START ROLLING NEW DATA IN AND OLD DATA OUT
  while(1){//stay in here until the keyword found or a timeout occurs

     //run through the entire buffer and look for the keyword
     //this check is here, just in case the first thing out of the ESP was the keyword, meaning the buffer was actually filled with the keyword
     for(byte i=0; i<key_size; i++){
       if(keyword1[i]!=data_in[i])//if it doesn't match, break out of the search now
       break;//get outta here
       if(i==(key_size-1)){//we got all the way through the keyword without breaking, must be a match!
       return 1; //return a 1 and get outta here!
       }//if
     }//for byte i

    //start rolling the buffer
    for(byte i=0; i<(key_size-1); i++){// keysize-1 because everthing is shifted over - see next line
      data_in[i]=data_in[i+1];// so the data at 0 becomes the data at 1, and so on.... the last value is where we'll put the new data
    }//for

           //timing control
            while(!ESP8266.available()){// same thing as done in the buffer
              if((millis()-timeout_start_val)>timeout_val){
                Serial.println("timeout");
                return 0;
              }//timeout
            }// while !avail

    data_in[key_size-1]=ESP8266.read();//save the new data in the last position in the buffer

      if(mode==1){//continue to save everything if thsi is set
      scratch_data_from_ESP[scratch_length]=data_in[key_size-1];
      scratch_data_from_ESP[0]=scratch_length;
      scratch_length++;
    }//mode 1

    /*  JUST FOR DEBUGGING
    if(ESP8266.overflow())
    Serial.println("*OVER");
    */

  }//while 1

}//read until ESP

boolean setup_ESP(const char SSID_ESP[],const char SSID_KEY[]){//returns a '1' if successful

  ESP8266.print("AT\r\n");// Send just 'AT' to make sure the ESP is responding
  //this read_until_... function is used to find a keyword in the ESP response - more on this later and in the function itself
  if(read_until_ESP(keyword_OK,sizeof(keyword_OK),5000,0))//go look for keyword "OK" with a 5sec timeout
    Serial.println("ESP CHECK OK");
  else
    Serial.println("ESP CHECK FAILED");
  serial_dump_ESP();//this just reads everything in the buffer and what's still coming from the ESP

   ESP8266.print("AT+RST\r\n");// Give it a reset - who knows what condition it was in, better to start fresh
  if(read_until_ESP(keyword_Ready,sizeof(keyword_Ready),5000,0))//go look for keyword "Ready" - takes a few seconds longer to complete
    Serial.println("ESP RESET OK");//depneding on the FW version on the ESP, sometimes the Ready is with a lowercase r - ready
  else
    Serial.println("ESP RESET FAILED");
  serial_dump_ESP();
  ESP8266.print("AT+RST\r\n");// Give it a reset - who knows what condition it was in, better to start fresh
  if(read_until_ESP(keyword_Ready,sizeof(keyword_Ready),5000,0))//go look for keyword "Ready" - takes a few seconds longer to complete
    Serial.println("ESP RESET OK");//depneding on the FW version on the ESP, sometimes the Ready is with a lowercase r - ready
  else
    Serial.println("ESP RESET FAILED");
  serial_dump_ESP();

   ESP8266.print("AT+CWMODE=");// set the CWMODE
   ESP8266.print(CWMODE);//just send what is set in the constant
   ESP8266.print("\r\n");
  if(read_until_ESP(keyword_OK,sizeof(keyword_OK),1000,0))//go look for keyword "OK"
    Serial.println("ESP CWMODE SET");
  else

    Serial.println("ESP CWMODE SET FAILED");//probably going to fail, since a 'no change' is returned if already set - would be nice to check for two words
    ESP8266.println("AT+CWMODE?");
    if(read_until_ESP(keyword_CHECKCWMODE,sizeof(keyword_CHECKCWMODE),1000,0))
    {
      Serial.println("CWMODE ALREADY SET");
      serial_dump_ESP();
    }
    serial_dump_ESP();

   //Here's where the SSID and PW are set
   Serial.print("SETTING SSID_ESP: ");
   Serial.println(SSID_ESP);
   Serial.print("SETTING SSID_KEY: ");
   Serial.println(SSID_KEY);
   //DEbug poin

   ESP8266.print("AT+CWJAP=");//
   ESP8266.print("\"");
   ESP8266.print(SSID_ESP);//
   ESP8266.print("\",\"");
   ESP8266.print(SSID_KEY);//
   ESP8266.print("\"\r\n");
  if(read_until_ESP(keyword_OK,sizeof(keyword_OK),5000,0)==1)//go look for keyword "OK"
    Serial.println("ESP SSID SET OK DEVICE CONNECTED");
  else if(read_until_ESP(keyword_FAIL,sizeof(keyword_FAIL),5000,0)==1)
    Serial.println("ESP SSID SET FAILED");
  serial_dump_ESP();

  //This checks for and stores the IP address
  Serial.println("CHECKING FOR AN IP ADDRESS");
  ESP8266.print("AT+CIFSR\r\n");//command to retrieve IP address from ESP
  if(read_until_ESP(keyword_rn,sizeof(keyword_rn),10000,0)){//look for first \r\n after AT+CIFSR echo - note mode is '0', the ip address is right after this
  if(read_until_ESP(keyword_rn,sizeof(keyword_rn),1000,1)){//look for second \r\n, and store everything it receives, mode='1'
    //store the ip adress in its variable, ip_address[]
    for(int i=1; i<=(scratch_data_from_ESP[0]-sizeof(keyword_rn)+1); i++)//that i<=... is going to take some explaining, see next lines
       ip_address[i] = scratch_data_from_ESP[i];//fill up ip_address with the scratch data received
//i=1 because i=0 is the length of the data found between the two keywords, BUT this includes the length of the second keyword, so i<= to the length minus
//size of teh keyword, but remember, sizeof() will return one extra, which is going to be subtracted, so I just added it back in +1
    ip_address[0] = (scratch_data_from_ESP[0]-sizeof(keyword_rn)+1);//store the length of ip_address in [0], same thing as before
    Serial.print("IP ADDRESS = ");//print it off to verify
    for(int i=1; i<=ip_address[0]; i++)//send out the ip address
    Serial.print(ip_address[i]);
    Serial.println("");
  }}//if first \r\n
  else
  Serial.print("IP ADDRESS FAIL");
  serial_dump_ESP();

   ESP8266.print("AT+CIPMUX=");// set the CIPMUX
   ESP8266.print(CIPMUX);//from constant
   ESP8266.print("\r\n");
  if(read_until_ESP(keyword_OK,sizeof(keyword_OK),5000,0))//go look for keyword "OK" or "no change
    Serial.println("ESP CIPMUX SET");
  else
    Serial.println("ESP CIPMUX SET FAILED");
  serial_dump_ESP();

 //that's it!  Could be done by nesting everything together, so if one thing fails, it returns '0', and if it gets all the way through it returns '1'...oh well

}//setup ESP

//pretty simple function - read everything out of the serial buffer and whats coming and get rid of it
void serial_dump_ESP(){
  char temp;
  while(ESP8266.available()){
    temp =ESP8266.read();
    delay(1);//could play around with this value if buffer overflows are occuring
  }//while

}//serial dump

What happens when you write +IPD\r\n as the next AT command? (https://github.com/espressif/ESP8266_AT/wiki/IPD)

@MaximilianGerhardt Can you elaborate more i am pretty much a beginner with the esp8266

I think you have to send this additional AT command to receive the data. Add ESP8266.print("+IPD\r\n"); as the last statement in your setup function. Refer to https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf

I have added that AT command and it seems there is a syntax error

Edit your question with the updated code and the error then.

Can you try the command "+IPD,500\r\n". This should request 500 bytes from the conenction. Try to play around with the number.

\\r\\n; are you sure you need to double escape those newlines?

@Gerben thanks alot apparently by replacing \r\n with the regular \r\n worked i am getting a response back apparently it status 400 but its progress still :)

@Gerben have ever had a situation where esp8266 would just hang after sending get request

I haven’t really done anything with an ESP. Try figuring out where the program halts. Most of the times it’s just a software problem. If the program sporadically stops working, you could look into enabling the WatchDog.

You need to have "Connection: keep-alive" in your http header, default is "Connection: close" and that's why you never get anything in return from the server.
I have described it all together with a code sample in https://arduino.stackexchange.com/a/54558/48149
The code sample uses the library WifiEsp to connect to ESP8266.

Yeah thanks i fixed that along time ago but still much respect for your contribution

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


text:
Keeping track of multiple actions
I have a number of LED's connected to an Arduino which receives a JSON dict.
The JSON dict determines which action the LED's follow (either a fade, a pulse, on, or off), but I'm having trouble working out how to get one LED to flash whilst another fades etc.
The important parts of the code looks like this:
int led_choice;
int led_brightness;
String pattern_name;
int pattern_length;

// Timer Setup
unsigned long led1_current_time;
unsigned long led2_current_time;
unsigned long previousFadeMillis[2];
unsigned long previousPulseMillis[2];
unsigned long current_time;

// fade setup
int fadeInterval = 50;
int fadeIncrement = 5;
int fadeDirection = 1;
int fadeValue = 0;
int maxPWM = 255;
int minPWM = 0;
int translated_pin;

// Pulse setup
int pulse_state = 0;

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
}

void loop() {

  current_time = millis();

  // CODE HERE TO READ SERIAL/MQTT, DECIPHER JSON AND EXTRACT VARIABLES

  if ( pattern_name == "fade"){
    fade(current_time, pattern_length, led_brightness, led_choice);
  } else if ( pattern_name == "pulse"){
    pulse(current_time, pattern_length, led_brightness, led_choice);
  }
  else if (pattern_name == "on" )
  {
    solid_running(led_choice, led_brightness);
  }
  else {
    switch_off(led_choice);
  }
}

/********** LED CONTROL FUNCTIONS *********/
void fade(unsigned long thisMillis, int fadeInterval, int maxPWM, int led_pin) {
  if (thisMillis - previousFadeMillis[led_pin] >= fadeInterval) {
    // yup, it's time!
    if (fadeDirection == 1) {
      fadeValue = fadeValue + fadeIncrement;
      if (fadeValue >= maxPWM) {
        // At max, limit and change direction
        fadeValue = maxPWM;
        fadeDirection = 0;
      }
    } else {
      //if we aren't going up, we're going down
      fadeValue = fadeValue - fadeIncrement;
      if (fadeValue <= minPWM) {
        // At min, limit and change direction
        fadeValue = minPWM;
        fadeDirection = 1;
      }
    }
    // Only need to update when it changes
    analogWrite(led_pin, fadeValue);
    // reset millis for the next iteration (fade timer only)
    previousFadeMillis[led_pin] = thisMillis;
  }
}

void pulse(unsigned long thisMillis, int on_duration, int on_speed, int led_pin){
  if (thisMillis - previousPulseMillis[led_pin] >= on_duration) {
    // save the last time you blinked the LED
    previousPulseMillis[led_pin] = thisMillis;

    // if the led is off turn it on and vice-versa:
    if (pulse_state == 0) {
      pulse_state = 1;
      // set the led with the ledState of the variable:
      analogWrite(led_pin, 255);
    } else {
      analogWrite(led_pin, 0);
      }
      pulse_state = 0;
    }
  }
}

void switch_off(int led_pin){
    analogWrite(led_pin, 0);
}

void solid_running(int led_pin, int led_brightness){
    analogWrite(led_pin, led_brightness);
}

If I send the json data telling LED 1 to pulse, as soon as I send a second string telling LED2 to fade, LED 1 stops pulsing.
I'm sure this is something obvious, but it's been driving me mad for days!
EDIT: Adding the second attempt at this
// Declare the number of LED's
const int led_count = 2;

// Setup the ENUM for the various Modes
enum EMode { Off, On, Pulse, Fade };
// Create the struct and initialise it
struct MMode {
  EMode pin_mode;
  int action_pin;
  int action_delay;
  int action_max;
  int action_min;
  int fade_direction;
  int fade_value;
  int fade_increment;
  unsigned long m_current_time;
  unsigned long previous_millis;
} leds[led_count] {
  {Fade, D4, 20, 255, 0, 1, 0, 1, 0, 0},
  {Fade, BUILTIN_LED, 20, 255, 0, 1, 0, 1, 0, 0}
};

void setup() {
  Serial.begin(9600);
  // Setup the Built-in LED
  pinMode(BUILTIN_LED, OUTPUT);
  // Setup the Red LED
  pinMode(D4, OUTPUT);
}

void loop() {
    for (int n = 0; n < led_count; n++) {
      leds[n].m_current_time = millis();
      switch(leds[n].pin_mode){
        case Fade:
          fade(leds[n]);
          break;
      }
    }
}

/********** LED CONTROL FUNCTIONS *********/
void fade(struct MMode led) {
  if (led.m_current_time - led.previous_millis >= led.action_delay) {
    // yup, it's time!
    if (led.fade_direction == 1) {
      led.fade_value = led.fade_value + led.fade_increment;
      Serial.print("Fade Up Value: ");
      Serial.print(led.fade_value);
      Serial.println("    ");
      if (led.fade_value >= led.action_max) {
        // At max, limit and change direction
        led.fade_value = led.action_max;
        led.fade_direction = 0;
      }
    } else {
      //if we aren't going up, we're going down
      led.fade_value = led.fade_value - led.fade_increment;
    //  Serial.print("Fade Down Value");
    //  Serial.print(led.fade_value);
    //  Serial.print("    ");
      if (led.fade_value <= led.action_min) {
        // At min, limit and change direction
        led.fade_value = led.action_min;
        led.fade_direction = 1;
      }
    }
    //Serial.print(led.fade_value);
    //Serial.print("  ");
    // Only need to update when it changes
    analogWrite(led.action_pin, led.fade_value);
    // reset millis for the next iteration (fade timer only)
    led.previous_millis = led.m_current_time;
    //Serial.print(led.previous_millis);
    //Serial.print("  ");
  }
}

This second iteration of the code appears to define the led's using the struct correctly, however when I upload it to the arduino, motor.fade_value gets set to 1, and never increments above this.
I get the feeling I'm missing something from the answers that I've had so far, but I'm not sure what that something is, and google isn't proving very helpful tonight...

your code has nothing to pulse or fade other led then `led_choice'

you need to call the fade/pulse function every time until the led state's change,
Start by creating full separate state for each LED,
struct LED_state{
    STATE state;

    unsigned long led1_current_time;
    unsigned long previousMillis;
    int pin;
    int fadeValue;
    int fadeDirection;
    int pulse_state = 0;
}

LED_state led[2];

STATE is an enum for each animation you do. Change the functions to take a pointer to this state. Initialize them in init().
Then create an update function which looks like:
void updateLED(LED_state* state){
    switch(state->state){
    case FADE:  fade(state);break;
    case PULSE: pulse(state);break;
    case ON:    solid_running(state);break;
    case OFF:   switch_off(state);break;
    }
}

Every time through the loop you call this update function for each LED's state.
To change what the LED does you the only need to update the state member in the struct for the LED.
  if ( pattern_name == "fade"){
    led[chosen_led]->state = FADE;
  } else if ( pattern_name == "pulse"){
    led[chosen_led]->state = PULSE;
  } else if (pattern_name == "on" ){
    led[chosen_led]->state = ON;
  } else {
    led[chosen_led]->state = OFF;
  }

So is this the same approach as @michel-keijzers (it seems to be to my eyes!), or does it differ?  If it differs, would you mind explaining what/why so I can make an informed decision? Thanks :)

it's pretty much the same, except I added more state into the per led struct

Without looking to the entire code, the best way is to use a 'mode' for each led. So for each led, keep track how it should behave (like Off, On, Blink, FadeOff, FadeOn etc) and some parameters (for the speed for fading for example). You can use a struct for this, like
enum EMode { Off, On, Pulse, FadeOff, FadeOn };
struct LedMode
{
   EMode mode;
   int fadeSpeed; // Only used when mode = fade off/on
};

LedMode ledModes[8]; // For e.g. 8 leds

When you get a JSon command, change the ledMode structure for that LED accordingly.
Than in the main loop use something like:
loop()
{
    for (int n = 0; n < 8; n++) // For each led
    {
       switch (ledModes[n].mode)
       {
       case Off:
         TurnOff(ledModes[n]);
         break;

       case On:
          TurnOn(ledModes[n]);
          break;

       case Pulse:
          Pulse(ledModes[n]);
          break;

       case FadeOn:
          FadeOn(ledModes[n]);
          break;

       ...
    }
}

To prevent going into each case all the time, add in the structure a 'Dirty' flag which is set to true by JSON and set to false after performed the change (e.g. you only have to switch a LED On or Off one time, not in every loop). For FadeOn/Off until it has reached 255 or 0. You also can use a PreviousMode and check if the mode has been changed since last time.
And for the Pulse/FadeOn/Off you need to add in the structure the last set value to be able to increase/decrease it, and the time it has changed last time.
Btw, you also can pass n and get LedModes[n] directly since it is global.

So this would move all of the code that controls the LED's out of the dedicated functions and directly into the main loop as part of the switch statement?

No, this was just the 'structure' .... PLEASE keep the separate functions, you can pass the structure for that led into the function (ledModes[n] where n is the LED that is currently handled in the loop). Use a separate function for each mode, that's very good programming practice.

That was what threw me, keeping them makes a lot of sense.
I'm used to coding in Python, but I struggle with translating things over to C!
Thanks.

You're doing a good job, it will make it easy if you use the struct with parameters, so every LED will have its own set of data, than in the mode functions (off, on, pulse etc) you can change the intensity LED depending on the parameters, independing of the other LEDs.

Unfortunately I can only accept one answer, and it was the part about referencing and setting the variables in @rachettFreak's answer that finally got this working for me.
Thanks for all the help, it really was appreciated, and if I could, I'd select your answer too!

His way is better actually, but I wanted to keep my solution simple to understand. It's good you understand his and can use it. Using struct or better: classes to keep information and functionality together is always a good idea, or better said: using structs/classes to keep different information/functionality separated is better.


text:
Can't flash ESP 32 Wroom

I have a new ESP32 Wroom attached to my USB and it shows up in the settings on my mac:

I do have another ESP thing from sparkfun which I can access via  /dev/cu.usbserial-DN02N1D8. This device I can flash without problems or read its mac address using esptool.py.
Connecting........_____....._____....._____....._____....._____....._____....._____

So I wonder how I can flash the ESP32.
Update: Added a picture of my board.

does the ESP32 contain a bootloader? ...... does it show up as a serial port?

I don't know for sure, but I would assume that it has a boot loader. It does not show up as an additional /dev/cu.XYZ entry, like the ESP-Thing does (/dev/cu.usbserial-DN02N1D8)

@jsotola, why do you ask if it has a bootloader? as far as I know the Espressif chips have only serial upload so without a bootloader from factory they were useless

How have you attached the device? The esp wroom 32 is not soldered onto any kind of breakout board, so have you soldered wires to rx/tx?! Do you actually have a reset button? If not, there is no chance to flash it. When trying to flash without the esp being in program mode I would expect exactly what you are seeing

you might have to hold some pins hi/lo to get it to flash. on some of my esp32 modules, that's holding down the flash button, on some it grounding a certain pin (0 i think) between starting the ide upload and actually uploading it, which is a bit of a balancing act. I recommend that once you get it flashed, use an OTA method to avoid the physical challenge.

I did fix the problem now.
My mac has USB-C and I was using a single USB-C to USB Dongle. And the serial port never showed up on my mac:
crw-rw-rw-  1 root  wheel   18,   5 Mar  8 10:53 /dev/cu.Bluetooth-Incoming-Port
crw-rw-rw-  1 root  wheel   18,   7 Mar  8 10:53 /dev/cu.Heinz-WirelessiAP
crw-rw-rw-  1 root  wheel   18,   3 Mar  8 10:53 /dev/cu.MALS
crw-rw-rw-  1 root  wheel   18,   1 Mar  8 11:02 /dev/cu.SOC

As soon as I used the Satechi USB Dock the Silicon Labs USB to UART port showed up in the list:
[...]
crw-rw-rw-  1 root  wheel   18,  13 Mar  8 11:04 /dev/cu.SLAB_USBtoUART

I can now communicate with the ESP32:
esptool.py --port /dev/cu.SLAB_USBtoUART read_mac

esptool.py v2.6
Serial port /dev/cu.SLAB_USBtoUART
Connecting........___
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
MAC: XXXXXXXXX
Uploading stub...
Running stub...
Stub running...
MAC: XXXXXXX
Hard resetting via RTS pin...

Please note that if you'll need the Drivers for the USB to Serial Chip from Silabs.
If you do not see the device showing up you'll need to load the kernel extension:
sudo kextload /Library/Extensions/SiLabsUSBDriver.kext/

After this you might to confirm the extension in the Privacy section of the mac settings. See this forum post for reference.

Flash ESP WROOM 32
kindly refer the link :
   https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#

Your link seems to have a typo in it.

@Besi the link is corrected


text:
How to send float numbers from python3 with struct to arduino
I have searched several questions and through google but could not find a solution. I am simply trying to send a float number from python3 with struct to arduino or if there is any other ways other than processing a char array at the arduino side because it is very slow in my opinion..
My arduino code:
void setup() {
  // initialize the serial communication:
  Serial.begin(9600);
}

void loop() {

  unsigned long t = millis();
  float x = analogRead(A3);
  float y = analogRead(A2);
  float c = Serial.read();
  Serial.println(c);
  //Serial.print(t/1000.0);
  //Serial.print(" , ");
  //Serial.print(x);
  //Serial.print(" , ");
  //Serial.println(y);

  // wait a bit for the analog-to-digital converter to stabilize after the last
  // reading:
  //delayMicroseconds(200);
  //delay(2);
  delay(250);
}

My python3 code :
import serial

import struct

arduino = serial.Serial('/dev/ttyACM0', 9600)
data = arduino.write(struct.pack('f', 111.32))
while True:
#    arduino.write(b"123")
    data = arduino.write(struct.pack('f', 111.32))

Getting the serial output as :
163.00
222.00
66.00
215.00
163.00
222.00
66.00
215.00
163.00
222.00
66.00
215.00
163.00

How can i solve my problem ?
EDIT : I changed the arduino code according to the answer the new arduino code is
float f;
void setup(){
  Serial.begin(9600);
}

void loop(){
  while(Serial.available() >= 3){

    f = Serial.read() << 24;
    f = ((unsigned long) f) | (Serial.read() << 16);
    f = ((unsigned long) f) | (Serial.read() << 8);
    f = ((unsigned long) f) | Serial.read();
    Serial.println(f);
  }
  Serial.println(f);
}

However, the output is now as such:
ovf
ovf
ovf
ovf
ovf
ovf
ovf
4294941184.00
4294941184.00
4294941184.00
4294941184.00
4294941184.00
4294941184.00
4294941184.00

I found a better way dealing with the conversion from char to float (note that you yourself have to add the setup() function for initiating Serial):
float f;
byte *fdata = (byte *) &f;
int num = 0;

void loop()
{
  if(Serial.available()){
    char c = Serial.read();
    if(c == 'B'){
      fdata[3] = c;
      num = 1;
    } else if(num == 1){
      fdata[2] = c;
      num++;
    } else if(num == 2){
      fdata[1] = c;
      num++;
    } else if(num == 3){
      fdata[0] = c;
      num = 0;
      Serial.write(fdata, 4);
      Serial.println(f);
    }
  }
}

First we are defining our float variable f and then a pointer of type byte named fdata. We are setting this pointer to point to our float variable. Now you can treat this pointer as an array. Since the type of the pointer is byte, we can access the first byte of f with typing fdata[0]. The other bytes can be accessed through fdata[1], fdata[2] and fdata[3].
In the loop example we are checking, if there is any byte in the buffer and read it. If it is the value of the character 'B' (which I used as a trigger, that your float starts, since the float number 111.32 starts with this value) we copy it to the last (most significant) byte of the array (aka float variable f). One after another we are doing the same with the other bytes.
When we received the last of the 4 bytes, we write the value back to Serial, once as pure byte data and once as ASCII encoded string.
In Python you can use the code, you already used:
arduino.write(struct.pack('>f',111.32))

You can read the output of the above sketch back with
arduino.readline()

PS: From my tries I guess the previous problem with getting ovf was, that the byte order was reversed (which simply would have been solved by using <f for the struct in python). But I personally like this way better, because it uses less casting.

Thank you for this and previous answers !! This will do i guess.

There is no way around dealing with serial bytewise, since the communication over serial relies on bytes as a unit. You can write the received bytes directly to the float variable. That is faster, than save them to a char array first:
float f = Serial.read() << 24;
f = ((unsigned long) f) | (Serial.read() << 16);
f = ((unsigned long) f) | (Serial.read() << 8);
f = ((unsigned long) f) | Serial.read();

With this the bytes of the float value have to be send with the order from most significant to least significant. I don't know, how the data is formatted, if you send a struct over python. The casting to unsigned long is important here to do the bitwise OR (unsigned long and float have both 4 bytes). (I tried it and it works for me)
Also be aware, that you shouldn't read from Serial, when there is no received byte in the buffer. You can check this with Serial.available(). If there is no new byte in the buffer the Serial.read() function returns an integer with value -1
EDIT:
The code above works, if you transmit the data directly as byte. In your comment you wrote, that you want to write arduino.write(b"111.32") in python. Here you are transmitting an ASCII string representation of the float number 111.32. This is not as fast as transmitting byte data (since you may need way more bytes for one float than 4). In this case you can use either Serial.parseFloat() to get the float from the serial buffer (but ensure, that all bytes for this number have been received with Serial.available()) or you can save the bytes to a string and using String.toFloat() to get the float out of it.
Since you wanted to do it the fast way, you should transmit the numbers as byte data. To do this in python, have a look at the answer of this question. It explains the python code for it (be sure, that you get the ordering of the bytes the same in python and Arduino).

When I try your code it gives an error like invalid operands of types 'float' and 'int' to binary 'operator| to all |= operators. I can send the float number as arduino.write(b"111.32") . Will this be better for your approach? I also added the Serial.available() part thank you.

Ah, ok. Now I understand, what you are trying to do. I will edit my answer. And yes, I didn't anticipated, that you have to cast

Thank you for your reply. However, I am still stuck at a point. You say that i have to send it as byte data and the way I change a float number to a byte representation is data = bytes(23.2) right ? and then i try arduino.write(data) but data = bytes(23.2) gives an error which says  float object is not iterable. I know I ask much but can you also provide a python sample code please ? Or when i try to do it with arduino.write(struct.pack('>f', 23.2)) it gives the serial output as ovf

I added a link to a question, which answers this for you

Thank you for the link. I have already checked that question and got the struct way from there. However, when I use your code to read the data i got overflow. Couldn't solve it. :( Updated the question accordingly


text:
How to scale a bitmap (uint8_t array) in Arduino?
So I have a project where I send text to an Arduino, which is then printed out as a QR code on a thermal printer that can take a bitmap image with a given width and height.
Is there a way I can "scale up" the "image," making it so one pixel is scaled up to 4 or 8 pixels?
Additionally, would it be possible to add a "quiet zone" of sorts on the left side of the image, as I am not able to offset/justify it to the middle.
QR Code lib: https://github.com/ricmoo/QRCode
Thermal printer lib: https://github.com/adafruit/Adafruit-Thermal-Printer-Library

Trying to splice in the QRPrint library causes the ESP32 to crash over and over.

Which Arduino? Most of them wouldn't have enough RAM for that.

@NickGammon I am using an ESP32, which has an Arduino core. :)

You didn't tell use the size of your QRCode, nor the type of Arduino you
are using. So I am just going to guess that your problem is that you may
have enough RAM to store the raw QRCode, but not enough to store a
scaled bitmap version.
The Adafruit tutorial for their thermal printer library suggests
printing bitmaps with the method:
printBitmap(width, height, tablename)

where tablename is an array holding the bitmap data. This will
obviously not work if you don't have enough RAM to store the array.
Fortunately, there is an overloaded method:
void Adafruit_Thermal::printBitmap(int w, int h, Stream *fromStream)

that allows you to stream the image data instead of preparing it in RAM.
You can create a stream that delivers arbitrary data by writing a class
that derives from Stream. Here is a tentative, untested
implementation, that delivers a scaled-up QRCode one pixel at a time:
// Stream a scaled QRCode one pixel at a time.
class QRCodeStream : public Stream
{
public:
    QRCodeStream(const QRCode &code, uint8_t scale = 1)
    : qrcode(code), scale(scale) {}

    // Output: writing to this stream is a no-op.
    size_t write(uint8_t) {}
    void flush() {}

    // Input delivers the QRCode pixels.
    int available();
    int peek();
    int read();
private:
    QRCode &qrcode;
    uint8_t scale;
    bool done = false;
    uint8_t code_x = 0;  // coordinates of the QRCode module
    uint8_t code_y = 0;
    uint8_t pix_x = 0;  // pixel coordinates within the module
    uint8_t pix_y = 0;
};

int QRCodeStream::available()
{
    // For simplicity, pretend the bytes come one at a time.
    if (done) return 0;
    else return 1;
}

int QRCodeStream::peek()
{
    if (done) return -1;
    if (qrcode_getModule(&qrcode, code_x, code_y)) {
        return 0;  // black
    } else {
        return 255;  // white
    }
}

int QRCodeStream::read()
{
    if (done) return -1;
    int data = peek();

    // Move to the next pixel.
    if (++pix_x >= scale) {
        pix_x = 0;
        if (++code_x >= qrcode.size) {
            code_x = 0;
            if (++pix_y >= scale) {
                pix_y = 0;
                if (++code_y >= qrcode.size) {
                    done = true;
                }
            }
        }
    }

    return data;
}

This would be used as
printer.printBitmap(width, height, QRCodeStream(qrcode, scale));

Note that QRCodeStream delivers the image data as 8-bit gray scale,
where each pixel is returned as one byte, either 0 (for black) or 255
(for white). This is likely not the format expected by the thermal
printer library, which seems to expect 1-bit black and white data, with
8 pixels packed in each byte. You will have to adapt the code for
the right format, which will likely be tedious, but not overly complex.
I leave that “as an exercise to the reader”.

Apologies. I am using an ESP32, and the Arduino IDE reports a Max Mem of 327680 bytes.
And I am aiming for a Version 3 QR Code at minimum :)

And here is the results of scales 1-3: https://i.imgur.com/7gBl0c1.jpg - Not sure if it's due to the format of the code itself, or something else...

@TonySesek: Looks like it's working, but every pixel gets converted to a line of 8 pixels because of the 1-bit vs. 8-bits format difference.

Ohh, my brain skipped over the important part of your postscript, my bad. Alright, that shouldn't be too bad. Maybe I can make another stream to take the stream, haha.


text:
ESP8266/NodeMCU unable to communicate with MFRC522 RFID reader
I am trying to use the 'DumpInfo.ino' example file to dump an rfid tag, the only changes i have made to the example is changing the pin settings.
#define RST_PIN         3          // Configurable, see typical pin layout above
#define SS_PIN          4         // Configurable, see typical pin layout above

i have wired it based on this guide (tried using the pins shown on here as well) when i run the code i get this error from mfrc522.PCD_DumpVersionToSerial();
WARNING: Communication failure, is the MFRC522 properly connected?

Ive also tried printing the version and i get 0xFF which along with 0x00 seems to mean it isnt connected.
The only light that is on during the test is D1 on the RFID reader which you can see in the first wiring pic.
Pictures of wiring here
Edit: I've changed the pins to D3 and D4 but i still get the same error

change the pins to Dx constants, to match your connections
#define RST_PIN         D3
#define SS_PIN          D4

because pin D3 is not io 3 and pin D4 is not io 4. see pins_arduino.h

Thanks, i didnt realise that, unfortunately it still doesnt work.

ok i got it working with this pinlayout:
D1 (GPIO 5)-- RC522 - RST
D2 (GPIO 4)-- RC522 - SDA/SS
D3 (GPIO 0)
D5 (GPIO 14)-- RC522 - SCK
D6 (GPIO 12)-- RC522 - MISO
D7 (GPIO 13)-- RC522 - MOSI
D8 (GPIO 15)
also i used this tutorials code and i posted a serial.println after each piece of code to see where it is/or fails:
http://www.instructables.com/id/MFRC522-RFID-Reader-Interfaced-With-NodeMCU/


text:
trouble running i2c and spi at the same time
I know this question has been asked before but I am having trouble running I2c and SPI at the same time. I am attaching my code below. The problem when I run the code is that the LED's don't blink until the OLED function has been complete, can I fix this with hardware? do I need to fix this in the code? (please note I am using a teensy 3.2)
My end goal is to be able to initially turn on the teensy, choose a pattern on the OLED for what led's turn on, and then just have the leds run.
code :
#include <SPI.h>
SPISettings settingsA(2000000, MSBFIRST, SPI_MODE1);
#include <SFE_MicroOLED.h>  // Include the SFE_MicroOLED library
#include <Wire.h>  // Include Wire if you're using I2C

int time_interval_for_chip = 1;
int blinking_interval = 500;
unsigned long current_time = 0;
#define PIN_RESET 9  // Connect RST to pin 9

#define DC_JUMPER 0

MicroOLED oled(PIN_RESET, DC_JUMPER);    // I2C declaration

void setup() {
  // put your setup code here, to run once:
  pinMode(10, OUTPUT);
  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
  Serial.begin(9600);
  SPI.begin();
  SPI.beginTransaction(settingsA);

  oled.begin();    // Initialize the OLED
  oled.clear(ALL); // Clear the display's internal memory
  oled.display();  // Display what's in the buffer (splashscreen)
  delay(1000);     // Delay 1000 ms
  oled.clear(PAGE); // Clear the buffer.

  randomSeed(analogRead(A0) + analogRead(A1));

  //SPISettings object is used to configure the SPI port for your SPI device. All 3 parameters are combined to a single SPISettings object, which is given to SPI.beginTransaction().
  //sending in bits by MSB first and using SPI_MODE1 which is output edge rising data capture falling
  // can be set to either 4000000 or 2000000
}

void loop() {

  //Blinks output 4 and 8 on and off with teensy without spi.endtrasaction()
  //delaying with delay void function made
  unsigned int result = 0;
  unsigned int result2 = 0;
  byte inbyte = 0;
  byte inbyte2 = 0;

  digitalWrite(10, LOW);
  result2 = SPI.transfer16(0b0100000100000100);
  Serial.print("result= ");
  Serial.println(result2, BIN);
  digitalWrite(10, HIGH);

  //getting the time
  current_time = millis();
  delaying(current_time, 1);

  digitalWrite(10, LOW);
  result = SPI.transfer16(0b0000010000010000);
  Serial.print("result2= ");
  Serial.println(result, BIN);
  digitalWrite(10, HIGH);

  //getting the time
  current_time = millis();
  delaying(current_time, 300);

  digitalWrite(10, LOW);
  result2 = SPI.transfer16(0b0100000000000100);
  Serial.print("result1= ");
  Serial.println(result2, BIN);
  digitalWrite(10, HIGH);

  //getting the time
  current_time = millis();
  delaying(current_time, 1);

  digitalWrite(10, LOW);
  result = SPI.transfer16(0b0000000000010000);
  Serial.print("result2= ");
  Serial.println(result, BIN);
  digitalWrite(10, HIGH);

  //getting the time
  current_time = millis();
  delaying(current_time, 100);
  lineExample();  // Run the pixel example function

}

void lineExample()
{
  int middleX = oled.getLCDWidth() / 2;
  int middleY = oled.getLCDHeight() / 2;
  int xEnd, yEnd;
  int lineWidth = min(middleX, middleY);

  printTitle("Lines!", 1);

  for (int i=0; i<3; i++)
  {
    for (int deg=0; deg<360; deg+=15)
    {
      xEnd = lineWidth * cos(deg * PI / 180.0);
      yEnd = lineWidth * sin(deg * PI / 180.0);

      oled.line(middleX, middleY, middleX + xEnd, middleY + yEnd);
      oled.display();
      delay(10);
    }
    for (int deg=0; deg<360; deg+=15)
    {
      xEnd = lineWidth * cos(deg * PI / 180.0);
      yEnd = lineWidth * sin(deg * PI / 180.0);

      oled.line(middleX, middleY, middleX + xEnd, middleY + yEnd, BLACK, NORM);
      oled.display();
       current_time = millis();
  delaying(current_time, 10);
    }
  }
}

void printTitle(String title, int font)
{
  int middleX = oled.getLCDWidth() / 2;
  int middleY = oled.getLCDHeight() / 2;

  oled.clear(PAGE);
  oled.setFontType(font);
  // Try to set the cursor in the middle of the screen
  oled.setCursor(middleX - (oled.getFontWidth() * (title.length() / 2)),
                 middleY - (oled.getFontWidth() / 2));
  // Print the title:
  oled.print(title);
  oled.display();

  //getting the time
  current_time = millis();
  delaying(current_time, 1500);
  oled.clear(PAGE);
}

void delaying(unsigned long current_time, int period) {

  while (millis() < current_time + period) {
    //wait approx. [period] ms
  }
}

Can you replace the use of millis with normal delay and test again? The usage of millis is wrong, your sketch could delay by 50 days sometimes. You say the the blinking on the leds is delayed. How much slower is it? The i2c bus is slow, and all those delays and millis make the sketch even slower. Why do you have so many delays and complain about the delays? I count 1.4 seconds delay in the function lineExample alone.

can you explain how I am using millis() wrong? that would be constructive

See the blink without delay example: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay As soon as you compare a value to the return value of millis(), that's wrong. You can use the blink without delay twice to do multiple things at once. Update the SPI at a fast rate and the oled at a slow rate.

ok I see what you mean for 1 but I don't see how this is wrong. I followed this link https://www.norwegiancreations.com/2017/09/arduino-tutorial-using-millis-instead-of-delay/

what my code is doing is it won't run the OLED and the led's at the same time, the OLED function needs to be complete before the leds run but I want to run the two at the same time.

I quickly removed the problem when the parameter is just 1 from my comment. I was not thinking that through. The blink-without-delay shows how to use millis. Do not follow what is written in that norwegian link, it is totally wrong. The blink-without-delay shows how to use millis. Can you try to use the blink-without-delay and have two leds blinking at different rates, completely independent of each other?

I will change it, but I don't see how what that person did was wrong, it makes sense.

No, not at all, it is really a bad example. That code is also here: https://dzone.com/articles/tackling-the-new-world-of-iot-management and there are comments there saying it is bad and harmful. You had bad luck finding that. The function millis() will rollover after 50 days, it is simple to avoid problems with the rollover by using it in the way the blink-without-delay shows.

I genuinely think if I change it to the other it won't make a difference. I use to use the while loop at Johns Hopkins University in their labs, so that doesn't make sense to me that this will (make or break it)

Use the blink-without-delay, do not compare the millis value directly to an other value. Everyone who knows about millis can tell you that.

An interupt could come in and be handled between when you record millis and when you wait for it. It might not be accurate.    However if the function is taking a long time to come back you cant do anything else since its blocking.  Unless you rewrite the function to be shorter, or use interrupts to drive your leds

can I drive the led's with the interrupt? I thought an interrupt was suppose to be for a quit time.  Just to clarify my exact goals, I want to do some things initially on the OLED to control how the LED's behave, like pick a pattern on my OLED and then the LED's do that. maybe there is a better way to do what I want?

I think you don't need interrupts for this. You just have to write your OLED and LED code non-blocking. The point of the BlinkWithoutDelay example is to not do busy waiting (what you are doing with your delaying function (doing a delay with your own function using millis() doesn't make sense eiter)), but to only do a short check in every loop cycle, if it is time to do something, and else going further in the code.


text:
Does millis() work inside a function?
So I know that millis() doesn't work how it's suppose to if you use it in an interrupt but lets say we have a code that looks like below, will millis() work properly or how it behaves in an interrupt? Do I need to use the delay() instead of millis() when I'm outside of void loop() ?
To clarify, I understand how millis() behaves in an interrupt and why delay() doesn't work in an interrupt.
const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;

void setup() {
 pinMode(ledPin, OUTPUT);
}
void loop(){
blink();
}
void blink(){
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

That is good code. You can use many more of those functions with different leds and different intervals, but each should have its own previousMillis variable. The interval can be an int or a long, but you can also make it an unsigned long, then the compiler does not have to convert it to unsigned long. Using millis in an interrupt can be used to remember the time, for example as a timestamp to decode a certain timing protocol. But don't use delay in a interrupt and don't use millis to create a delay in a interrupt.

So the millis() will work fine in the void blink() ? it's not like an interrupt where the millis() is the last millis() used in the regular void loop() ?

It will work fine. I don't understand your second question. The way you use millis in the sketch is checking if enough time has passed since the previousMillis, that is how to use millis. There is no waiting, no delay, the led is changed when it is time to do so.

I think I'm confused with the term interrupt vs function, like void blink() isn't considered an interrupt is it? is an interrupt only when I actually declare it?

Your blink function is a normal function. Everything that is called from the loop function is a normal function. An interrupt function is for example with the function attachInterrupt https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Just as a terminology item: loop is a  function it is not a void. void is the return type. To say something like "the void blink" is confusing. You mean: "the function (named) blink".

Just to reaffirm. The way you  are using millis is absolutely fine. Excellent example of not using delay to blink an led.

Millis is driven by an interrupt. The reason it doesn't "work" from inside an interrupt is that you can't have two interrupts running at the same time. So when your interrupt is running the interrupt that makes millis count can't run.
Millis does work in an interrupt as long as all you want is to record a single point in time. If you do anything that relies on millis changing within the lifetime of the interrupt it will break. That is why delay is bad in interrupts.
So from that you can see that it's only when in an interrupt that things can go awry. Everywhere else, as long as interrupts are enabled, both millis and delay work fine.
After all, loop is just a function called by main, and main is just a function called by _startup... Etc...

Although that is a nice explanation of an interrupt my question isn't about what an interrupt does. To clarify is void blink() behaving as an interrupt or does something only behave as an interrupt when you declare it?

Something only behaves like an interrupt when it is called by an interrupt. Blink is just a function. Like loop. Like millis. Like delay. Like setup. They are all just functions. Only interrupts are interrupts.

so it's only considered a interrupt only when i use attachInterrupt() right? so then in the void blink() function about millis() works fine, it doesn't behave like the way it would in an interrupt correct?

An interrupt is a context not a function. A separate thread of execution if you like.

Only if you called blink from an interrupt would it behave like an interrupt.

ok I think my confusion was Jot said that my delay function written on this thread https://arduino.stackexchange.com/questions/51049/trouble-running-i2c-and-spi-at-the-same-time?noredirect=1#comment104925_51049 was wrong and I just didn't understand how it's wrong, especially because it worked correctly.

It's not your usage of millis that is wrong but your method of calculation. You run into problems when the millis count rolls over. Your calculation, with integer wraparound, goes awry.


text:
Ribbon sensor resistance slowly drops when released
I recently bought a ribbon sensor (the one displayed here), with the intention to use it as a touch-enabled music instrument.
I used it correctly (so it seems), but I have two issues :

When not pressed, the sensor seems to give random data, as if nothing was plugged to the pin.
When unpressed, the resistance slowly decreases (and so is my sound pitch). Is that a normal behaviour ?

I don't know how to solve both issues. Has anyone an idea ?
A tinker of my test (Currently corrected thanks to @VE7JRO) can be seen here with my code here (The ribbon is replaced by a potentiometer but the principle remains the same). The code is also Available on GitHub.

The instructions on Adafruit say "When no pressure is applied, the middle pin floats, so be sure to use some sort of weak pull-up, such as 100K ohm.". Have you connected it to your Arduino using all of the "To use" directions?

I didn't quite understood this instruction (English is not my first language), so it should work with a 100kohm resistor between the middle pin and the reading pin ?

The Adafruit website says this:
There is a nominal 10K resistance across the two outer leads. The middle pin resistance with respect to either of the outer pins changes depending on where on the strip one presses. When no pressure is applied, the middle pin floats, so be sure to use some sort of weak pullup, such as 100K ohm.
To use Connect one side pin to ground via a 10K resistor in series. Connect the other side pin to your Vcc power line (3V, 5V etc) via a different 10K resistor in series. Then read the analog voltage on the center pin. It will range from 1/3 Vcc to 2/3 Vcc . Do not connect to Ground and Power directly!
Here is a diagram of how I would connect it to a 5V Arduino Uno.

Yes, it works, thanks ! I didn't understood where to put this resistor first.