text:
Can I do something like this to simplify the code for arduino?
Can I simplify the code in arduino where it doesn't promote any error.
Example:
Int led =13;
Blink = digitalWrite(led, HiGH);
             delay(1000);
             digitalWrite(led, LOW);
             delay(1000);

void setup(){
pinMode(led, OUTPUT);
}

void loop(){
Blink
}

Please paste the code directly instead of posting an image. Noone will waste their time to type your code.

The previous version was better, just select the code after pasting, and press ctrl-k to indent it so you get the proper 'code style layout'.

Note that, as long as loop() does nothing but blink(), there is no simplification in defining blink() as a separate function.

There are indeed some errors.
First, you cannot assign a function body to a variable.
So you have to rewrite the Blink function:
void blink()
{
    digitalWrite(led, HIGH);
    delay(1000);
    digitalWrite(led, LOW);
    delay(1000);
}

Also for calling a function, even without parameters, you should use ( and ):
void loop()
{
    blink();
}

Also you need to use the correct capitals or not:
int led = 13;

You can make it constant since it does not change:
static const int led = 13;

So all together you get:
static const int led = 13;

void setup()
{
    pinMode(led, OUTPUT);
}

void loop()
{
    blink();
}

void blink()
{
    digitalWrite(led, HIGH);
    delay(1000);
    digitalWrite(led, LOW);
    delay(1000);
}

I suggest you read a book about C or C++ to get used to the syntax.
Also, note that int is written as int, not Int. Case matters.

Thank you so so much. It was a good learning experience for me.

You're welcome, if it helping you, please upvote and if it solves your problem, accept the answer (clicking on the button next tot he answer). Have fun with the Arduino.

Your code
Blink = digitalWrite(led, HiGH);
         delay(1000);
         digitalWrite(led, LOW);
         delay(1000);

Is attempting to define a function Blink that you can call later. You don't do that with an assignment (=)
You want to define a function. I'd suggest naming it blink(), not Blink. (all lower case.
Functions have parentheses after the name, which is where you put parameters if your function has any parameters. If not you still need the parentheses. The basic syntax of a function definition is:
return_type function_name(param_type param_name)

If your function doesn't return a value, use the type void which means "no type."
So for a function foo that doesn't take any parameters and doesn't return any value, you'd use:
void foo () {
   //Code for function foo()
}

Michael's excellent answer (voted!) shows you what changes you need to make to your code to make it work. The above explains in a little more detail WHY you need to make those changes.

Of course C++ has nice things.
For fun ad learn a working Arduino sketch based on the code from the Question:
int led =13;

auto Blink = []() { digitalWrite(led, HIGH);
             delay(1000);
             digitalWrite(led, LOW);
             delay(1000);
};

void setup(){
pinMode(led, OUTPUT);
}

void loop(){
Blink();
}

Note: use normal functions in your sketches and save lambdas for special occasions.

Lambdas are way, WAAAAY beyond the OPs current abilities. You do them a disservice by even mentioning them at this stage in their learning.

And this should be byte, vs int, to save on memory:
static const int led = 13;

HiGH should be HIGH, all caps.

For a const it makes no difference to the memory use if you use byte, int, long or even long long.


text:
Arduino I2C Wire.onReceive hangs after a few loops
I have an Arduino Leonardo (master) and a Polulu A-star 328 PB(slave). I intend to use the slave to actuate some servos. I've modified the code from https://www.arduino.cc/en/Tutorial/MasterWriter to also blink the builtin led of the slave and it hangs after a few loops. Without the blink, it works fine. With blink, it hangs after a few loops.
Master:

#include <Wire.h>

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop() {
  Wire.beginTransmission(8); // transmit to device #8
  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte
  Wire.endTransmission();    // stop transmitting
  x++;
  delay(2000);
}

Slave:
#include <Wire.h>

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Wire.begin(8);                // join i2c bus with address #8
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600);           // start serial for output
}

void loop() {
delay(100);
}

void receiveEvent(int howMany) {
while (1 < Wire.available()) {
  char c = Wire.read();
  Serial.print(c);
}
int x = Wire.read();
Serial.println(x);
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
}

Serial monitor:
x is 16
x is 17
x is 18
x

Any idea what's causing it and what can I do to further debug it or fix it?
Thank you!

onRecieve is an interrupt routine. You can't use things like delay(), millis() or Serial.print inside interrupt routines.

The onReceive callback get's called from an ISR (interrupt service routine). During the execution of this ISR, the MCU cannot react to other interrupts, since interrupts get automatically turned off at the start of an ISR.
Some functions like delay() and millis() rely on interrupts to work correctly, since the timekeeping in the Arduino framework is done via a timer interrupt. This means, that you cannot use delay() inside of an ISR. It will block forever, waiting for the internal time increment from the pointer, which will never come.
You can also get a problem with big Serial.print()s. These Serial functions fill the libraries internal buffer, and  the library will use interrupts to actually transmitt the data. If interrupts are turned off (like in an ISR), the buffer get's filled, until it is full. If you then again call Serial.print() or one of it's siblings, the library will block the execution, until there is enough space in the buffer, which will never happen. (You don't have this problem here, since you are only printing a few characters, but you should know this)
Generally ISR's should be as short as possible to prevent, that the Arduino misses an interrupt (which may mean data loss). Instead doing the blink in the ISR, you should simply set a flag variable, which you check in your loop() function and execute the blink correspondingly. That looks about like this:
volatile byte flag=0;

void loop(){
    if(flag){
        // Execute blink here
    }
}

void receiveEvent(int howMany) {
    // Do receiving here
    flag=1; //Set flag to a non-zero value to activate the corresponding code in loop()
}

After a bit of tinkering, I noticed that removing the delay() call in the slave fixed it and there were no more hangs. Also, when using the Servo library to move a servo instead of blinking the led, Servo.write() hangs while Servo.writeMicroseconds() doesn't. I'd mark the answer that has an explanation for this strange behavior.

upvote for continuing your investigation ... one thing that you could try to find out is will the code work with minimal delay(1) call?

source: Stack Exchange

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

sort: votes


text:
Global JsonObject (ArduinoJson)
I know a global JsonObject shouldn't be used, but I have my reasons.
I have a JsonObject* functions and I want him to save the content of a file.
With

functions=new JsonObject(jsonBuffer.as<JsonObject>());

I can access the JsonObject, but not when I leave the method. Can someone help me to understand why?
(Don't give me a solution like: copy into a struct, I need a JsonObject ready to be read in all my code.
Full code:
JsonObject* functions;

void loadFunctions() {
  File file = SPIFFS.open("/functions.json", "r");
  if (!file) {
    Serial.println("Failed to open the file");
  }else{
    size_t size = file.size();
    if (size > 512) {
      Serial.println("File size is too large");
    }else{
      std::unique_ptr<char[]> buf(new char[size]);
      file.readBytes(buf.get(), size);
      DynamicJsonDocument jsonBuffer(256);
      DeserializationError error = deserializeJson(jsonBuffer, buf.get());
      if (error) {
        Serial.println("Failed to parse file ");
      } else {
        functions=new JsonObject(jsonBuffer.as<JsonObject>());
        Serial.println((*functions)["test"].as<String>()); //this doesn't work in another method
      }
    }
  }
}

did you call loadFunctions anywhere?

Yes and the last Serial.println works, but not if I use it in another method (after this method)

jsonBuffer is local to the function. When you leave the function the contents of jsonBuffer are lost.
functions just points to the internals of jsonBuffer to get its data (to save memory).
You can either:

Make the jsonBuffer global so it sticks around all the time, or
Have a secondary DynamicJsonDocument or StaticJsonDocument that is global to which you copy your objects once read from jsonBuffer.

Thank you, solved by using the second choice.

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


text:
Help with function template syntax
I am trying to understand the following code snippet from the Espressif OTABasic example for the ESP32 wireless/BT module (see this repository for the full code).
 ArduinoOTA
.onStart([]() {
  String type;
  if (ArduinoOTA.getCommand() == U_FLASH)
    type = "sketch";
  else // U_SPIFFS
    type = "filesystem";

  // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
  Serial.println("Start updating " + type);
})
.onEnd([]() {
  Serial.println("\nEnd");
})
.onProgress([](unsigned int progress, unsigned int total) {
  Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
})
.onError([](ota_error_t error) {
  Serial.printf("Error[%u]: ", error);
  if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
  else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
  else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
  else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
  else if (error == OTA_END_ERROR) Serial.println("End Failed");
});

The initial 'ArduinoOTA' looks kinda like an implied 'with ArduinoOTA' statement, but I can't find anything like that in the reference documents.  I know it has something to do with the way the function templates in 'ArduinoOTA.h', but it's beyond me to untangle the syntax.
May I buy a clue, please?
TIA,
Frank
Thanks to all for the clues; I'm an old-time c/c++ programmer, but must have slept through the 'lambda function' class ;-).
To help my somewhat calcified brain, is it functionally equivalent (if more clunky) to write the above snippet as shown below with the handler functions 'unchained'?
    ArduinoOTA.onStart
([]() //lambda function
    {
        String type;
        if (ArduinoOTA.getCommand() == U_FLASH)
            type = "sketch";
        else // U_SPIFFS
            type = "filesystem";

        // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
        Serial.println("Start updating " + type);
    }
);

ArduinoOTA.onEnd
([]() //lambda function
    {
        Serial.println("\nEnd");
    }
);

ArduinoOTA.onProgress
([](unsigned int progress, unsigned int total) //lambda func with arguments
    {
        Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    }
);

ArduinoOTA.onError
([](ota_error_t error) //lambda func with arguments
    {
        Serial.printf("Error[%u]: ", error);
        if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
        else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
        else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
        else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
        else if (error == OTA_END_ERROR) Serial.println("End Failed");
    }
);

TIA,
Frank

This is called (by me, anyway) "method chaining".
It's nothing special, really.  ArduinoOTA is just an instance of the class ArduinoOTAClass.
Each method of that class does what it needs to do, then returns a reference to the object that the method is within.  Which means that you can then call a method on that returned reference ... and so on.
All the rest of it is "lambda" functions - that is, functions that are embedded within the parameters of the functions being called.
The basic result is something like:
A.foo().bar().baz();

Where A.foo() returns A. A.bar() returns A. A.baz() returns A.
You can do the same with:
A.foo();
A.bar();
A.baz();

that snipet looks like a multiple event handler declaration or multiple event handler overloading

@jsotola It's just passing anonymous ("lambda") functions as parameters to simple methods which then store those functions as as pointers and return the object again. Nothing magic about it, and no overloading or anything like that.

i learn something new every day ... thank you


text:
Why doesn't data return when I use Sim808 http request
Why is it that when i use this code for http request on DFRobot_sim808 , I get 'fetch over' message, that means that no data is being returned?
char strings:
char http_cmd[] = " HTTP/1.0\r\n"
                        "Host: 5ac80719.ngrok.io\r\n"
                        "\r\n";
char first[] = "GET /index.php?lat=";

char requestion[100];

functions to join them:

void setup() {
  float lat = 32.685362, lon = 48.411512;
  char char_coor[10];

  mySerial.begin(9600);
  Serial.begin(9600);

// Set Http Cmd
  strcpy(requestion,first);
// For Convert latitude float to char
  dtostrf(lat, 4, 6, char_coor);
  strcat(requestion,char_coor);
// For Convert longitude float to char
  dtostrf(lon, 4, 6, char_coor);
  strcat(requestion,"&long=");
  strcat(requestion,char_coor);
  strcat(requestion,http_cmd);

.
.
.

and fetching:
sim808.send(requestion, strlen(requestion)-1);
  while (true) {
      int ret = sim808.recv(buffer, sizeof(buffer)-1);
      if (ret <= 0){
          Serial.println("fetch over...");
          break;
      }

/*
The program stops at above
*/

      buffer[ret] = '\0';
      Serial.print("Recv: ");
      Serial.print(ret);
      Serial.print(" bytes: ");
      Serial.println(buffer);
      break;
  }

thanks

OK i mean why no data returned??

perhaps the device is not connected to the internet ... it is your job to do basic troubleshooting and update your question with a description of what you already tried

One problem I can see is the while loop has a break statement in it that "exits" the while loop before printing the data. Removing that break and printing the data out where the break "was" may help. Here's an example of what I'm trying to say:
void setup(){
  Serial.begin(9600);
}

void loop(){

  while(true){
    int ret = 0;
    if(ret <= 0){
      Serial.println("fetch over...");
      // Print out the received data here...
      Serial.print("Recv: ");
      Serial.print(ret);
      break;
    }
  }

}


text:
LED strip brightness decreases when using multiple strips
Newbie question here.
I have bought a 5V, 40A power supply to externally power up some LED strips (WS2812B). The Arduino Nano is powered by a standard USB wall charger (5V).
So far I have tested with 4 LED strips (each of about 25 LED's). Each of the strips is connected to an individual data pin on the Arduino in addition to the power supply (5V and ground).
So, to the problem. For each LED strip that gets powered it seems that the brightness of the LED's decreases. Using for example "white color", all the LED's shows a "yellow"-ish color when all the LED strips are powered. If only one or two is powered it looks fine.
The Arduino by the way shares the same ground as the power supply.
What could the cause to this issue be? The power supple should be more than sufficient for the task. Is it the data pins that can't handle it?
Thanks for any help!
EDIT:
I more detail, each LED strip has 3 pins (1 for 5V, 1 for data input, and 1 for ground). Each for the LED strips 5V pin are connected to the + rail on a breadboard where the power supplies + is also connected. The same goes for the ground pin of the LED strips (they are connected to a ground rail on the same breadboard where also the ground of the power supply is connected).
The data pin on the LED strips are connected to 4 (when all are connected) different data pins on the Arduino Nano (A1,A2,A3 and A4).
The ground pin on the Arduino Nano is connected to the same breadboard ground rail as the rest. When I didn't do this the LED's had weird behaviour.
The wires going from the LED strips into the breadboard are standard 24 AWG stranded wires (each of about 50 - 80 cm in length).
Power supply used is "AC 110V-220V TO DC 5V 40A" from ebay.
https://www.ebay.com/itm/AC-110V-220V-TO-DC-5V-12V-24V-Switch-Power-Supply-Driver-Adapter-LED-Strip-Light/152134115704
LED strips that are used "5M WS2812B 5050 RGB, 150LEDS ip65 Waterproof"
https://www.ebay.com/itm/5M-WS2812B-Strip-LED-Lights-5050-RGB-30-60-LED-M-IC-Individual-Addressable-DC5V/113117301639?

have you done basic investigation of voltage levels?

@jsotola: I have checked the power supply and it provided 5.00 - 5.02V when I checked.
Measured in the circuit itself now, and it actually seems that it drops from 5V to everything between 4.44 - 2.3 based on how many strips that are activated.
I was expecting the power supply to hold based on the specification.

How is everything connected? And do you use cables/wires that are thick enough to conduct the needed current?

As chrisl says, you need to explain your setup in more detail. Are you connecting the LED strips' power through the Arduino? If so, don't do that. You should use a separate, heavy-gauge wire for the 5V lead for your LED strips (and another heavy gauge wire for the ground.) What's the max current draw from one of your LED strips? What's the total power from the full number of strips you are planning to use?

connect multiple wires in parallel to one of the strips .... is it brighter than the others?

I found a 144 WS2812B LED strip on Amazon that draws 20A just for 1 strip. Your 40A power supply would only be able to power 2 of those without getting overloaded.

@chrisl: Thank you for your reply. The question has been updated. Right when I updated the answer I started thinking that the power and ground of the power supply is in fact using the same wire type as everything else. Could that be the problem (24 AWG stranded wire)?

I don't think a breadboard can handle that much current. Also, try measuring the voltage at the power supply. If it can't handle that much current the voltage will drop a bit, which is easy to measure.

Still a circuit schema would come in handy.

When the voltage drops at the circuit, but not on the power supply, the voltage is lost on the way between them (for example in undersized wires and connections, like the breadboard)

As @Gerben said, definitely do not use breadboard for distributing power.

40 amps is a LOT of current.
24 AWG wire can't handle anywhere near 20A of current, nevermind 40A. (After a little googling, it looks like 24 AWG wire is limited to about 3.5A.)
Think about it. In the US, 15 amp branch circuits require 14 AWG wire. 20 amp circuits require 12 AWG wire. It looks like 40 amps requires 8 AWG, from the googling I did. (Voltage doesn't really matter when considering current carrying capacity.) So if you want to drive 40 amps, you need 8-gauge wire on both the +5 leg and the ground leg to your LED strip.
As I said in my comment, I found some 144 WS2812B LED strips on Amazon that draw 20A just for one strip. You say your strips have 150 WS2812B LEDs on them. Assuming it's 150 vs 144 of the same LEDS, you're going to need almost 21 amps per strip, so 2 strips will slightly exceed the 40A capacity of your power supply, and VASTLY exceed the current handling ability of your wiring. As a general rule you should have a power supply that offers a little MORE current that your max needs, never less.(When a power supply reaches its current limits its voltage may start to droop, or it may be slower to adjust to rapid changes in load.)
In addition, You're gonna need BIG, THICK 5V and ground wires to feed your LED strips, and you should wire the LED stips in parallel. (I suggest 8 AWG wires for 40A. Those are HUGE, but that's what you need for that much current.) You should not connect either the +5V supply or the ground wires through a breadboard.

Thanks for your answer. Removed the breadboarded and replaced it with wago instead. In addition switched the 24 AWG to some thicker wires from the power supply to the wago and LED strips. Now it seems to work perfect!

What is "wago"?

A type of wire connector:
https://www.ebay.com/itm/3-50pcs-Spring-Lever-Push-Fit-Reusable-Cable-2-3-5-Way-Wire-Connector-For-Wago/172570569841


text:
How do I convert this program to assembly from c++
I am trying to implement a program in assembly code for an Arduino UNO. A potentiometer is used on an ADC pin for variable time (t). LED1 flashes for t seconds, then stays on for t seconds, then goes off and another LED(LED2) goes on for t seconds and then the cycle repeats (t is variable time that comes from potentiometer). I have a working program in c++ but I want to convert it to assembly. I have just started learning assembly and am not very good at it.
The part I am really stuck on is the analogRead() function. I do not know how to implement this on assembly. Anyone know how to do this?
#define led 3
#define led2 2

void setup()

{

Serial.begin(9600);

//initializing pins
pinMode(led,OUTPUT);

pinMode(led2,OUTPUT);

}
void loop()

{

// read the input on analog pin 0:
int sensorValue = analogRead(A0);

// Convert the analog reading(which goes from 0 - 1023) to a voltage(0-5V):
int voltage = sensorValue * (5.0 / 1023.0);

// print out the value you read:
Serial.println(voltage);

for(int i=0;i<2*voltage;i++)

{

digitalWrite(led,LOW);

delay(100);

digitalWrite(led,HIGH);

delay(100);

}

//red stays on
digitalWrite(led,HIGH);

delay(voltage*500);

digitalWrite(led,LOW);

//green stays on
digitalWrite(led2,HIGH);

delay(voltage*500);

digitalWrite(led2,LOW);

}

are you able to run simple blink code, that does not use analog input, in assembly?

It sounds like you want to forsake all the work people have put into the Arduino environment and do what is called bare metal programming.  If that is the case, say so and I will respond with a new answer to your question.  Be aware, this will immerse you into firmware programming where you will need to do everything the Arduino environment is doing for you.  This can get so technical that some companies hire special embedded programmers who specialize in Board Support Packages or BSPs.

@jsotola Yes I am able to do that

@st2000 Yes please

Download a copy of the Atmega328P datasheet from here  http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf  There are examples in C and in Assembly for doing many things.  See Section 24.  I think you can also use AVRDUDE commands to create/save assembly code as part of the compile process, write some simple code and see how the compiler does it.

Well, @CrossRoads basically told you what to do.  You will need to read and understand the parts of the datasheet which describes the peripheral you are interested in using as well as the core of the processor.  You don't need to bother with the electrical or physical packaging details.  Yes, I know the PDF is 600 pages.  (This is what the Arduino is abstracting you from.)  Welcome to firmware and bare metal programming!

The obvious solution for converting any program to assembly is... to
compile it! You can disassemble the resulting binary with a command
like:
avr-objdump -S -C the_program.elf > the_program.lss

This will output a listing of the program, with the original source
interspersed with an hex dump of the binary and the corresponding
disassembly.

The part I am really stuck on is the analogRead() function.

Here it goes:
000003a6 <analogRead>:
 3a6:   8e 30           cpi r24, 0x0E   ; 14
 3a8:   08 f0           brcs    .+2         ; 0x3ac <analogRead+0x6>
 3aa:   8e 50           subi    r24, 0x0E   ; 14
 3ac:   87 70           andi    r24, 0x07   ; 7
 3ae:   20 91 00 01     lds r18, 0x0100 ; 0x800100 <__data_start>
 3b2:   90 e4           ldi r25, 0x40   ; 64
 3b4:   29 9f           mul r18, r25
 3b6:   90 01           movw    r18, r0
 3b8:   11 24           eor r1, r1
 3ba:   82 2b           or  r24, r18
 3bc:   80 93 7c 00     sts 0x007C, r24 ; 0x80007c <__TEXT_REGION_LENGTH__+0x7e007c>
 3c0:   80 91 7a 00     lds r24, 0x007A ; 0x80007a <__TEXT_REGION_LENGTH__+0x7e007a>
 3c4:   80 64           ori r24, 0x40   ; 64
 3c6:   80 93 7a 00     sts 0x007A, r24 ; 0x80007a <__TEXT_REGION_LENGTH__+0x7e007a>
 3ca:   80 91 7a 00     lds r24, 0x007A ; 0x80007a <__TEXT_REGION_LENGTH__+0x7e007a>
 3ce:   86 fd           sbrc    r24, 6
 3d0:   fc cf           rjmp    .-8         ; 0x3ca <analogRead+0x24>
 3d2:   80 91 78 00     lds r24, 0x0078 ; 0x800078 <__TEXT_REGION_LENGTH__+0x7e0078>
 3d6:   20 91 79 00     lds r18, 0x0079 ; 0x800079 <__TEXT_REGION_LENGTH__+0x7e0079>
 3da:   90 e0           ldi r25, 0x00   ; 0
 3dc:   92 2b           or  r25, r18
 3de:   08 95           ret

Now, in order to more easily make sense of it, you need to know what all
those magic numbers mean. The command
avr-nm -nC the_program.elf

will dump the symbols associated with every RAM and flash address. In
order to tell those apart, 0x800000 is added to every RAM address. This
will tell you that, in this specific program, the RAM address 0x0100
is actually the address of the variable analog_reference from the
Arduino core library. Thus, you can replace the line
 3ae:   20 91 00 01     lds r18, 0x0100 ; 0x800100 <__data_start>

by
    lds  r18, analog_reference

Then you can use the datasheet to get the names of the memory-mapped IO
registers, and the names of the bits from those registers. I have done
all this for you, so here is the cleaned-up disassembly of
analogRead():
analogRead:
    cpi  r24, 14
    brcs 1f
    subi r24, 14
1:  andi r24, 0x07
    lds  r18, analog_reference
    ldi  r25, 1<<REFS0
    mul  r18, r25
    movw r18, r0
    clr  r1
    or   r24, r18
    sts  _SFR_MEM_ADDR(ADMUX), r24
    lds  r24, _SFR_MEM_ADDR(ADCSRA)
    ori  r24, 1<<ADSC
    sts  _SFR_MEM_ADDR(ADCSRA), r24
2:  lds  r24, _SFR_MEM_ADDR(ADCSRA)
    sbrc r24, ADSC
    rjmp 2b
    lds  r24, _SFR_MEM_ADDR(ADCL)
    lds  r18, _SFR_MEM_ADDR(ADCH)
    ldi  r25, 0
    or   r25, r18
    ret

If you compare this with the source code of analogRead(), it
should now make perfect sense.

I am trying to implement a program in assembly

Now, if you want to write the assembly yourself, that's a whole
different story. If you allow yourself the use of the Arduino core, then
you can simply
    ldi r24, 14  ; pin A0 is pin 14
    call analogRead

If you don't want to rely on external libraries, and really write
everything yourself, it's going to be a lot harder. I suggest you do
this as a two-step process:
Step 1: Learn how to program the ATmega328P in plain C, at the
register level, using no library other than the avr-libc. You can start
by reading this short tutorial about direct port access.
But then you should quickly move on to studying the
datasheet and the manual of the avr-libc. Yes,
that's a lot to digest. I hope you didn't expect this to be quick and
easy. But note that, on those documents, you can skip all the chapters
related to functions you are not going to use.

I am really stuck on is the analogRead() function.

In the specific case of your example program, you don't need a version
of analogRead() that can read any pin with any reference. You can
instead write a simpler version that just reads the currently selected
pin using the currently selected reference:
int simple_analog_read(void)
{
    ADCSRA |= 1<<ADSC;                    // start the converion
    while (ADCSRA & (1<<ADSC)) continue;  // wait till it's done
    return ADC;                           // return the reading
}

Of course, this assumes you have appropriately initialized the ADC.

int voltage = sensorValue * (5.0 / 1023.0);

You really, really don't want to implement something like this in
assembly. The AVR hardware supports neither floating point nor
divisions. All this is handled by the compiler through supporting
libraries, and they are not simple. What you really want is something
like
int voltage = (sensorValue * 5) >> 10;

which is incidentally more correct, as the scaling factor is 5/1024, not
5/1023 (see the datasheet).
Step 2: Learn assembly, and rewrite your low-level C code in
assembly. If your C code is low-level enough this should not be too
hard. As a learning aid, you can ask the compiler to do it for you and
then try to make sense of what it did. If you just try to compile the
simple_analog_read() function I wrote above you will see the
translation to assembly is almost trivial.


text:
qMenuSystem using DigoleSerial library doesn’t work on my I2C Monochrome OLED
Just like the title says I’m trying to make qMenuSystem to work with my oled display.
Here is what I know so far about my display :
- It's a Monochrome OLED 128x64 (Blue) Display
- It's connecting using I2C using the 0x3C address allocated
- It's working well with Adafruit SSD1306 and Adafruit GFX Libraries
- It's looking like this : https://cdn3.volusion.com/btfzd.umflq/v/vspfiles/photos/AD304-2T.jpg?1526038845

The library DigoleSerial has the following files :
//DigoleSerial.cpp

//Digole Digital Solutions: www.digole.com
#include "DigoleSerial.h"
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "Arduino.h"

/*
// Communication set up command
 * "SB":Baud (ascII bytes end with 0x00/0x0A/0x0D) -- set UART Baud Rate
 * "SI2CA":Address(1 byte <127) -- Set I2C address, default address is:0x27
 * "DC":1/0(1byte) -- set config display on/off, if set to 1, displayer will display current commucation setting when power on
// Text Function command
 * "CL": -- Clear screen--OK
 * "CS":1/0 (1 byte)-- Cursor on/off
 * "TP":x(1 byte) y(1 byte) -- set text position
 * "TT":string(bytes) end with 0x00/0x0A/0x0D -- display string under regular mode
// Graphic function command
 * "GP":x(1byte) y(1byte) -- set current graphic position
 * "DM":"C/!/~/&/|/^"(ASCII 1byte) -- set drawing mode--C="Copy",! and ~ = "Not", & = "And", | = "Or", ^ = "Xor"
 * "SC":1/0 (1byte) -- set draw color--only 1 and 0
 * "LN":x0(1byte) y0(1byte) x1(1byte) y2(1byte)--draw line from x0,y0 to x1,y1,set new pot to x1,y1
 * "LT":x(1byte) y(1byte) -- draw line from current pos to x,y
 * "CC":x(1byte) y(1byte) ratio(byte) -- draw circle at x,y with ratio
 * "DP":x(1byte) y(1byte) Color(1byte) -- draw a pixel--OK
 * "DR":x0(1byte) y0(1byte) x1(1byte) y2(1byte)--draw rectangle, top-left:x0,y0; right-bottom:x1,y1
 * "FR":x0(1byte) y0(1byte) x1(1byte) y2(1byte)--draw filled rectangle, top-left:x0,y0; right-bottom:x1,y1
 */

// that resetting the Arduino doesn't reset the LCD, so we
// can't assume that its in that state when a sketch starts (and the
// LiquidCrystal constructor is called).

//UART function

void DigoleSerialDisp::preprint(void) {
    //write((uint8_t)0);
    Print::print("TT");
}

/*----------Functions for Graphic LCD/OLED adapters only---------*/
void DigoleSerialDisp::drawBitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h, const uint8_t *bitmap) {
    uint8_t i = 0;
    if ((w & 7) != 0)
        i = 1;
    Print::print("DIM");
    writePosition(x); //x;
    writePosition(y);
    writePosition(w);
    writePosition(h);
    for (int j = 0; j < h * ((w >> 3) + i); j++) {
        write(pgm_read_byte_near(bitmap + j));
//        delay(5);
    }
}

void DigoleSerialDisp::setRot90(void) {
    Print::print("SD1");
}

void DigoleSerialDisp::setRot180(void) {
    Print::print("SD2");
}

void DigoleSerialDisp::setRot270(void) {
    Print::print("SD3");
}

void DigoleSerialDisp::undoRotation(void) {
    Print::print("SD0");
}

void DigoleSerialDisp::setRotation(uint8_t d) {
    Print::print("SD");
    write(d);
}

void DigoleSerialDisp::setContrast(uint8_t c) {
    Print::print("CT");
    write(c);
}

void DigoleSerialDisp::drawBox(unsigned int x, unsigned int y, unsigned int w, unsigned int h) {
    Print::print("FR");
    writePosition(x);
    writePosition(y);
    writePosition(x + w);
    writePosition(y + h);
}

void DigoleSerialDisp::drawCircle(unsigned int x, unsigned int y, unsigned int r, uint8_t f) {
    Print::print("CC");
    writePosition(x);
    writePosition(y);
    writePosition(r);
    write(f);
}

void DigoleSerialDisp::drawDisc(unsigned int x, unsigned int y, unsigned int r) {
    drawCircle(x, y, r, 1);
}

void DigoleSerialDisp::drawFrame(unsigned int x, unsigned int y, unsigned int w, unsigned int h) {
    Print::print("DR");
    writePosition(x);
    writePosition(y);
    writePosition(x + w);
    writePosition(y + h);
}

void DigoleSerialDisp::drawPixel(unsigned int x, unsigned int y, uint8_t color) {
    Print::print("DP");
    writePosition(x);
    writePosition(y);
    write(color);
}

void DigoleSerialDisp::drawLine(unsigned int x, unsigned int y, unsigned int x1, unsigned int y1) {
    Print::print("LN");
    writePosition(x);
    writePosition(y);
    writePosition(x1);
    writePosition(y1);
}

void DigoleSerialDisp::drawLineTo(unsigned int x, unsigned int y) {
    Print::print("LT");
    writePosition(x);
    writePosition(y);
}

void DigoleSerialDisp::drawHLine(unsigned int x, unsigned int y, unsigned int w) {
    drawLine(x, y, x + w, y);
}

void DigoleSerialDisp::drawVLine(unsigned int x, unsigned int y, unsigned int h) {
    drawLine(x, y, x, y + h);
}

void DigoleSerialDisp::nextTextLine(void) {
    write((uint8_t) 0);
    Print::print("TRT");
}

void DigoleSerialDisp::setFont(uint8_t font) {
    Print::print("SF");
    write(font);
}

void DigoleSerialDisp::setColor(uint8_t color) {
    Print::print("SC");
    write(color);
}

void DigoleSerialDisp::backLightOn(void) {
    Print::print("BL");
    write((uint8_t) 1);
}

void DigoleSerialDisp::backLightOff(void) {
    Print::print("BL");
    write((uint8_t) 0);
}

void DigoleSerialDisp::directCommand(uint8_t d) {
    Print::print("MCD");
    write(d);
}

void DigoleSerialDisp::directData(uint8_t d) {
    Print::print("MDT");
    write(d);
}

void DigoleSerialDisp::moveArea(unsigned int x0, unsigned int y0, unsigned int w, unsigned int h, char xoffset, char yoffset) {
    Print::print("MA");
    writePosition(x0);
    writePosition(y0);
    writePosition(w);
    writePosition(h);
    write(xoffset);
    write(yoffset);
}

void DigoleSerialDisp::uploadStartScreen(int lon, const unsigned char *data) {
     int j;
     uint8_t c;
    Print::print("SSS");
    write((uint8_t) (lon % 256));
    write((uint8_t) (lon / 256));
    delay(300);
    for (j = 0; j < lon;j++) {
        if((j%32)==0)
         delay(50);
         delay(_Comdelay);
        c=pgm_read_byte_near(data+j);
        write(c);
    }
}

void DigoleSerialDisp::uploadUserFont(int lon, const unsigned char *data, uint8_t sect) {
     uint8_t c;
    Print::print("SUF");
    write(sect);
    write((uint8_t) (lon % 256));
    write((uint8_t) (lon / 256));
    for (int j = 0; j < lon; j++) {
        if((j%32)==0)
         delay(50);
         delay(_Comdelay);
        c=pgm_read_byte_near(data+j);
        write(c);
    }
}
void DigoleSerialDisp::drawBitmap256(unsigned int x, unsigned int y, unsigned int w, unsigned int h, const uint8_t *bitmap) {   //display 256 color image
    uint8_t i = 0;
    Print::print("EDIM1");
    writePosition(x); //x;
    writePosition(y);
    writePosition(w);
    writePosition(h);
    for (int j = 0; j < h * w; j++) {
        write(pgm_read_byte_near(bitmap + j));
//        delay(5);
    }
}
void DigoleSerialDisp::drawBitmap262K(unsigned int x, unsigned int y, unsigned int w, unsigned int h, const uint8_t *bitmap) {  //display 256 color image
    uint8_t i = 0;
    Print::print("EDIM3");
    writePosition(x); //x;
    writePosition(y);
    writePosition(w);
    writePosition(h);
    for (int j = 0; (j < h * w *3); j++) {
        write(pgm_read_byte_near(bitmap + j));
//        delay(5);
    }
}
void DigoleSerialDisp::setTrueColor(uint8_t r, uint8_t g, uint8_t b) {  //Set true color
    uint8_t i = 0;
    Print::print("ESC");
    write(r);
    write(g);
    write(b);
}

//DigoleSerial.h

//Digole Digital Solutions: www.digole.com
#ifndef DigoleSerialDisp_h
#define DigoleSerialDisp_h

#include <inttypes.h>
#include "Print.h"
#include <Wire.h>
#include "Arduino.h"

// Communication set up command
// Text function command
// Graph function command

#define Serial_UART 0;
#define Serial_I2C 1;
#define Serial_SPI 2;
#define _TEXT_ 0
#define _GRAPH_ 1

class DigoleSerialDisp : public Print {
public:
#if defined(_Digole_Serial_UART_)

DigoleSerialDisp(HardwareSerial *s, unsigned long baud) //UART set up
    {
        _mySerial = s;
        _Baud = baud;
        _Comdelay=2;
    }

    size_t write(uint8_t value) {
        _mySerial->write(value);
        return 1; // assume sucess
    }

    void begin(void) {
        _mySerial->begin(9600);
        _mySerial->print("SB");
        _mySerial->println(_Baud);
        delay(100);
        _mySerial->begin(_Baud);
    }
#endif
#if defined(_Digole_Serial_I2C_)

void begin(void) {
        _myWire->begin();
    }

    DigoleSerialDisp(TwoWire *s, uint8_t add) //U2C set up
    {
        _myWire = s;
        _I2Caddress = add;
        _Comdelay=6;
    }

    size_t write(uint8_t value) {
        _myWire->beginTransmission(_I2Caddress);
        _myWire->write(value);
        _myWire->endTransmission();
        return 1; // assume sucess
    }
#endif
#if defined(_Digole_Serial_SPI_)

void begin(void) {
    }

    DigoleSerialDisp(uint8_t pin_data, uint8_t pin_clock, uint8_t SS) //spi set up
    {
        _Clockpin = pin_clock;
        _Datapin = pin_data;
        _SSpin = SS;
        pinMode(_Clockpin, OUTPUT);
        pinMode(_Datapin, OUTPUT);
        pinMode(_SSpin, OUTPUT);
        digitalWrite(_SSpin, HIGH);
        digitalWrite(_Clockpin, LOW);
        digitalWrite(_Datapin, LOW);
        _Comdelay=6;
    }

    size_t write(uint8_t value) {
        digitalWrite(_SSpin, LOW);
        digitalWrite(_SSpin, LOW);
        digitalWrite(_SSpin, LOW);
        shiftOut(_Datapin, _Clockpin, MSBFIRST, value);
        digitalWrite(_SSpin, HIGH);
        return 1; // assume sucess
    }
#endif
    //    virtual size_t write(uint8_t);
    //    void begin(void);

        /*---------fucntions for Text and Graphic LCD adapters---------*/
    void writePosition(int p)
    {
    if(p>255)
    {
        write(255);
        p-=255;
    }
    write(p);
    }
    void disableCursor(void) {
        Print::print("CS0");
    }

    void enableCursor(void) {
        Print::print("CS1");
    }

    void drawStr(unsigned int x, unsigned int y, const char *s) {
        Print::print("TP");
    writePosition(x);
    writePosition(y);
        Print::print("TT");
        Print::println(s);
    }

    void setPrintPos(unsigned int x, unsigned int y, uint8_t graph = _TEXT_) {
        if (graph == _TEXT_) {
            Print::print("TP");
            writePosition(x);
            writePosition(y);
        } else {
            Print::print("GP");
            writePosition(x);
            writePosition(y);
        }
    }

    void clearScreen(void) {
        Print::print("CL");
    }

    void setLCDColRow(uint8_t col, uint8_t row) {
        Print::print("STCR");
        write(col);
        write(row);
        Print::print("\x80\xC0\x94\xD4");
    }

    void setI2CAddress(uint8_t add) {
        Print::print("SI2CA");
        write(add);
        _I2Caddress = add;
    }

    void displayConfig(uint8_t v) {
        Print::print("DC");
        write(v);
    }
    //print function

    size_t println(const __FlashStringHelper *v) {
        preprint();
        Print::println(v);
        Print::print("\x0dTRT");
    }

    size_t println(const String &v) {
        preprint();
        Print::println(v);
        Print::println("\x0dTRT");
    }

    size_t println(const char v[]) {
        preprint();
        Print::println(v);
        Print::println("\x0dTRT");
    }

    size_t println(char v) {
        preprint();
        Print::println(v);
        Print::println("\x0dTRT");
    }

    size_t println(unsigned char v, int base = DEC) {
        preprint();
        Print::println(v, base);
        Print::println("\x0dTRT");
    }

    size_t println(int v, int base = DEC) {
        preprint();
        Print::println(v, base);
        Print::println("\x0dTRT");
    }

    size_t println(unsigned int v, int base = DEC) {
        preprint();
        Print::println(v, base);
        Print::println("\x0dTRT");
    }

    size_t println(long v, int base = DEC) {
        preprint();
        Print::println(v, base);
        Print::println("\x0dTRT");
    }

    size_t println(unsigned long v, int base = DEC) {
        preprint();
        Print::println(v, base);
        Print::println("\x0dTRT");
    }

    size_t println(double v, int base = 2) {
        preprint();
        Print::println(v, base);
        Print::println("\x0dTRT");
    }

    size_t println(const Printable& v) {
        preprint();
        Print::println(v);
        Print::println("\x0dTRT");
    }

    size_t println(void) {
        Print::println("\x0dTRT");
    }

    size_t print(const __FlashStringHelper *v) {
        preprint();
        Print::println(v);
    }

    size_t print(const String &v) {
        preprint();
        Print::println(v);
    }

    size_t print(const char v[]) {
        preprint();
        Print::println(v);
    }

    size_t print(char v) {
        preprint();
        Print::println(v);
    }

    size_t print(unsigned char v, int base = DEC) {
        preprint();
        Print::println(v, base);
    }

    size_t print(int v, int base = DEC) {
        preprint();
        Print::println(v, base);
    }

    size_t print(unsigned int v, int base = DEC) {
        preprint();
        Print::println(v, base);
    }

    size_t print(long v, int base = DEC) {
        preprint();
        Print::println(v, base);
    }

    size_t print(unsigned long v, int base = DEC) {
        preprint();
        Print::println(v, base);
    }

    size_t print(double v, int base = 2) {
        preprint();
        Print::println(v, base);
    }

    size_t print(const Printable& v) {
        preprint();
        Print::println(v);
    }
    void preprint(void);
    /*----------Functions for Graphic LCD/OLED adapters only---------*/
    //the functions in this section compatible with u8glib
    void drawBitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h, const uint8_t *bitmap);
    void drawBitmap256(unsigned int x, unsigned int y, unsigned int w, unsigned int h, const uint8_t *bitmap);
    void drawBitmap262K(unsigned int x, unsigned int y, unsigned int w, unsigned int h, const uint8_t *bitmap);
    void setTrueColor(uint8_t r, uint8_t g, uint8_t b);
    void setRot90(void);
    void setRot180(void);
    void setRot270(void);
    void undoRotation(void);
    void setRotation(uint8_t);
    void setContrast(uint8_t);
    void drawBox(unsigned int x, unsigned int y, unsigned int w, unsigned int h);
    void drawCircle(unsigned int x, unsigned int y, unsigned int r, uint8_t = 0);
    void drawDisc(unsigned int x, unsigned int y, unsigned int r);
    void drawFrame(unsigned int x, unsigned int y, unsigned int w, unsigned int h);
    void drawPixel(unsigned int x, unsigned int y, uint8_t = 1);
    void drawLine(unsigned int x, unsigned int y, unsigned int x1, unsigned int y1);
    void drawLineTo(unsigned int x, unsigned int y);
    void drawHLine(unsigned int x, unsigned int y, unsigned int w);
    void drawVLine(unsigned int x, unsigned int y, unsigned int h);
    //-------------------------------
    //special functions for our adapters
    void setFont(uint8_t font); //set font, availale: 6,10,18,51,120,123, user font: 200-203
    void nextTextLine(void); //got to next text line, depending on the font size
    void setColor(uint8_t); //set color for graphic function
    void backLightOn(void); //Turn on back light
    void backLightOff(void); //Turn off back light
    void directCommand(uint8_t d); //send command to LCD drectly
    void directData(uint8_t d); //send data to LCD drectly
    void moveArea(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, char xoffset, char yoffset); //move a area of screen to another place

    void displayStartScreen(uint8_t m) {
        Print::print("DSS");
        write(m);
    } //display start screen

    void setMode(uint8_t m) {
        Print::print("DM");
        write(m);
    } //set display mode

    void setTextPosBack(void) {
        Print::print("ETB");
    } //set text position back to previous, only one back allowed

    void setTextPosOffset(char xoffset, char yoffset) {
        Print::print("ETO");
        write(xoffset);
        write(yoffset);
    }

    void setTextPosAbs(unsigned int x, unsigned int y) {
        Print::print("ETP");
        writePosition(x);
        writePosition(y);
    }
    void setLinePattern(uint8_t pattern) {
        Print::print("SLP");
        write(pattern);
     }
    void setLCDChip(uint8_t chip) {      //only for universal LCD adapter
        Print::print("SLCD");
        write(chip);
     }
    void uploadStartScreen(int lon, const unsigned char *data); //upload start screen
    void uploadUserFont(int lon, const unsigned char *data, uint8_t sect); //upload user font
    void digitalOutput(uint8_t x) {Print::print("DOUT");write(x);}
private:
    unsigned long _Baud;
    HardwareSerial *_mySerial;
    uint8_t _I2Caddress;
    TwoWire *_myWire;
    uint8_t _Clockpin;
    uint8_t _Datapin;
    uint8_t _SSpin;
    uint8_t _Comdelay;
};

#endif

And qMenuSystem has 4 files :
qMenuDisplay.cpp
#include "qMenuDisplay.h"
#include <Wire.h>

//DigoleSerialDisp _disp(8,9,10);
DigoleSerialDisp _disp(&Wire,'\x3C');

qMenuDisplay::qMenuDisplay()
{
}

qMenuDisplay::qMenuDisplay(DigoleSerialDisp disp)
{
  _disp=disp;
}

void qMenuDisplay::Start()
{
  _disp.clearScreen();
  _disp.setFont(18);
}

void qMenuDisplay::Finish()
{
}

void qMenuDisplay::Title(const char text[])
{
  _disp.setTextPosAbs(64-strlen(text)*9/2,11);
  _disp.print(text);
  _disp.drawHLine(0,14,128);
}

void qMenuDisplay::Item(int index,const char text[])
{
  _disp.setTextPosAbs(5,(index*14)+32);
  _disp.print(text);
}

void qMenuDisplay::Highlight(int index)
{
  _disp.setMode('~');
  _disp.drawBox(4,(index*14)+20,120,13);
}

void qMenuDisplay::MessageBox(const char text[])
{
  int textWidth=strlen(text)*9;
  int x=64-(textWidth/2);
  int y=32;

  _disp.setMode('&');
  _disp.setColor(0);
  _disp.drawBox(x-5,y-12,textWidth+9,21+3);
  _disp.setMode('~');
  _disp.setColor(1);
  _disp.drawFrame(x-3,y-10,textWidth+5,17+3);

  _disp.setTextPosAbs(x,y+5);
  _disp.print(text);
}

qMenuDisplay.h

#define _Digole_Serial_I2C_
#include <DigoleSerial.h>
#ifndef qMenuDisplay_h
#define qMenuDisplay_h

class qMenuDisplay
{
  public:
    qMenuDisplay(DigoleSerialDisp disp);
    qMenuDisplay();
    void Start();
    void Finish();
    void Title(const char text[]);
    void Item(int index,const char text[]);
    void Highlight(int index);
    void MessageBox(const char text[]);
  private:
//    char tempBuffer[32];
};

#endif

qMenuSystem.cpp

/////////////////////
// qMenuSystem
// version: 1.0
// 22.12.2013
// CLASS
/////////////////////
#include <avr/pgmspace.h>
#include "qMenuSystem.h"
#include "qMenuDisplay.h"

//DigoleSerialDisp disp(255,255,255);
//qMenuDisplay qmd;

qMenuSystem::qMenuSystem(DigoleSerialDisp disp)
{
  qmd=qMenuDisplay(disp);
  _selectedIndex=0;
  _itemCount=0;
  _firstVisible=1;
}

void qMenuSystem::InitMenu(const char ** page, int itemCount, int selectedIndex)
{
  CurrentMenu=page;
  _selectedIndex=selectedIndex;
  _itemCount=itemCount;
//  ProcessMenu(ACTION_NONE);
  ShowMenu();
}

int qMenuSystem::ProcessMenu(int action)
{
  if (action==ACTION_DOWN)
    _selectedIndex++;
  if (action==ACTION_UP)
    _selectedIndex--;

  if (_selectedIndex>_itemCount)
    _selectedIndex=1;
  if (_selectedIndex<1)
    _selectedIndex=_itemCount;

  if (action==ACTION_SELECT)
    return _selectedIndex;

  ShowMenu();

  return 0;
}

void qMenuSystem::ShowMenu()
{
  if (_selectedIndex>_firstVisible+2)
    _firstVisible=_selectedIndex-2;
  else if (_selectedIndex<_firstVisible)
    _firstVisible=_selectedIndex;

  qmd.Start();

  // display title
  strcpy_P(tempBuffer, (char*)pgm_read_word(&(CurrentMenu[0])));
  qmd.Title(tempBuffer);

  // display items
  int p = 3;
  if (p > (_itemCount-_firstVisible+1))
    p=_itemCount-_firstVisible+1;
  for (int i=0;i<p;i++)
  {
    strcpy_P(tempBuffer, (char*)pgm_read_word(&(CurrentMenu[i+_firstVisible])));
    qmd.Item(i,tempBuffer);
  }

  // display selection
  qmd.Highlight(_selectedIndex-_firstVisible);

  qmd.Finish();
}

qMenuSystem.h

/////////////////////
// qMenuSystem
// version: 1.0
// 22.12.2013
// HEADER
/////////////////////
#include "qMenuDisplay.h"

#ifndef qMenuSystem_h
#define qMenuSystem_h

#define ACTION_NONE    0
#define ACTION_UP      1
#define ACTION_DOWN    2
#define ACTION_SELECT  3
#define ACTION_BACK    4

class qMenuSystem
{
  public:
    qMenuSystem(DigoleSerialDisp disp);
    void InitMenu(const char ** page, int itemCount, int selectedIndex);
    int ProcessMenu(int action);
    void ShowMenu();
    void MessageBox(const char text[]) { qmd.MessageBox(text); };

    const char ** CurrentMenu;
  private:
    int _selectedIndex;
    int _itemCount;
    int _firstVisible;

    char tempBuffer[32];
    qMenuDisplay qmd;
};

#endif

Here is what it should show on the screen : https://www.youtube.com/watch?v=rjON_enuOGs
The example code that I'm using it this:
/*
======================================
qMenuSystem example #1
======================================

1. Connect OLED in SPI mode: DATA=D8, CLOCK=D9, SS=D10
2. Compile & upload
3. Open Serial monitor (Ctrl+Shift+M)
4. Use "q", "a", "s" to move across menu ("q" = up, "a" = down, "s" = select)

*/

#define _Digole_Serial_I2C_
#include <DigoleSerial.h>
#include <Wire.h>

#include <qMenuDisplay.h>
#include <qMenuSystem.h>

#include "TestMenu.h"

//DigoleSerialDisp mydisp=DigoleSerialDisp(8,9,10);
//DigoleSerialDisp _disp(&Wire,'\x3C');

//DigoleSerialDisp mydisp=DigoleSerialDisp _disp(&Wire,'\x3C');
//qMenuSystem menu=qMenuSystem(mydisp);
DigoleSerialDisp _mydisp(&Wire,'\x3C');
qMenuSystem menu(_mydisp);

void setup()
{
  //mydisp.begin();
  //mydisp.clearScreen(); //CLear screen
  menu.InitMenu(mnuRoot,cntRoot,1);
  //mydisp.write(0);
  Serial.begin(9600);
}

void loop()
{
  int keycode=0;
  int clickedItem=0;

  if (Serial.available()>0)
  {
    switch(Serial.read())
    {
      case 97:
        menu.ProcessMenu(ACTION_DOWN);
        break;
      case 113:
        menu.ProcessMenu(ACTION_UP);
        break;
      case 115:
        clickedItem=menu.ProcessMenu(ACTION_SELECT);
        break;
    }
  }

  if (clickedItem>0)
  {
    // Logic for Root menu
    if (menu.CurrentMenu==mnuRoot)
      switch (clickedItem)
      {
        case 1:
          menu.InitMenu(mnuSubmenu1,cntSubmenu1,1);
          break;
        case 2:
          menu.InitMenu(mnuSubmenu2,cntSubmenu2,1);
          break;
        case 3:
          menu.InitMenu(mnuSubmenu3,cntSubmenu3,1);
          break;
        case 4:
          menu.MessageBox("Some message!");
          break;
      }
    // Logic for Submenu 1
    else if (menu.CurrentMenu==mnuSubmenu1)
      switch (clickedItem)
      {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
          menu.MessageBox("Item clicked");
          break;
        case 6:
          menu.InitMenu(mnuRoot,cntRoot,1);
          break;
      }
    // Logic for Submenu 2
    else if (menu.CurrentMenu==mnuSubmenu2)
      switch (clickedItem)
      {
        case 1:
          menu.MessageBox("On");
          break;
        case 2:
          menu.MessageBox("Off");
          break;
        case 3:
          menu.InitMenu(mnuRoot,cntRoot,2);
          break;
      }
    // Logic for Submenu 3
    else if (menu.CurrentMenu==mnuSubmenu3)
      switch (clickedItem)
      {
        case 1:
          menu.MessageBox("Enabled");
          break;
        case 2:
          menu.MessageBox("Disabled");
          break;
        case 3:
          menu.InitMenu(mnuRoot,cntRoot,3);
          break;
      }

  }
}

and with the bundled progmem part :
// required for "prog_char" and "PROGMEM"
#define _PROG_TYPES_COMPAT_
#include <avr/pgmspace.h>

// texts for menus

const char itmBack[] PROGMEM = "< Back";
const char itmOn[] PROGMEM = "On";
const char itmOff[] PROGMEM = "Off";
const char itmEnabled[] PROGMEM = "Enabled";
const char itmDisabled[] PROGMEM = "Disabled";

const char itmRoot[] PROGMEM = "Root menu";
const char itmSubmenu1[] PROGMEM = "Submenu 1";
const char itmSubmenu2[] PROGMEM = "Submenu 2";
const char itmSubmenu3[] PROGMEM = "Submenu 3";
const char itmMessageBox[] PROGMEM = "Message box";
const char itmItem1[] PROGMEM = "Item 1";
const char itmItem2[] PROGMEM = "Item 2";
const char itmItem3[] PROGMEM = "Item 3";
const char itmItem4[] PROGMEM = "Item 4";
const char itmItem5[] PROGMEM = "Item 5";

////////////////////////////////////////////////////////////////
// menus - first item is menu title and it does not count toward cnt

const char* mnuRoot[] = {
  itmRoot,
  itmSubmenu1,itmSubmenu2,itmSubmenu3,itmMessageBox};
const int cntRoot = 4;

const char* mnuSubmenu1[] = {
  itmSubmenu1,
  itmItem1,itmItem2,itmItem3,itmItem4,itmItem5,itmBack};
const int cntSubmenu1 = 6;

const char* mnuSubmenu2[] = {
  itmSubmenu2,
  itmOn,itmOff,itmBack};
const int cntSubmenu2 = 3;

const char* mnuSubmenu3[] = {
  itmSubmenu3,
  itmEnabled,itmDisabled,itmBack};
const int cntSubmenu3 = 3;

Can somebody please help me figuring out what's wrong that it doesn't show on the screen? (there are no errors on the code while compiling.)
Thank you so much for reading all the code I posted and for your time.

try changing the first include in qMenuDisplay.h

Thank you for reply, sorry but it's a little bit unclear. First   in which file ? in the test code it's present straight from the start.


text:
Using MOSI and MISO pins for multiple devices
For the device I am creating, I am hooking up an apa102 led strip to pins 11 and 13 to control each LED. But I would also like to hookup my NRF receiver to the arduino, but I also use pins 11 and 13. My question is can i hookup both to the same pins and control the inputs and outputs through the MOSI amd MISO pins separately!

Read about SPI. You can connect all devices to SCK, MISO, MOSI bus and address individual devices via CS(or SS).

@OlegMazurov the APA102 however doesn't have a CS pin, so it can't share a SPI bus. You can implement SPI in software (i.e. bitbang SPI).

@Gerben but you can disable the clock signal to the strip with a transistor or buffer, and it doesn't use the MISO at all so that's not an issue.


text:
Using Arduino fix_fft or arduinoFFT library to filter some specific sound?
I would like to know if there is a way to filter some specific sound using FFT on arduino. For instance, there is wind sound frequency in my analysis and I want to take it off. I searched for that a lot, but I didn't find something useful to solve this problem.

FFT is a tool for analyzing sound. It is not very appropriate for
filtering, unless you have loads of computing power to spare. And it is
even less appropriate for real-time filtering, if that is what you are
after.
Attempting to filter-out a noise based on its frequency is a reasonable
strategy for narrow-band noise, i.e. noise that lies in a narrow band of
frequencies. You can hope that, with some luck, removing this narrow
band doesn't affect too much the interesting part of the signal.
Alas, wind noise is very broad band, although it has more weight at low
frequencies:

(image source).
If the frequencies that interest you are above ≈ 2 – 4 kHz, you could
try a simple high-pass filter. Something like this should work even on
an Arduino if the sample rate is not too high:
static uint16_t filter(uint16_t input)
{
    static uint16_t sum;
    uint16_t delta = input - (sum >> SCALE);
    sum += delta;
    return delta
}

where SCALE is a small constant that determines the cut-off frequency.
Edit: The Z-domain transfer function of this filter is
H = (z − 1) / (z − u)
where u = 1 − 2−SCALE. Its cut-off frequency is then
approximately fsamp ÷ (2 π 2SCALE).

Excellent answer. Note that AVR based Arduinos are a long way from having "Loads of computing power." In fact they are quite the opposite, and do floating point math in software. Their math is really slow, and FFT is floating point intensive.


text:
How to manage interrupt from accelerometer BMA220?
I would like to use the interrupt register from the BMA220 accelerometer in order to detect high-g shock. I am using a Mega2560 and the sensor is powered by 3.3 V. I use a voltage divider to convert the 5V from the card to 3.3V because the 5V pin gives more current. The memory map concerning the registers is shown below
In the datasheet the section concerning high-g registers is as followed :

It is written that whenever a condition is met for the interrupt controller "an interrupt (logic '1') is issued through the INT pin of the sensor."
However after initializing the necessary registers (in I2C):

0xC for high_th
0xA for high_hy and high_dur
0x1C for en_high_x/y/z

I don't get my interrupt working. Using a voltmeter I always get a high value (3.3V) on the INT pin of my accelerometer eventhough it stays still and I wrote a threshold of 2G...
Here is the code I am using :
#include <BMA220.h>
#include "SEN0168.h"

BMA220 bma;
byte interruptPin = 2;
byte count = 0;
const uint8_t HIGH_SET = 0xA;
const uint8_t HIGH_LOW_TH = 0xC;
const uint8_t INTERRUPT_REG = 0x18; // to get the bit indicating an interrupt was detected, not used because of the INT pin
const uint8_t ENABLE = 0x1C;

void setup() {
   Serial.begin(74880);
   pinMode(interruptPin, INPUT);
   init_SEN0168(R4); // set sensitivity to 4G
   bma.setRegister(ENABLE, 0xF7); // enable high-g-detection, reset interrupt bit control and latch permanently
   bma.setRegister(HIGH_LOW_TH, 0x1); // Threshold of 1G
   bma.setRegister(HIGH_SET, 0x1); // No hysteresis and 2 signals needed to trigger
   attachInterrupt(digitalPinToInterrupt(interruptPin),counter, HIGH);
}

void loop() {
    if (count==1){
    Serial.print("x-axis: ");
    Serial.println(accel_range_SEN0168(X,R4));
    Serial.print("y-axis: ");
    Serial.println(accel_range_SEN0168(Y,R4));
    Serial.print("z-axis: ");
    Serial.println(accel_range_SEN0168(Z,R4));
    count =0;
    bma.setRegister(INTRP_RES_REG, 0xF7); // enable high-g-detection, reset interrupt bit control and latch permanently
    }
    else{
      Serial.println("No shock");
      count =0;
    }
}

void counter(){
  count +=1;
}

Am I missing something to clear in one register ? Or maybe since the card is in 5V and the sensor 3.3V logic there is a problem to detect change on the interrupt pin ?  Also I don't know if I understand properly the "logic 1". For me it means it puts the pin to "HIGH".
I use a part of the library written by Sönke Carstens-Behrens to set the registers from here : https://github.com/scbrac/BMA220.
I really need this interrupt pin to work...
Thank you for your help !

I use a voltage divider to convert the 5V from the card to 3.3V because the 5V pin gives more current. errr.... NO!  https://majenko.co.uk/blog/why-you-cant-use-resistors-voltage-regulator

Ok thank you for the article it answers simply the problem of voltage divider ! So it means I just cannot make my device work properly without a voltage regulator ? However I used to record some data that way and it was working. Appart from this, is there something in my code that shouldn't work ?

I am not too familiar with that unit, so I can't be sure.  However, you don't need a voltage regulator. Just use the 3.3V pin to power it. On modern Arduinos the 3.3V pin can provide plenty of power. The old rumour that 3.3V is limited to 50mA is wrong, and has been for many years.

Ok I will use the 3.3V then, thank you ! Has anybody an idea about the logic 1 interrupt ?

You should, at least for testing, set lat_int to 0b111 so it latches the interrupt on the pin until you manually reset it by setting reset_int to 1.  At the moment you have such a brief interrupt that you'll be hard pressed to see it even if it does trigger.

Ok so I tried to change the latch duration for many values in the register 0x1C as you can see in the updated code (for permanent latching) but still no detection of the shock... and the threshold is set to only 1G with no hysteresys

By changing HIGH to LOW of the interrupt I get record from the accelerometer but it doesn't respect the high-g condition...

The interrupt should be RISING, FALLING or LOW. There is no HIGH.

Ok but it is written that when a condition is met a logic 1 will be sent via the INT pin. How am I suppose to detect it ? Also I made a mask to get the bit corresponding to high_int (set to 1 if an interrupt has been triggered) in register 0x18 and this bit is always 1 ! I don't understand...

You would use RISING, which is a change from LOW to HIGH to catch the interrupt. As to why it's always HIGH I have no idea.  However most INT pins I have come across are active LOW not active HIGH...

I tried both RISING and LOW but I don't get the expected behaviour by the accelerometer... So nobody has experience with this accelerometer to share ?

Maybe on ee.se they may. It's more general electronics than Arduino really.

ee.se ? It tells me the website doesn't exist

It's shorthand for electronics.stackexchange.com

Oh ! OK I didn't know sorry ^^'... Well thank you for help Majenko !

That's ok... my fault for assuming everyone had the same strange mind as I do :P  I was using my phone, so easier to type shorthand on there.

EE.se has people that are more likely to understand the internal configuration of the chip and have experience with it.  You should take the Arduino out of the mix for the interrupt reading and instead connect it to an oscilloscope or logic analyser that can independently confirm the presence or not of an interrupt event.  Once you are happy that the interrupt is being configured correctly and is occurring on the pin as you require it to then you can start tackling the Arduino code to read the interrupt.

Thanks it is what I am doing right now and I hope I will get the result I want !

Majenko maybe you know what does this mean : 1 LSB is 2*(LSB of acc_data) ? Because now I get a better behaviour of my accelerometer but I wrote 0x8 for the threshold which is surely not 8G according to the shake I give to it

The least significant bit of the value is double the least significant bit of the accelerometer data.  So 1 is 0.5g, 2 is 1g, 3 is 1.5g, etc. Or that's my interpretation

Ok it is what I was thinking too ! Thanks ! What is funny is that when I put 0x8 I have a better behaviour of the interrupt but I should get 4G threshold which is surely not what I am giving the accelerometer. When I put 0x4 it activates the INT pin too often eventhough I just move slightly the sensor...Maybe I should play with hysteresis now


text:
Powering SIM800L
With peak consumption at 2A, the SIM800L needs much more current than can be supplied by an Arduino or NodeMCU.
What is the best strategy to power this module, considering that you have access to a 100-240V outlet?

Use a suitable 2A power supply.

good answers until now, all UPVOTED.  Will place bounty tomorrow, whoever has the most votes takes it all.

I had to design a board for a customer with a built in LTE modem module (similar to a SIM800), and the power circuitry was something that required special consideration.
One requirement of the board was that the modem should be able to be powered on and off to save power, but that powering it on shouldn't ever cause the rest of the board to brownout.
To this end a separate 5V power circuit was built with a "soft start" facility built in.  This was always on, and fed into a number of capacitors to act as a reservoir. From them the power went via a large P-channel MOSFET to switch the power on to the LTE module when needed.  The capacitors provided the extra inrush current the LTE module demanded at powerup, and the soft start of the power supply limited the initial inrush current of charging the capacitors.
The power supply also had a "power good" output on it which was monitored to know when the output voltage had risen to an acceptable level (and hence the capacitors were charged) and the LTE module was able to be safely enabled.
The basic circuit was:

simulate this circuit – Schematic created using CircuitLab
That is a somewhat overkill probably for your situation though, but you should understand how it's done in the "real world" in a proper device.  However for experimental / prototyping with an Arduino where you aren't wanting to turn the modem on and off, and aren't too worried about the odd brownout, and bulkiness isn't of as much of a concern, then simply using two suitably sized external power supplies is adequate.  One small one to power the MCU (Arduino), and one larger one to power the modem.

simulate this circuit
Because the power supplies themselves should have plenty of capacitance, and they are separately powered from a low impedance source (the mains power) there should be no interference between the modem and the MCU.

The cleanest solution is to use separate power supplies for your MCU and your other high power devices. Get a 2.5A supply for the SIM800L, and a more modest supply for the Arduino/NodeMCU.
If you use the same power supply for both, you should use a bigger power supply than your max current needs to minimize "droop" as the load changes. You might also need to add filtering capacitors to the 5V rails of each device fed by the power supply.
EDIT
I've used this 2A power supply in my projects before: https://www.amazon.com/gp/product/B01G6ZJ6DY/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
You could use one of those for your SIM800L, and a 0.5A supply for the Arduino (A USB power supply would be fine.) Just be sure to tie the ground lines of the separate power supplies together.

two power supplies for MCU and GSM module?

One for each, yes. A regulated power supply still "bobbles" some as its load changes. By using separate power supplies, you isolate the MCU from voltage variations caused the the changing load from the GSM module.

I am usually using 12V/1000 mA adapter source to power Arduino and adjustable step-down/buck converter which powers GPS and similar modules. Advantage of this is that these converters usually have big capacitors on input and output, so you do not have to use additional auxiliary capacitors.

Do you feed 12V into the Arduino's barrel connector? That's on the high side for it's voltage regulator, and will make it run pretty hot. (Or do you feed it regulated 5V from one of the buck converters?)

Yes, I am using barrel connector. It is true that the voltage drop is quite large, but in case you power only Arduino I never had a problem with high temperatures on linear regulator. For chinese clones I rather use 9V power source, though (absolute maximum voltage rating is different for original Arduinos and clones).

Addendum: Just a clarification – the buck converters are also powered from the 12V or 9V power source, not from Arduino VIN or 5V.


text:
How do you write to a specific register using I2C communcation?
I am trying to write to a charging IC (BQ24193) and I am trying to figure out how to use I2C to write to a specific register so I can set up the charging IC properly. I have watched a few videos on the communication protocol, but I don't understand how to write to a register directly. Your help would be appreciated. Thanks.
Datasheet: http://www.ti.com/lit/ds/symlink/bq24193.pdf

use Wire library

figure 18 in the datasheet

The Arduino uses the Wire.h library to communicate on an I2C bus.
Writing to a register in I2C is usually done by sending two bytes to the correct I2C address.  The first byte is usually the register address, and the second is the value to place into the register:
#define CHIP_ADDRESS     0x6B
#define REGISTER_ADDRESS 0x12

Wire.beginTransmission(CHIP_ADDRESS);
Wire.write(REGISTER_ADDRESS);
Wire.write(0x18);
Wire.endTransmission();

Reading from a register is slightly more tricky, in that first you need to write to the chip to set the register address, then as a separate operation you need to read from that address:
Wire.beginTransmission(CHIP_ADDRESS);
Wire.write(REGISTER_ADDRESS);
Wire.endTransmission();
Wire.requestFrom(CHIP_ADDRESS, 1); // We want one byte
uint8_t val = Wire.read();

So with my IC, how do I find the address for each register? I checked the datasheet, and it only included the slave address.

@Jay page 26: "8.5 Register Map"


text:
D1 Mini latch button using rst pin
I'm trying to use a Wemos D1 mini as a smart button that will boot up, perform a task, and then shut back down. I'd like to do this as a true power off as opposed to any sort of sleep mode.
I'm hoping I can do something similar to this post https://www.esp8266.com/viewtopic.php?f=11&t=4458

Tie RST pin to a Low GPIO pin so that it doesn't boot
Push a button that will run 3.3v to RST pin to make it go high and cause a boot up
Flip the GPIO pin that is tied to RST to high so that it stays running when button is no longer pressed
Run some code and flip GPIO back to LOW shutting down

Things I've tried:

Tie to GPIO15 (D8) - This stops the boot and starts booting when button is pressed but never finishes booting up. I'm assuming I am causing D8 to go high by pressing my button and interfering with the boot, but honestly not sure
Tie to GPIO4 or 5 (D2, D1). This doesn't prevent boot.
I've also tried #2 with a pull down resistor on the GPIO pin, but that doesn't seem to work either

Any help would be much appreciated.

reset button is HIGH and connecting it to ground executes reset

how do you plan to turn off the USB chip on Wemos D1?

To do this you would usually use MOSFETs to control the power.
Take the following circuit, for example:

simulate this circuit – Schematic created using CircuitLab
M1 is normally off, having its gate pulled up by R1.
Pressing SW1 pulls the gate of M1 low, allowing current to flow through it to power the D1.
The D1 boots up, and immediately drives the GPIO high.
This then turns on M2 (which is normally off, having the gate pulled down by R2), which in turn pulls the gate of M1 low.
SW1 can now be released since M2 is doing the same job.
To turn off, simply drive the GPIO low, or allow it to float as an input, in which case R2 will turn off M2, which then turns off M1, which stops the current flowing.

Try using D8, also follow this for selecting your pins to make sure the code runs as it is attended to work

D8 (io 15) must be LOW at boot

Would a diode between my button and D8 maybe fix the problem with it getting pushed high?

as far as I know, it's not possible [the way as simple as you said]. here's some notes :

after a reset, GPIOs are set as inputs. if you connect a GPIO to RST and make it low, it resets the chip, but immediately sets the GPIOs as inputs and the RST is released.
if you don't use appropriate resistors, you'll burn the GPIO driver by connecting an output GPIO to a supply line. e.g. when you are trying to connect 3.3v to RST and LOW GPIO which is holding RST down.
sleep modes are very efficient. many times, the battery self discharge is much higher than an slept MCU
if you insist, turn the chip off by cutting off it's supply using an external circuitry. a 555 with a mosfet without any res,cap will do the jb (using only it's internal flip flop)

reset pin has a pull-up so a pin in input mode will nott pull it LOW

@Juraj that's exactly what I assumed. he wanted a GPIO to keep reset LOW. but I said it's not possible because as soon as chip resets, the GPIO is input and the reset is released. it boots up

sorry, yes, you are right


text:
Arduino Uno not working after Short-circuit
While wiring up my new Arduino Uno R3, I accidentally shorted the 5V pin and the GND pin (for less than a sec). It was powered by a 12V 500mAh power supply through the Arduino DC power jack. . The ON, Rx, X1 and L LED's are glowing continuously, and also, pressing the reset button doesn't have any effect on the LED's and arduino doesn't restarts. How can I get my arduino working again?

Because short only lasted for a sec, maybe just maybe one of the component in the supply part of Arduino burned out. or the 500mA damaged the the main IC(ATMEGA328). so before anything change the regulator (AS1117) that is next to the power jack, and then turn on the Arduino. if it didn't work try changing the main IC.

The regualator of that 5V Blew up or the diode you need to read the schemtics of the Arduino Uno and check the circuits.
https://www.arduino.cc/en/uploads/Main/arduino-uno-schematic.pdf

Chances are the cheap Chinese clone board you have has an inferior 5V regulator with no thermal protection.
These are notorious for breaking with a short circuit (over-current = over-temperature = meltdown).  And when they break they "fail short", which means that they end up working like a simple piece of wire - the voltage you put in is the voltage you get out.
That means that 12V has now been sent into the rest of the Arduino, and has destroyed everything - the main MCU, the USB interface chip, etc.
In short: your board is dead.

You can tell it's a fake Uno because the USB chip is not an Atmega32U4.


text:
Rotary Encoder gives "wrong" patterns?
I am trying to learn how to use a Rotary Encoder together with an LCD display where I can use the encoder to choose Letters that will be printed in the LCD.

This is the kind of result I should be getting, but instead I am getting this:
1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16
c  d  e  f  0  1  2  3  4  5   6   7   8   9   a   b
10 00 10 00 11 01 11 01 10 00  10  00  11  01  11  01
A:
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
B:
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
Shouldn't I be getting a sort of
001100110
100110011
pattern to be able to tell which way it is rotated?
How can I fix this?
I am using the following connections:

I don't understand what you mean with these patterns. Please explain more, how you get to those patterns and what exactly you didn't expect

How are we supposed to know what's wrong with your code if we can't see it?

you are misunderstanding how to use the encoder ... you do not read the two bits and look for patterns ... you wait for A to change ... that tells you that the encoder moved ... the state of B at the time of the change tells you the direction of rotation ... to make it simple, look for only the rising edge of signal A


text:
Is it possible to put priorities between external interrupts?
My question is quite simple. I am using one external interrupt on the Mega2560 to wake it up with an alarm from the rtc DS3231 and record data from sensors for about 30 seconds and I would like also to use the other external interrupt to wake it up in case of shock detection to measure the signal.
The thing is that I know external interrupts have priority on internal interrupt but is it possible to put, in my case, the shock detection prior to the alarm ? In case the shock occurs during the alarm recording I would prefer to record the shock signal.
Thank you for your help !

Is it really important to catch the case, that both interrupts fire at the same time? That's seems to be a rather rare case. Maybe it would be sufficient to check the shock interrupt flag at the start of the alarm ISR.

Hi ! Ok so it is not possible to have priorities between external interrupts ? I agree that it would be bad luck if the shock occurs at that moment but I wanted a rather robust system. Your idea of checking the flag at the moment of the alarm will just tell me if a shock occured but I wouldn't get the intensity of it... I guess I will have to make a compromise. Thank you !

Interrupts are not the right place to handle priorities. The interrupt
handlers should be as short as possible. Then the likeliness of two of
them happening at the same time is very low. And even if it happens, the
lowest-priority interrupt will only be delayed by a handful of
microseconds, which should not be a big deal.
In this case, the sensible approach is to have the interrupt handlers
set a global flag and do nothing else. Then the main program will
check the flags and do the real work, handling the priorities as needed.
Conceptually, the code could be something along these rough lines:
// Global flags.
volatile bool alarmDetected;
volatile bool shockDetected;

// Interrupt handlers.
void onAlarmInterrupt() { alarmDetected = true; }
void onShockInterrupt() { shockDetected = true; }

void loop() {
    if (shockDetected) {  // check this first!
        measureShockData();
        if (gotEnoughShockData()) {
            shockDetected = false;
            alarmDetected = false;  // ignore the alarm
            goToSleep();
        }
    } else if (alarmDetected) {
        recordSensorData();
        if (gotEnoughSensorData()) {
            alarmDetected = false;
            goToSleep();
        }
    }
}

Note that you can remove the line that ignores the alarm in case of
shock. If you do so, the alarm will be handled after all relevant
shock data has been recorded.

Hi ! Thank you for your solution I think I will go with it !


text:
Http request change delay
i'm noob in coding i try to make some led blink ( with succes ) and now i would like to add http request to change delay.
i have no error compiling the code but it dont work any idea ?
Thanks
 include SPI.h
 include Ethernet.h

unsigned long maxTime = 4000;

EthernetServer arduinoServer(81);
EthernetServer httpServer(80);

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 8, 60);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

////CODE IS 11001010
int led1 = 6;  // = 0
int led2 = 7;  // = 1

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

  // Setup the 3 pins as OUTPUT
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);

  // You can use Ethernet.init(pin) to configure the CS pin
  //Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // 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
  }
  Serial.println("Ethernet WebServer Example");

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

}

void loop()
{
  digitalWrite(led1, LOW);
  digitalWrite(led2, HIGH);
  delay(maxTime);
  digitalWrite(led2, LOW);
  delay(maxTime);
  digitalWrite(led1, LOW);
  digitalWrite(led2, HIGH);
  delay(maxTime);
   digitalWrite(led1, HIGH);
   digitalWrite(led2, LOW);
  delay(maxTime);
  digitalWrite(led1, LOW);
   delay(maxTime);

   digitalWrite(led1, HIGH);
   digitalWrite(led2, LOW);
  delay(maxTime);
   digitalWrite(led1, LOW);
   digitalWrite(led2, HIGH);
  delay(maxTime);
   digitalWrite(led1, HIGH);
   digitalWrite(led2, LOW);
  delay(maxTime);
   digitalWrite(led1, LOW);
   digitalWrite(led2, HIGH);
  delay(maxTime);
   digitalWrite(led1, HIGH);
   digitalWrite(led2, LOW);
  delay(maxTime);
     digitalWrite(led1, LOW);
   digitalWrite(led2, LOW);
  delay(5000);

 // listen for incoming clients
}

void receiveHttpRequest() {
  EthernetClient client = httpServer.available();
  String requestInputString;
  boolean resetArduino = false;
  boolean forceSolved = false;
  client.setConnectionTimeout(50);

  if (client)
  {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    boolean firstLine = true;
    requestInputString = String("");
    while (client.connected())
    {
      if (client.available())
      {
        char c = client.read();
        if (firstLine)
        {
          requestInputString += String(c);
        }
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank)
        {

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close"); // the connection will be closed after completion of the response
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html><body>");

            int newMaxTime = requestInputString.substring(20).toInt();
            if (newMaxTime < 2000) {
              newMaxTime = 2000;
            }

            maxTime = newMaxTime;

            client.print(String("New maxTime is: "));
            client.println(maxTime);
          }
        }
      }
    }
  }

At no point do you call receiveHttpRequest(). Just making a function isn't good enough - you have to actually call that function.

Inside delay() no other code can run. Which also means that no clients can be serviced.
Change that delay-laden function to a state machine mirroring blinkWithoutDelay.
That is you test if(millis() - previousTimestamp < delay) and if true progress to the next state in your blinks and update previousTimestamp.
After that if you call receiveHttpRequest() to see if any clients are waiting and process the input.


text:
Missing bytes sended through serial from C# app
I am trying to store values sended by C# app in EEPROM via Arduino UNO. Here is a C# code that reads bytes from file (I'm 100% sure that there are, and always will be 256 bytes) and sends the buffer via SerialPort
        SerialPort port = new SerialPort("COM3", 9600);
        const string fileName = @"filepath";
        port.Open();
        byte[] buffer = File.ReadAllBytes(fileName);
        port.Write("W");
        port.Write(buffer, 0, buffer.Length);

Here is Arduino Code
int flag;
int datasize = 256;
byte byteBuffer[256];

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

  //read_write();
}

void loop() {
  readEEPROM();
  writeEEPROM();
  delay(500);
}

void readEEPROM() {
  if (Serial.available()) {
    flag = Serial.read();
    if (flag == 'R') {
      for (int i = 0; i < datasize; i++) {
        byteBuffer[i] = ME.read(i);
      }
      flag = 'S';
      Serial.write(byteBuffer, datasize);
    }
  }
}
void writeEEPROM() {
  if (Serial.available()) {
    flag = Serial.read();
    if (flag = 'W') {
      int bytesRead = 0;
      digitalWrite(LED_BUILTIN, HIGH);
      delay(500);
      while (bytesRead < 256) {
        if (Serial.available() > 0) {
          byteBuffer[bytesRead] = Serial.read();
          bytesRead++;
        }
      }
  digitalWrite(LED_BUILTIN, LOW);

  for (int i = 0; i < datasize; i++) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(50);
    ME.writeEnable();
    ME.write(i, byteBuffer[i]);
    ME.writeDisable();
    digitalWrite(LED_BUILTIN, LOW);
    delay(50);
  }
  flag = 'S';
   }
  }
 }

As you can see in writeEEPROM function arduino turns on BUILTIN_LED before it starts reading serial, sadly the LED is never turning off, which makes me think like there are never 256 bytes in SerialPort, whats more, when i turn the c# program on again, the arduino successfully leaves the while loop, but the data is deformed, I mean the values are different.

why don't you know if there are 256 bytes received by the serial port?

Don't forget that the Arduino reboots every time you open the serial port from the computer - and the bootloader runs for a second or two gobbling up any serial data you send its way...

@jsotola Well, to leave the while loop arduino needs to enter into if(Serial.available()) 255 times, right now it is not leaving while loop, that's why i assume that there are couple of bytes missing or something like that :/

@Majenko How can I solve this then ? :)

Either put a delay after opening the serial port to give the bootloader a chance to finish, or write a proper protocol that includes being able to tell if the Arduino is ready to receive data.  Maybe send a "?" and if the Arduino replies "Y" then it's running and you can send data.

But if the arduino comes into Flag = 'W' in my example isn't it already able to read the data? I mean it have to read the serial to start the function :) Anyway I tried delaying the C# program after opening the port, it didn't help

It can't help but get into "w" - you're assigning with = not comparing with ==.

@Shizzle, the reason i asked you why you do not know if 256 bytes have been received was to make you think "how do i verify that 256 bytes have been sent without error?" .... you can debug your code by removing the EEPROM code and replacing it with code that sends the data back to sender ... that way you can narrow down the area of failure

There's two basic things wrong here.
First is your way of opening the serial port and immediately sending data.  The Arduino is reset when you open the serial port and the bootloader runs. This takes a second or so, and during that time any data that you send is lost.
Secondly you're not checking for a flag of "W" but instead you're assigning "W" to the flag, which always succeeds.
The line
if (flag = 'W') {

should read
if (flag == 'W') {

To get around the first problem you can either just put a delay (however you do that in C#) after opening the port and before sending the "W", or you could implement a "Are you there?" handshake to look for the Arduino.
One example would be to add an extra flag of (say) "?" to which the Arduino simply responds "Y".
The PC then sends "?" and, if it doesn't receive "Y" within a certain timeout it loops sending "?" again.
Once it receives "Y" then it knows the Arduino is there and ready to receive data, so you can send the "W" command and the data.


text:
is there any archives of melody tones for buzzer used in arduino?
I am using buzzer in my arduino and I read some articles about using array of tones(notes in music) with different frequencies to play play pleasant melodies.however, I do not find any site and archives for tones used in industrial, such as Start,Stop,warning,danger,next level,.... is there any site that collects these things and if not how can I create my own array of tones?
this is notes I have
#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978
#define REST      0

// DURATION OF THE NOTES
#define BPM 480      //you can change this value changing all the others
#define H 2*Q //half 2/4
#define Q 6000U/BPM //quarter 1/4
#define E Q/2   //eighth 1/8
#define S Q/4 // sixteenth 1/16
#define W 4*Q // whole 4/4

There certainly wouldn't be a website that collects Arduino tone arrays. There may be examples around, but no one would collect the arrays together in one place - pretty pointless and obscure.  If you want to map the different musical notes to the actual frequencies then the examples in the IDE have "pitches.h" that contain macros that map the notes for you so you don't need to find out all the frequencies. Then it's just a matter of getting all the right notes in the right order with the right delays. How you implement that is up to you.

I already said that I need industrial notes. I have pitches.h and I need a site to that have a collection of melodies to choose. something to create different melodies for different situation.

There's plenty of places with sound samples of industrial situations - but you would have to transcribe those to individual notes for playing, which you'd need to do by hand.  Most "industrial" systems use sirens and klaxons with predefined tones built in.

not industrial by put the link here https://github.com/robsoncouto/arduino-songs and https://codebender.cc/sketch:238461#Songs%20on%20Piezo.ino

you don't really want to use pleasant melodies in an industrial setting

@jsotola,yeah I don't intend to put Super-mario melody . actually I need 2 or 3 Notes for a specific beep.

@david Could you further define what you mean by "industrial notes"? A "tone" and a "melody" are two different thinks, so I wonder whether you're looking for a song or a certain sound... btw, are you firm with how music "works"?

@SimSon I am not a musician everything I know are from articles I read and they may be incorrect but a "tone" is proportional to a frequency and declared by a Note. a melody is a train of tones. My definition of "Industrial Notes" is single or array of multiple tones that can be heard from an industrial device. for example warning signals is a repeatition of a single tone + no tone or if you might hear a beep in an elavator when it changes a level

Do you know tone()? (https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/). With this you can generate a tone, but composing a melody for start,stop,... is up to you.

maybe this may help you ... https://onlinesequencer.net/

try a sequence C5, E5, G5, C6

@jsotola thanks It was very Helpful,however I have to first set it to 8 bit square wave to get a real buzzer sound

see the toneMelody example in Arduino IDE. or try this sketch https://arduino.stackexchange.com/questions/48166/how-to-loop-a-specific-tone/48173#48173

or use this library https://github.com/evert-arias/EasyBuzzer

@Juraj, Thanks ,It was helpful

#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define REST      0

int piezoPin = 13;
int numTones = 15;
int tempo = 2.5;

//Twinkle Twinkle Little Star:

int tones[] = {NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_C4, REST};

int duration[] = {500, 500, 500, 500, 500, 500, 1000, 500, 500, 500, 500, 500, 500, 1000, 4000};

void setup()
{
  for (int i = 0; i < numTones; i++)
  {
    tone(piezoPin, tones[i], duration[i] / tempo);
    delay(duration[i] / tempo);
  }
  noTone(piezoPin);
}

void loop()
{
} // Reset to play the song again

Twinkle twinkle.  Very industrial.


text:
Wiring power new power button to UPS power module for raspberry pi
I have a UPS Power Module Expansion Board for Raspberry Pi 3B/3B+(Plus) and removed the power button because it is in the way and would like to attach this read button instead. But it is not working, they board does not turn on?
Am i wiring the incorrectly?

you want to replace an on/off switch with momentary button? and where is the Arduino?

This looks like a momentary push-button; use a latching button (push-on/push-off) instead.

Thanks! Will try it out :)


text:
ESP8266 using EEPROM to store a value of 100,000
I'm using Wemos mini in my project. I wish to store a Boolean value in cell #0, which changes every boot.
Since writing to EEPROM is limited to roughly 100,000 cycles - I want to store in cell #1 the amount of writing cycles done so far, so when reaching 100,000 , value will be stored in cell#2 and writing cycles will be stored in cell#3 and so on.
Reading and writing using #include <EEPROM.h> is done as needed, but since each cell can store a byte, it can only reach 255.
My question is how to store a value of 10^6 (except of convert it to a*2^0 + b*2^1 + c*2^2 + d*2^3....).
Guy
EDIT1
Part or relevant code:
void setup() {
        Serial.begin(9600);
        Serial.println("BEGIN:");
        if (HARD_REBOOT) {
                EEPROM.begin(1024);
        }
        if (HARD_REBOOT) {
                EEPROM.write(0,100000);
                EEPROM.commit();
                delay(50);
                Serial.print("value in flash: ");
                Serial.println(EEPROM.read(0));
        }
}

and its output:
Ȥl⸮⸮BGS[⸮<b8ɗ⸮BEGIN:
22:40:58.732 -> value in flash: 160

Comments are not for extended discussion; this conversation has been moved to chat.

The esp doesn't have an eeprom, but emulates it in its flash. Therefore 100.000 cylces will not apply, it's more like 10.000 cycles for flash.
The easiest way to prepare a datatype to be stored as bytes is to use union like follows:
union Converter{
  uint32_t ui32;
  byte eeprom_bytes[4];
}convert;

void convert_for_eeprom (uint32_t your_number) {
  convert.ui32=your_number;
  // convert.eeprom_bytes contains the 4-byte represenstation of your number, write those to eeprom
}

uint32_t convert_from_eeprom () {
  // read four bytes from eeprom and assign those to convert.eeprom_bytes
  return convert.ui32;
}

Note that this isn't a type conversion and the value of convert.eeprom_bytes are not meant to be processed, as they are simply interpreted as if they were a four-byte array, indeed those bytes contain "dumb" values. This way you can "convert" any datatype for byte-wise storage and read-back respectively.
Another option to convert a 32 bit integer to 4 bytes is by using bit-wise operations:
uint32_t your_number=100000;
byte b1=your_number;
byte b2=your_number>>8;
byte b3=your_number>>16;
byte b4=your_number>>24;

But this only makes sense for integers and I suggest taking a look at union.

EEPROM.put() can write any type. that is the easiest  way

to save any variable to EEPROM use EEPROM.put(), to read it use EEPROM.get(). example
EEPROM.put(EEPROM_COUNT_ADDR, count);
EEPROM.get(EEPROM_COUNT_ADDR, count);
On esp8266 EEPROM is emulated in flash and there the whole page wears out. The EEPROM library of esp8266 does what can be done to protect the flash pages used for EEPROM emulation.

But still can use ‘put’ and ‘get’?

yes. the esp8266 EEPROM library has put() and get() too.

substitute write in put, was OK, but when using get yielded :
error: no matching function for call to 'EEPROMClass::get(int)'                  Serial.println(EEPROM.get(0));

EEPROM.get(EEPROM_COUNT_ADDR, count); ! Use second parameter for a variable to be filled.

@Guy.D, does it work?