text:
How to set PC (Program Counter) register to another function (for scheduler)
I am trying to implement a scheduler for Arduino Mega 2560. I think I lack understanding of how to set the PC register to another instruction.
Here is my simple approach so far:
void dummy(){
    digitalWrite(LED_BUILTIN, HIGH);
 }

in a naked ISR method:
SP = (uint16_t)(&dummy)
__asm volatile(
"reti     \n\t"
)

However it is not working. How should the PC register be set to a certain function or to where it was in a previous process for a scheduler approach?

This:
SP = (uint16_t)(&dummy)

is changing the stack pointer. Not what you want. You want to instead
push the destination address to the stack. However, rather than
simulating a function return, it should be simpler to perform an
indirect jump:
asm volatile("ijmp" :: "z"(dummy));

Don't forget that your naked ISR has to save all the call-used
registers, as well as SREG, r0 and r1, in its custom prologue. And
restore them in its epilogue. Check the AVR calling
conventions.

Thanks for you fast answer, I am saving all registsers r0, ..,r31 and SREG to the stack, however I am not sure how I can save the PC into the stack and reload it.

@MustafaOtbah: The PC was already saved by the interrupt. You normally restore it with reti. Maybe you should expand your question and explain in more detail how you intend to manage saving and restoring task context, what you have done so far, and what is not working.


text:
Run light sequence function continuously in if statement
My goal - run light sequence function on momentary button press (button 2) continuously until another of the 3 momentary buttons are pressed.
    /* switch
 *
 * Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
 * press), the output pin is toggled from LOW to HIGH or HIGH to LOW.  There's
 * a minimum delay between toggles to debounce the circuit (i.e. to ignore
 * noise).
 *
 * David A. Mellis
 * 21 November 2006
 */
 #include "FastLED.h"

int inPin = 8;         // the number of the input pin
int inPinTwo = 9;
int inPinThree = 10;
int outPin = 13;       // the number of the output pin

int state = HIGH;      // the current state of the output pin
int reading;           // the current reading from the input pin
int readingTwo;
int readingThree;
int previous = LOW;    // the previous reading from the input pin

int pixelNumber;

// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

//NEOPIXEL
#define LED_PIN     7
#define LEDPIN 7
#define LED_TYPE     NEOPIXEL
#define NUM_LEDS    2
#define BRIGHTNESS 10
#define FRAMES_PER_SECOND 60
CRGB leds[NUM_LEDS];
#define COLOR_ORDER GRB
#define CHIPSET     WS2811

bool gReverseDirection = false;
CRGBPalette16 gPal;

void setup()
{

  pinMode(inPin, INPUT);
  pinMode(inPinTwo,INPUT);
  pinMode(inPinThree,INPUT);
  pinMode(outPin, OUTPUT);

  Serial.begin(9600);

  // set up LED strip info
FastLED.addLeds<LED_TYPE,LEDPIN>(leds,NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
}

void loop()
{

//    BUTTON 1 - SOLID LIGHT
  reading = digitalRead(inPin);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH){
      state = LOW;
      fill_solid(leds,NUM_LEDS,CRGB::Black);
      FastLED.show();
    }
    else{
      state = HIGH;
      fill_solid(leds,NUM_LEDS,0xFAF6D1);
      FastLED.show();
      }

    time = millis();

  }
    digitalWrite(outPin, state);
    previous = reading;

//  BUTTON 2 - GLITTER LIGHT
   readingTwo = digitalRead(inPinTwo);
  if (readingTwo == HIGH && previous == LOW && millis() - time> debounce){
    if(state == HIGH){
      state = LOW;
      fadeToBlackBy( leds, NUM_LEDS, 10);
      addGlitter(30);
      FastLED.show();
      }
    else{
      state = HIGH;
      fill_solid(leds,NUM_LEDS,CRGB::Black);
      FastLED.show();
    }

    time = millis();
    }
    digitalWrite(outPin,state);
    previous = readingTwo;

//  BUTTON 3  - MOVEMENT SENSOR LIGHT
       readingThree = digitalRead(inPinThree);
  if (readingThree == HIGH && previous == LOW && millis() - time> debounce){
    if(state == HIGH){
      state = LOW;
       fill_solid(leds,NUM_LEDS,CRGB::Black);
        FastLED.show();
      }
    else{
      state = HIGH;

    }

    time = millis();
    }
    digitalWrite(outPin,state);
    previous = readingThree;
}

//glitter effect
void addGlitter( fract8 chanceOfGlitter) {
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;}
}

The issue - the function seems to be only ran once (see button 2), which doesn't achieve the required effect.  I realize that changing this if statement to a while statement would be beneficial, but I cannot figure out how to break out of this while loop upon button press.  I know that setting state = LOW will break the while loop but if I leave it in, the light sequence function never runs.
//  BUTTON 2
   readingTwo = digitalRead(inPinTwo);
  if (readingTwo == HIGH && previousTwo == LOW && millis() - time> debounce){
    while(state == HIGH){
//      state = LOW;
      fadeToBlackBy( leds, NUM_LEDS, 10);
      addGlitter(30);
      FastLED.show();
  }

    while(state == LOW){
      state = HIGH;

      fill_solid(leds,NUM_LEDS,CRGB::Black);
        FastLED.show();

    }

Any help would be greatly appreciated!

do all of the button reading, debouncing and processing at the beginning of the loop() block .... keep track of the current state and the previous state (use the button presses to change the state variables .... run the LED control blocks depending on the state variables

I already use the button presses to change the state variables and the LEDS depending on them.  Maybe I misunderstand your comment?

read the comment up to the first ....

this rough idea uses only one button ... read button only at begining of loop() ... expand it to your liking with more buttons ....use a state variable with 6 states ... in setup state = 1 ... at beginning of loop() read button ... if it is pressed then increment state ... now the LEDs ... if state==1, run button1 code ... if state==2, run button1.else code and set state=3 ... if state==3, run button2 code ... if state==4, run button2.else code and set state=5 .... similarly for the rest of the code

thanks for expanding your comment jsotola.  I'll test it out and post progress.

I added int btnPress which gets set on each button press.  Then an if statement runs according to btnPress number.  Thanks jsotola for the point in the right direction!
#include "FastLED.h"

int inPin = 8;         // the number of the input pin
int inPinTwo = 9;
int inPinThree = 10;
int outPin = 13;       // the number of the output pin

int state = HIGH;      // the current state of the output pin

int reading;           // the current reading from the input pin
int readingTwo;
int readingThree;
int previous = LOW;    // the previous reading from the input pin
int previousTwo = LOW;
int previousThree = LOW;
volatile int change;
int btnPress;

int pixelNumber;

long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

//NEOPIXEL
#define LED_PIN     7
#define LEDPIN 7
#define LED_TYPE     NEOPIXEL
#define NUM_LEDS    2
#define BRIGHTNESS 255
#define FRAMES_PER_SECOND 60
CRGB leds[NUM_LEDS];
#define COLOR_ORDER GRB
#define CHIPSET     WS2812B

void setup()
{

//BUTTON
  pinMode(inPin, INPUT);
  pinMode(inPinTwo,INPUT);
  pinMode(inPinThree,INPUT);
  pinMode(outPin, OUTPUT);

  Serial.begin(9600);

  // set up LED strip info
FastLED.addLeds<LED_TYPE,LEDPIN>(leds,NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
btnPress = 1;

}

void loop()
{
//    BUTTON 1 - SOLID LIGHT
  reading = digitalRead(inPin);
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH){
      state = LOW;
      btnPress = 1;
    }
    else{
      state = HIGH;
      btnPress = 2;
      }

    time = millis();

  }
    digitalWrite(outPin, state);
    previous = reading;

//  BUTTON 2 - GLITTER LIGHT
   readingTwo = digitalRead(inPinTwo);
  if (readingTwo == HIGH && previousTwo == LOW && millis() - time> debounce){
    if(state == HIGH){
      state = LOW;
      btnPress = 3;
      }
    else{
      state = HIGH;
      btnPress = 4;
    }
    time = millis();
    }
    digitalWrite(outPin,state);
    previousTwo = readingTwo;

//  BUTTON 3  - MOVEMENT SENSOR LIGHT
       readingThree = digitalRead(inPinThree);
  if (readingThree == HIGH && previousThree == LOW && millis() - time> debounce){
    if(state == HIGH){
      state = LOW;
       btnPress = 5;
      }
    else{
      state = HIGH;
      btnPress = 6;
    }

    time = millis();
    }
    digitalWrite(outPin,state);
    previousThree = readingThree;

    //BUTTON 1 - SOLID LIGHT
     if (btnPress == 1){
          fill_solid(leds,NUM_LEDS,CRGB::Black);
          FastLED.show();Serial.println("pressed1");
      }

    if (btnPress == 2){
          fill_solid(leds,NUM_LEDS,0xFfffff);
          FastLED.show();Serial.println("pressed2");

      }

    //  BUTTON 2 - GLITTER LIGHT
    if (btnPress == 3){
            fill_solid(leds,NUM_LEDS,CRGB::Black);
          FastLED.show();Serial.println("pressed3");

      }
    if (btnPress == 4){
         fadeToBlackBy( leds, NUM_LEDS, 10);
          addGlitter(30);Serial.println("pressed4");
          FastLED.show();
      }

    //  BUTTON 3  - MOVEMENT SENSOR LIGHT
    if (btnPress == 5){
            fill_solid(leds,NUM_LEDS,CRGB::Black);Serial.println("pressed5");
          FastLED.show();

      }
    if (btnPress == 6){
        Serial.println("pressed6");
      }
  }

//glitter effect
void addGlitter( fract8 chanceOfGlitter) {
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;}
}

source: Stack Exchange

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

sort: votes


text:
MPU-6050 showing all -1s
I am following this tutorial and have an MPU-6050 connected to an Arduino Micro with the following connections

VCC - 5V/3.3V
  GND - GND
  SDA - A2
  SCL - A3

I'm trying to run the short example sketch:
// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain
#include <Wire.h>
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
}

void loop(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  Serial.print("AcX = "); Serial.print(AcX);
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);
  delay(333);
}

But the output keeps showing -1 for all the fields.
Are these values actually correct or am I doing something wrong?

Are you sure, that the address is correct? You can use the I2C Scanner sketch to test, under what address the MPU can be found

the -1 is the same as a binary 11111111 ... that means that the data line never changes

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


text:
Wiring ESP8266 and PN532
I'm trying the Android Hce example in this PN532 library. I can't find how to set SDA and SCL address in the code, so I tried connecting them in CLK and SD0 pins. The serial monitor gives me "Didn't find PN53x board". Can someone help me?
    #if 0
      #include <SPI.h>
      #include <PN532_SPI.h>
      #include "PN532.h"

      PN532_SPI pn532spi(SPI, 10);
      PN532 nfc(pn532spi);
    #elif 1
      #include <PN532_HSU.h>
      #include <PN532.h>

      PN532_HSU pn532hsu(Serial1);
      PN532 nfc(pn532hsu);
    #else
      #include <Wire.h>
      #include <PN532_I2C.h>
      #include <PN532.h>
    #endif

    void setup()
    {
        Serial.begin(115200);
        Serial.println("-------Peer to Peer HCE--------");

        nfc.begin();

        uint32_t versiondata = nfc.getFirmwareVersion();
        if (! versiondata) {
          Serial.print("Didn't find PN53x board");
          while (1); // halt
        }

        // Got ok data, print it out!
        Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
        Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
        Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

        // Set the max number of retry attempts to read from a card
        // This prevents us from waiting forever for a card, which is
        // the default behaviour of the PN532.
        //nfc.setPassiveActivationRetries(0xFF);

        // configure board to read RFID tags
        nfc.SAMConfig();
    }

    void loop()
    {
      bool success;

      uint8_t responseLength = 32;

      Serial.println("Waiting for an ISO14443A card");

      // set shield to inListPassiveTarget
      success = nfc.inListPassiveTarget();

      if(success) {

         Serial.println("Found something!");

        uint8_t selectApdu[] = { 0x00, /* CLA */
                                  0xA4, /* INS */
                                  0x04, /* P1  */
                                  0x00, /* P2  */
                                  0x07, /* Length of AID  */
                                  0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* AID defined on Android App */
                                  0x00  /* Le  */ };

        uint8_t response[32];

        success = nfc.inDataExchange(selectApdu, sizeof(selectApdu), response, &responseLength);

        if(success) {

          Serial.print("responseLength: "); Serial.println(responseLength);

          nfc.PrintHexChar(response, responseLength);

          do {
            uint8_t apdu[] = "Hello from Arduino";
            uint8_t back[32];
            uint8_t length = 32;

            success = nfc.inDataExchange(apdu, sizeof(apdu), back, &length);

            if(success) {

              Serial.print("responseLength: "); Serial.println(length);

              nfc.PrintHexChar(back, length);
            }
            else {

              Serial.println("Broken connection?");
            }
          }
          while(success);
        }
        else {

          Serial.println("Failed sending SELECT AID");
        }
      }
      else {

        Serial.println("Didn't find anything!");
      }

      delay(1000);
    }

    void printResponse(uint8_t *response, uint8_t responseLength) {

       String respBuffer;

        for (int i = 0; i < responseLength; i++) {

          if (response[i] < 0x10)
            respBuffer = respBuffer + "0"; //Adds leading zeros if hex value is smaller than 0x10

          respBuffer = respBuffer + String(response[i], HEX) + " ";
        }

        Serial.print("response: "); Serial.println(respBuffer);
    }

    void setupNFC() {

      nfc.begin();

      uint32_t versiondata = nfc.getFirmwareVersion();
      if (! versiondata) {
        Serial.print("Didn't find PN53x board");
        while (1); // halt
      }

      // Got ok data, print it out!
      Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
      Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
      Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

      // configure board to read RFID tags
      nfc.SAMConfig();
    }

For I2C the default pins to use are whatever are defined in your board configuration - probably pins 4 and 5 (to mirror A4 and A5 on the Uno). However your code is set up to use serial, not I2C.

I was doubting so, can you please tell me the exact wiring for serial? (Or for anything to make this code work). I'd like to even know how to get these information, usually I find the pinout in the define section (how should be done)

For serial connect it to the UART1 TX and RX pins. Where those are depends on what module you have.

I have connected SCK to CLK (on ESP8266), MSO and MOSI connected to D6 and D7. How should I set up this in code? I tried to changing SPI, but it doesn't work

What you wire to where, and what code you use, depends on what PN532 module you have and what ESP8266 module you have.

I have Elechouse PN532 Module V3 and a NodeMCU

This one?

Solved. Set #if 1 and #elif 0.
Connected:
SCK to D5
MISO to D6
MOSI to D7
SS to D0 (and set it on pn532spi)


text:
pulseIn only returning 0
I'm new to arduino and I've searched through a lot of posts but can't find anything to fix the issue.
I'm trying to send a signal through some medium (water in this example) using a pizoelectric transducer and measure the time it takes for the signal to go from transducer to the other.
Attached is an image of the setup. Below is the code.
const int trigPin = 1;
const int echoPin = 0;
float duration;

void setup() {
  pinMode (trigPin, OUTPUT);
  pinMode (echoPin, INPUT);
  Serial.begin (9600);
}

void loop() {
  // set transmitting pin to low
  digitalWrite (trigPin, LOW);
  delayMicroseconds (2);

  // send the signal
  digitalWrite(trigPin, HIGH);
  digitalWrite (trigPin, LOW);

  // read in the signal on receiving pin, print duration to the Monitor
  duration = pulseIn (echoPin, HIGH);
  Serial.print("duration: ");
  Serial.print(duration);
  Serial.print("\n");
}

The issue is "duration" variable has been 0 in all of my tests. I've tried using various values for the timeout parameter in pulsIn to no avail. Any advice is appreciated.

There are a few issues here.
The most obvious is that you are using the wrong pins. On the Arduino
Uno, digital 0 is the serial RX pin, and digital 1 is TX. Thus, if you
use Serial in your sketch, you cannot use these pins for anything
else.
At a more fundamental level, it looks from your picture that you have
connected your Arduino to a couple of bare piezo transducers. Your code,
on the other hand, assumes the Arduino is connected to a digital sonar
module, like the very common HC-SR04. You have to keep in mind that
a piezo transducer is an analog device. The sonar module, on the other
hand contains quite a few electronic parts that take care of
conditioning the analog signals and providing an easy to use digital
interface, where you just have to call pulseIn() to get the
measurement.
If you want to use the bare piezo transducers, the first thing you have
to do is read their datasheet. This is really essential. Once you have
read (and understood) that document, you can figure out whether or not
you need some interface electronics between the piezos and your Arduino.
Maybe you can get away with exciting the transmitter with PWM and
reading the receiver with the on-board ADC. Or maybe not. First read the
datasheet, then design your circuit, then test using a scope to look at
your signals.


text:
Can the following materials be used to power up an attendance based sensor?
arduino uno, esp8266, rfid module rc522, sd card module, real time clock module, buzzer, led light and battery holder. I was planning to build a sensor that monitors attendance with the use of and RFID card, and I was planning to make it run on its own with the help of a battery instead of being connected to a computer. If not, is there another way that would be possible?

you only need a power supply to power up a sensor ... if you want to read data from the sensor, then you need a power supply,  an arduino and a sensor.... if you want to store the resulting data, then you need to add an SD card module ... if you want to add functionality, then you need to add a module for that functionality

start development with power supply, arduino and sensor

Possible? Yes, totally possible. You won't get really better answers with such a broad question. If this question is mainly about power, then we would need to know, what type of battery you want to use and also how you want to connect it (and everything else, since the Uno is 5V and an ESP is 3.3V)

I'm really new to this so I don't have much knowledge. I was thinking of using a 2 AA batteries connected to a battery holder to power it up because I heard that it would help it last long.

or using a 9 volt battery


text:
Can a pin be Neutral, not high or low?
I'm trying to figure out a way to controll a DFplayer mini mp3 player with ADkeys.
Because I only have two or three files to play at a fixed volume I find it easier to just use the ADkeys. https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299#target_4

Lets say I want to use Segment 1 - Segment 3 (MP3 file 1 - MP3 file 3). I would then connect a resistor (or none in Segment 1) in between and to three pins on the Arduino.
But how can I make the pin neutral, so that it does not trigger everything at once?
As far as I can read the pins are grounded in Arduino if not "high".

You mean “high impedance”?

@EdgarBonet I was thinking as high as there is 5 volt, and low as grounded. Sorry for the confusion.

What you are talking about in this instance is "Open Drain".  Normally, as you rightly note, with outputs you have either HIGH or LOW, which effectively connects the output pin to +5V or GND respectively.
Instead you are asking for Open Drain.  In this arrangement a pin is either "active", in which case it connects it to GND, or "inactive", in which case it is disconnected from (almost) anything.
Most 8-bit Arduino boards don't have Open Drain capability on their IO pins (some more advanced 32-bit boards do, though), but it is easy enough to emulate it in software.
You can emulate it using "Tri-State" logic.  That is logic where, as well as HIGH and LOW you have "High Impedance", or "HI-Z".  HI-Z is pretty much the same as "inactive" Open Drain. On the Arduino HI-Z is the same as INPUT.
So you can emulate it by:

To activate a pin set it to OUTPUT and LOW
To deactivate a pin set it to INPUT

For example, to "press" one of your buttons for 100ms you could:
pinMode(4, OUTPUT);
digitalWrite(4, LOW);
delay(100);
pinMode(4, INPUT);

I see! So setting the pin to input means it's waiting for input thus is neither. That's clever!

@Andreas Actually technically the pin is always "waiting" for input. Setting it to INPUT mode just turns off the output driver circuitry and allows it to "see" the outside world.

Your drawing appears to be attempting to provide analog levels to the DF miniplayer.
What you can do in that case is use two PWM outputs from the Arduino, with a RC lowpass filter to smooth the PWM into a DC level. (Arduino pin to 10K resistor, 4.7uF cap to gnd after that, the cap/resistor junction going to the DF Miniplayer).
Then
analogWrite(pin, 128); // with pin being 3,5,6,9,10,11 on a Uno for example

to output 2.5V to the DF Miniplayer.
Similarly, 64 would be about 1.25V, while 192 would be about 3.75V.
Other levels are easily obtained.

Thank you for your answer but I believe you missed something. It's ground that the circuit is connected to, not a positive end. Or did I misunderstand you?

The DF Miniplayer has some internal pullup resistor, yes? So connecting different value resistors from the pin to Gnd via switch creates a voltage divider and results in different voltages at the pin. How is that different  than driving the pin with a voltage directly? Setup a few resistors, measure the voltage when pressed.  See 3.5 of the Manual to see what buttons do  https://github.com/Arduinolibrary/DFPlayer_Mini_mp3/raw/master/DFPlayer%20Mini%20Manual.pdf

To be honest I dont know. I don't have a clue what the internals are and how that is different. I don't have the knowledge. I can see a benefit of your answer if it works, but since I only need two or three then I'm fine with just using separate pins.


text:
Communicate between 3 nodeMCU
How should I verify the communication between three node MCUs where one behaves as server and the other two as clients such that data of each node mcu is obtained on all three?

you would verify the communication by transmitting pre determined data ... if the data arrives correctly, then the communication is working correctly ... if the data is incorrect, then the communication has an issue

communication between 3 nodemcu can be done instead dont assume one nodemcu as server other two as client. Mqtt is a message protocol which is used to transfer messages. Connect all the three nodemcus in the same network and host a mqtt server separately in the same network. Mqtt has to flexibility to send data from one nodemcu to other nodemcus which are in the same network. Publish and subscribe method can be used to get data or post data.
Go through this link
http://mqtt.org/

i want to communicate using the IPs of the nodemcu and not by the mqtt protocol.


text:
Sim808 module HTTP Bad request
I have an Arduino UNO and sim808 EVB-V3.02.4.
I want to send a GET request to my url but I always receive 400 Http bad request error.
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

#define PIN_TX    7
#define PIN_RX    8
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

char http_cmd[] = "GET /index.php?lat=10&long=100 HTTP/1.0\r\n\r\n";
char buffer[512];

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

void loop() {
  //*********** Attempt DHCP *******************
  while(!sim808.join(F("cmnet"))) {
      Serial.println("Sim808 join network error");
      delay(2000);
  }

  //************ Successful DHCP ****************
  Serial.print("IP Address is ");
  Serial.println(sim808.getIPAddress());

  //*********** Establish a TCP connection ************
  while(!sim808.connect(TCP,"39c309ae.ngrok.io", 80)) {
      Serial.println("Connect error");
  }
  Serial.println("Connection success");

  //*********** Send a GET request *****************
  Serial.println("waiting to fetch...");
  sim808.send(http_cmd, sizeof(http_cmd)-1);
  while (true) {
      int ret = sim808.recv(buffer, sizeof(buffer)-1);
      if (ret <= 0){
          Serial.println("fetch over...");
          break;
      }
      buffer[ret] = '\0';
      Serial.print("Recv: ");
      Serial.print(ret);
      Serial.print(" bytes: ");
      Serial.println(buffer);
      break;
  }

  //************* Close TCP or UDP connections **********
  sim808.close();

  //*** Disconnect wireless connection, Close Moving Scene *******
  sim808.disconnect();
  delay(5000);
  }

My php code:
<?php
file_put_contents('test.txt', $_GET['lat'] . '---' . $_GET['lon']);
print '
<html>
<head>
<title>Good</title>
</head>
<body>
Was Good
</body>
</html>
';
?>

I want just open http://39c309ae.ngrok.io/index.php?lat=10&long=100 with arduino and sim808.
What is wrong in my codes?

You aren't sending the Host: header with your request.  Without that the web server has no idea which website you want to get the /index.php page from.
char http_cmd[] = "GET /index.php?lat=10&long=100 HTTP/1.0\r\n"
                  "Host: 39c309ae.ngrok.io\r\n"
                  "\r\n";

nice worked! thanks a lot! becuse of low mine low reputation i can not flag your question for best answer! anyway , thanks


text:
How to manage two alarms with one interrupt?
I have a datalogger using the RTC DS3231 as an interrupt generator. I am able to have the interrupts work but here is my problem. I would like to take 2 separate measures from 2 different sensors (one for humidity, temperature and the other for accelerations), one every 30 min et one every hour, the thing is that because I use the same pin (only one pin from the DS3231) for both of these alarms I cannot use a simple counter in my interrupt function otherwise one measure will not be taken when both of the alarms will trigger...
For example I just did a quick test with one alarm each min when seconds are 00 and an other alarm each minute when seconds are 20. The problem as I said is that I cannot increment counters for each since I use the same interrupt function (because of the single pin).
Here is my loop function and interrupt handling function :

void loop() {
  delay(1000);
  sleepNow();
  if (alarm == true){
    handleAlarm(); // reset the possibility to trigger alarm
    if (counter_dtphl == COUNT_DTPHL){
      take_measure_DTPHL();
      counter_dtphl = 0;
    }
    else if (counter_accel == COUNT_ACCEL){
      take_measure_ACCEL();
      counter_accel = 0;
    }
  }
}

void wakeUpNow() {
  Serial.println("In wake up now");
  delay(100);
  alarm = true;
  //Serial.println(counter);
  sleep_disable();//Disable sleep mode
  byte sec = get_date(SEC);
  Serial.println(sec);
  if (sec == 0){
  counter_dtphl +=1;
  }
  else if (sec == 30){
  counter_accel +=1;
  }
  detachInterrupt(digitalPinToInterrupt(interruptPin)); //Removes the interrupt from pin 2;
}

void handleAlarm() {
  alarm = false;
  rtcObject.LatchAlarmsTriggeredFlags();
}

COUNT_ACCEL and COUNT_DTPHL are constant having the value of minutes corresponding to the trigger for the measure.
Has anybody an idea how to manage this situation ?
For the acceleration I need to save the data for a period of 30 sec. One solution I tried is to increment the counter according to the time in second that corresponds each minute but I cannot put it in the wakeUpNow function since only fast processing should be done there (it is the function executed by the interrupt).
Thank you for your time !

what else does the sketch? why do you need RTC as timer? you can do something every 30 min with millis()

why would you need two interrupts for an action that occurs every 30 minutes?

Hello, I need a RTC as timer because the data logger will be an embedded system and the consumption is a key factor for this project. Thus, I cannot let it run with a simple millis() because I am powering down the card all the time and wake it up with alarm interrupt of DS3231.

Consider it is good practice to leave as little code in an interrupt as possible.  In this case, as the time in question is much greater then how often the loop() function is called, setting a single flag indicating an interrupt occurred would be sufficient.
Each time in your loop() function test for this flag.  If TRUE, immediately set it to FALSE so as not forget to do so later.  Next, while still in the scope of the IF statement, assuming the RTC DS3231 has been configured to create an interrupt every 30 minutes, take your "30 minute sample".  Next, while still in the scope of the IF statement, increment a counter.  Make sure this counter is defined as a global variable in order to persist between calls to the loop() function.  If this counter has reached the value of 2, clear this counter to zero and take your "60 minute sample".
Consider the following pseudo code:
// Global variable defined outside of functions to track state & time.
bool state_interrupts;
int counter_interrupts;

void setup()
{
  // Initialize RTC to generate an interrupt once every 30 minutes.
  <RTC initialization code.>
  // Call attach interrupt to identify interrupt function name "wakeUpNow".
  attachInterrupt(...)
  // Initialize state & counter;
  interrupts_state = false;
  interrupts_counter = 0;
}

void loop()
{
  // Check if interrupt occurred.
  if(interrupts_state)
  {
    interrupts_state = false;
    interrupts_counter++;
    // Sample 30 minute sensor.
    <Sample 30 minute sensor code.>
    if(interrupts_counter >= 2)
    {
      interrupts_counter = 0;
      // Sample 60 minute sensor.
      <Sample 60 minute sensor code.>
    }
  }
}

void wakeUpNow()
{
    interrupts_state = true;
}

Hi and thank you for your answer. I already tried what you say but it doesn't work for my need. I need 2 different measures from 2 different sensors. One every 30 min et the other every hour. The thing is that there will be a conflict each hour between the calls since 30 min is half of an hour. So I cannot use a counter that way

@JamesONeil, are you sure you are not over thinking this?  Or is there a problem constraint that you have not told us about?  Yes, 2 different measurements from 2 sensors.  The interrupt DOES'NT SAMPLE ANYTHING!!! The interrupt only sets a flag indicating 30 minutes has passed.  YOUR CODE in the Loop function needs to keep track of the number of interrupts. Such that every time flag-set it samples the 30 minute sensor and every other time it samples the 60 minute sensor as well. REPEAT, the INTERRUPT DOES NOT SAMPLE ANY SENSORS!!! It's good practice to do as little as possible in interrupts!

@JamesONeil, since you made the effort to edit / improve your question, I added pseudo code to my answer to make the proposed solution easier to understand.

Hi ! Sorry for late answer I managed to have it worked the way I wanted :) Thank you for your pseudo code it is a good way also to solve my problem !

"Initialize RTC to generate an interrupt once every 30 minutes." doesn't look like it is an option from the A2M2 bit's table in  https://datasheets.maximintegrated.com/en/ds/DS3231.pdf  -- It looks like you can only trigger every minute or when the minutes match a particular number.  If you choose '30' you'll miss '00' & vice versa.  You could trigger each minute and count minutes interruptState = (++elapsedMinutes % 30 == 0);, or read the minutes and act accordingly.

The typical solution to this type of problem is:

In the ISR set a flag to indicate an RTC interrupt has occurred.
In the loop check the flag and if the set:
a) Read the alarm flags from the RTC,
b) Check the alarms, return value from LatchAlarmsTriggeredFlags(), and do the appropriate action.

What you should not do is write a lot of code in the ISR. Especially code that is also interrupt driven or depend on interrupts such as Wire, Serial, millis(), delay(), etc.
Cheers!

After the interrupt read the time from the RTC and then do the correct thing based on the result.

Try this:
bool x = true; This is before setup
bool done = false;
x = !x;  Do this in the interrupt function.
done = true;
this is in your loop!
if done == true{    // Determine if you have been here before
if X !true do both functions
else
do the 30 second one
I use the !X as it is faster.
done = false;}
This should give you an idea, I did not actually code this but i use code similar to this all the time. My goal is to do no more then 1 or two instructions in the interrupt service routine (ISR).


text:
How to read from multiple multiplexers (CD74HC4067) with a library
I need to read alot of buttons and analog inputs for my project (60 buttons 15 faders) and there fore need to use multiplexers. But most mux libraries seems to only support one mux, am i wrong?

It seems to me a library is a bit overkill for that IC, since you have 4 pins to define which input pin/channel will be used. Seems to me to send 4 digital writes to define the channel, an one analog read for getting the signal. So since you do not a library, you can control them all the way you want.

Which library? You should be able to use multuple instances, and there are libraries that have support for cascaded muxes.


text:
Problem sending IR signal on Arduino Leonardo/Uno (IRRemote library)
I am trying to use my Arduino Leonardo (or Uno!) as a remote with the IRRemote library. The current setup picks up and decodes a signal perfectly, but fails to retransmit it.
I have tested the infrared LED and it works.
I have tested the setup against a television IR receiver at very close range.
My board consists of:

I am using the example IRRecord code (included below) with one change -- I made STATUS_PIN P3 (instead of P13), as I read that P13 is used to transmit IR signal on the Leonardo. I made this change after testing all PWM pins (including P3) for transmitting the IR signal. I'd appreciate any help to get this working.
I have also tried this on an Arduino Uno to no effect. This is driving me a little crazy!
Code below.
/*
 * IRrecord: record and play back IR signals as a minimal
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * An IR LED must be connected to the output PWM pin 3.
 * A button must be connected to the input BUTTON_PIN; this is the
 * send button.
 * A visible LED can be connected to STATUS_PIN to provide status.
 *
 * The logic is:
 * If the button is pressed, send the IR code.
 * If an IR code is received, record it.
 *
 * Version 0.11 September, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 11;
int BUTTON_PIN = 12;
int STATUS_PIN = 3;

IRrecv irrecv(RECV_PIN);
IRsend irsend;

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(BUTTON_PIN, INPUT);
  pinMode(STATUS_PIN, OUTPUT);
}

// Storage for the recorded code
int codeType = -1; // The type of code
unsigned long codeValue; // The code value if not raw
unsigned int rawCodes[RAWBUF]; // The durations if raw
int codeLen; // The length of the code
int toggle = 0; // The RC5/6 toggle state

// Stores the code for later playback
// Most of this code is just logging
void storeCode(decode_results *results) {
  codeType = results->decode_type;
  int count = results->rawlen;
  if (codeType == UNKNOWN) {
    Serial.println("Received unknown code, saving as raw");
    codeLen = results->rawlen - 1;
    // To store raw codes:
    // Drop first value (gap)
    // Convert from ticks to microseconds
    // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
    for (int i = 1; i <= codeLen; i++) {
      if (i % 2) {
        // Mark
        rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
        Serial.print(" m");
      }
      else {
        // Space
        rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
        Serial.print(" s");
      }
      Serial.print(rawCodes[i - 1], DEC);
    }
    Serial.println("");
  }
  else {
    if (codeType == NEC) {
      Serial.print("Received NEC: ");
      if (results->value == REPEAT) {
        // Don't record a NEC repeat value as that's useless.
        Serial.println("repeat; ignoring.");
        return;
      }
    }
    else if (codeType == SONY) {
      Serial.print("Received SONY: ");
    }
    else if (codeType == PANASONIC) {
      Serial.print("Received PANASONIC: ");
    }
    else if (codeType == JVC) {
      Serial.print("Received JVC: ");
    }
    else if (codeType == RC5) {
      Serial.print("Received RC5: ");
    }
    else if (codeType == RC6) {
      Serial.print("Received RC6: ");
    }
    else {
      Serial.print("Unexpected codeType ");
      Serial.print(codeType, DEC);
      Serial.println("");
    }
    Serial.println(results->value, HEX);
    codeValue = results->value;
    codeLen = results->bits;
  }
}

void sendCode(int repeat) {
  if (codeType == NEC) {
    if (repeat) {
      irsend.sendNEC(REPEAT, codeLen);
      Serial.println("Sent NEC repeat");
    }
    else {
      irsend.sendNEC(codeValue, codeLen);
      Serial.print("Sent NEC ");
      Serial.println(codeValue, HEX);
    }
  }
  else if (codeType == SONY) {
    irsend.sendSony(codeValue, codeLen);
    Serial.print("Sent Sony ");
    Serial.println(codeValue, HEX);
  }
  else if (codeType == PANASONIC) {
    irsend.sendPanasonic(codeValue, codeLen);
    Serial.print("Sent Panasonic");
    Serial.println(codeValue, HEX);
  }
  else if (codeType == JVC) {
    irsend.sendPanasonic(codeValue, codeLen);
    Serial.print("Sent JVC");
    Serial.println(codeValue, HEX);
  }
  else if (codeType == RC5 || codeType == RC6) {
    if (!repeat) {
      // Flip the toggle bit for a new button press
      toggle = 1 - toggle;
    }
    // Put the toggle bit into the code to send
    codeValue = codeValue & ~(1 << (codeLen - 1));
    codeValue = codeValue | (toggle << (codeLen - 1));
    if (codeType == RC5) {
      Serial.print("Sent RC5 ");
      Serial.println(codeValue, HEX);
      irsend.sendRC5(codeValue, codeLen);
    }
    else {
      irsend.sendRC6(codeValue, codeLen);
      Serial.print("Sent RC6 ");
      Serial.println(codeValue, HEX);
    }
  }
  else if (codeType == UNKNOWN /* i.e. raw */) {
    // Assume 38 KHz
    irsend.sendRaw(rawCodes, codeLen, 38);
    delay(100);
    Serial.println("Sent raw");
  }
}

int lastButtonState;

void loop() {
  // If button pressed, send the code.
  int buttonState = digitalRead(BUTTON_PIN);
  if (lastButtonState == HIGH && buttonState == LOW) {
    Serial.println("Released");
    irrecv.enableIRIn(); // Re-enable receiver
  }

  if (buttonState) {
    Serial.println("Pressed, sending");
    digitalWrite(STATUS_PIN, HIGH);
    sendCode(lastButtonState == buttonState);
    digitalWrite(STATUS_PIN, LOW);
    delay(50); // Wait a bit between retransmissions
  }
  else if (irrecv.decode(&results)) {
    digitalWrite(STATUS_PIN, HIGH);
    storeCode(&results);
    irrecv.resume(); // resume receiver
    digitalWrite(STATUS_PIN, LOW);
  }
  lastButtonState = buttonState;
}

if you have another arduino, then use it to confirm that the transmitted data is same as the remote control

@jstotola I am using the code above to capture the signal from the TV's remote and then retransmit it from the Arduino to the TV. The capture component works perfectly, but it is not sending a signal -- any signal at all.

I measured voltage across the IR LED while holding down the signal button + looked through a digital camera to see if the LED lights up. I also tried supplementing the IR LED with a visible-light LED.


text:
Nodemcu POST Response "-1"
Nodemcu device is returning HTTP response -1 for a POST request on django rest api.
I tried the below http request to Postman, and it works perfectly fine.
http://localhost:8000/api/datalogs/?plant=http://localhost:8000/api/plants/1/&light=23&temperature=24&humidity=75&soil=Dry&moisture=787&remarks=/
This is my arduino post request:
if(WiFi.status() == WL_CONNECTED) {
    HTTPClient http;

    http.begin(host_url);

    http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    httpCode = http.POST(postData);

    payload = http.getString();
    http.end();
}

The expected result is 200, but I get -1. Can someone please explain?

the values of host_url and postData are not shown ... your code is sending unknown data .. therefore there is nothing to explain

you use the name "localhost" in the request from other device?

can you be more specific about the code on nodemcu side like what is the host_url and also postdata. At the same time update the code form Django side like what function is catching the http response from nodemcu.

Yes, thanks. I might be messing it with localhost, whereas my device has a different ip than my computer.. I should give it a try first Juraj

The host_url is http://localhost:8000 and the postData is "plant="+String(host)+"plants/1/&light="+String(lux)+"&temperature="+String(temperature)+"&humidity="+String(humidity)+"&soil="+mRes+"&moisture="+mVal+"&remarks=/";
I think the issue might be localhost jsotola

So, I tried using ip address, also configured from django settings, works perfectly from my mobile device, Insomnia REST API client. But Nodemcu returns 301 Moved Permanently.

if it returns 301 then only https is allowed so the url should use https://

So, I found the solution. It was a very simple mistake. The NodeMCU IP is not the same as the Computer IP that the server was running on.
I changed the localhost string with the IP of my pc, and it worked perfectly fine.


text:
2 buttons pressed at the same time elevator logic
I have currently created a working elevator code where the elevator goes up when pressed a button, and stops at a floor when the sensor senses that it has reached the floor. This is how it works:
#define Buzzer 5

#define pwmMot 6

#define halPin 8

#define butto1 9  //level 1
#define butto2 10 //level 2
#define butto3 11 //level 3

#define SeEcho 12
#define SeTrig 13

int button1_status = 0;
int button2_status = 0;
int button3_status = 0;

int current_level = 1;
int required_level =-1;

void setup(){
  Serial.begin(9600);
  pinMode(Buzzer, OUTPUT);
  digitalWrite(Buzzer, HIGH);
  pinMode(halPin, INPUT);
  pinMode(butto1, INPUT);
  pinMode(butto2, INPUT);
  pinMode(butto3, INPUT);
  pinMode(SeTrig, OUTPUT);
  pinMode(SeEcho, INPUT);
  pinMode(pwmMot, OUTPUT);
  Serial.println("you are in level 1");
}

void emergencyStop(){
  analogWrite(pwmMot, 255);
}
int sensor() {
  unsigned long duration;
  int distance;
  digitalWrite(SeTrig, LOW);
  delayMicroseconds(2);
  digitalWrite(SeTrig, HIGH);
  delayMicroseconds(5);
  digitalWrite(SeTrig,LOW);
  duration = pulseIn(SeEcho,HIGH);
  distance = int(duration/2/29.412);
  return distance;
}

bool hallSen(){
  return digitalRead(halPin);
}

int going_up(){
  while (sensor() > 12){
    analogWrite(pwmMot, 1600);
  }
  return 1;
}

int going_down(){
  while (sensor() > 12){
    analogWrite(pwmMot, 570);
  }
  return 1;
}

void loop() {
  button1_status = digitalRead(butto1);
  button2_status = digitalRead(butto2);
  button3_status = digitalRead(butto3);
  required_level = button1_status == HIGH ? 1 : button2_status == HIGH ? 2 : button3_status == HIGH ? 3 : -1;
  if (required_level != -1 && required_level != current_level){
    while (current_level != required_level){
      if (current_level > required_level) Serial.println("Going Down"), current_level-=going_down();
      else if (current_level< required_level) Serial.println("Going Up"), current_level+=going_up();
      Serial.print("you are in level "); Serial.println(current_level);
      delay(1000);
    }
    analogWrite(pwmMot, 1550); //stop elevator
    digitalWrite(Buzzer, LOW);
    delay(100);
    digitalWrite(Buzzer, HIGH);
    required_level = -1;
  }
}

Now I am just curious as to how I will extend this so that for example if we are in level 1, both the levels 2 and 3 are pressed it should go to level 2 even if level 3 was pressed first. Or if we are in level 2 and both level 1 and 3 are pressed, it should go to the one that is pressed first as both levels are the same distance from level 2.

when you are at floor 1 you can't just jump to floor 3 you have to pass level 2 first, if you have a sensor there you can simply do something like if button2 = high && sensor2 = high {do that} else... i see a state machine in your future!

definitely a state machine

@newbie use == instead of =

@MichelKeijzers right, i was just demonstrating...

there is no such thing as a "two buttons pressed" scenario as far as the microcontroller is concerned ... the microcontroller checks the buttons sequentially ... that means you have one of two scenarios

if we are in level 1, both the levels 2 and 3 are pressed it should go
  to level 2 even if level 3 was pressed first.

For this to work, the program should remember which buttons (mind the
plural!) have been pressed. Thus, instead of remembering only one
request, as in
int required_level =-1;

it should have a boolean variable for each of the possible levels,
telling us whether a stop was requested for that level.
For convenience, I would number the levels from zero, and hold these
variables in an array:
const int LEVEL_COUNT = 3;
bool requested_stop[LEVEL_COUNT];

if we are in level 2 and both level 1 and 3 are pressed, it should go
  to the one that is pressed first as both levels are the same distance
  from level 2.

The part I emphasized doesn't make sense to me. The elevator should go
to the one that was pressed first, irrespective of the distances.
Imagine you are in an elevator at level 5, and press the button for
level 2. As the elevator just starts moving down, another rider presses
the button for level 6. Should the elevator immediately revert to going
up in order to reach level 6, which is closer? Of course not. If it is
going down, it should continue in that direction. Now, if the other
rider presses 3, it should stop by level 3 on its way down, even though
you pressed 2 first.
As stated by chrisl in a comment, a finite state machine is
definitely the solution for this kind of problems. I propose a state
machine with three states, STOPPED, GOING_UP, and GOING_DOWN:

when STOPPED, it should change to GOING_UP or GOING_DOWN as soon
as a button for another level is pressed
when GOING_UP, as soon as it reaches a level that has been
requested, it should change to STOPPED
same thing when GOING_DOWN.

And here is my proposed implementation:
void loop() {
    // Check the buttons.
    for (int i = 0; i < LEVEL_COUNT; i++)
        if (digitalRead(button[i]) == HIGH)
            requested_stop[i] = true;

    // Finite state machine.
    static enum { STOPPED, GOING_UP, GOING_DOWN } state = STOPPED;
    switch (state) {
    case STOPPED:
        requested_stop[current_level] = false;
        for (int i = 0; i < LEVEL_COUNT; i++) {
            if (requested_stop[i]) {
                if (i < current_level) {
                    analogWrite(pwmMot, PWM_DOWN);
                    state = GOING_DOWN;
                    break;
                } else if (i > current_level) {
                    analogWrite(pwmMot, PWM_UP);
                    state = GOING_UP;
                    break;
                }
            }
        }
        break;
    case GOING_UP:
        if (elevator_height() >= LEVEL_HEIGHT[current_level + 1]) {
            current_level++;
            if (requested_stop[current_level]) {
                analogWrite(pwmMot, PWM_STOP);
                state = STOPPED;
            }
        }
        break;
    case GOING_DOWN:
        if (elevator_height() <= LEVEL_HEIGHT[current_level - 1]) {
            current_level--;
            if (requested_stop[current_level]) {
                analogWrite(pwmMot, PWM_STOP);
                state = STOPPED;
            }
        }
        break;
    }
}

This code assumes you have written the function elevator_height() that
measures the height of the elevator, and have defined an array of
constants LEVEL_HEIGHT[].
Notice that this is still far from perfect. You should probably ensure
that each stop lasts at least some minimum duration. Otherwise, if the
elevator stops at level 1 while level 0 has also been requested, the
stop will only last an instant. This can be achieved by splitting the
STOPPED state in two distinct states, and switching from “waiting for
the riders to go in/out” to “waiting for a button to be pressed” on a
timeout. You may also want to ensure that, after a stop, the elevator
continues in the same direction if possible. Otherwise it will never
reach level 2 if some joker is repeatedly pressing 0 and 1.

There is a sensor in the elevator and a sensor in each level so instead of the level height logic (we dont have the required sensor to measure the level height) cant we say if elevator sensor matches level sensor and button pressed there then stop?

@Utsav: Yes. You would just have to replace the condition elevator_height() >= LEVEL_HEIGHT[current_level+1] by elevator_is_sensed_at_level(current_level+1). And similarly for the test for current_level-1.


text:
How to make watchdog and automatically reset on esp8266
When my system is confronting at logical & hardwaretical problem,
I want to make system know It has some problem and reset automatically
because my esp8266(nodeMCU) is on the place where people usually cannot touch.
so I apply this 'ticker' code, but I think they are not working when it is on  problem status.
please see my code and give me some advice that how to make system know the problem status and do reset automatically.
//these are global values
Ticker ticker;
volatile unsigned int ISRcounter = 0;

void setup(){

ticker.attach(2,ISRdog);
//ticker always give Interrupt every 2 second.
//and when it get Interrupt, ISRdog function is called.
}

void ISRdog() {
  ISRcounter += 1;
//when ISR is called, ISRcounter is ++.

  if (ISRcounter == 10) {
    ESP.deepSleep(5e5); //reset
//and when it is 10, deepSleep for 5second and automatically wakeup.
//so it means, 'system reset'

  }

}

void loop(){

ISRcounter=0;
//when program running properly, system's flow always go to loop in final.
//so at the loop, make ISRcounter =0, for not making the system reset(ISRcounter==10)

.....
}

...and other functions ....

In short, this code is making reset until the system is not entering the  loop() over 20second.
so I expect when system get problem somehow, then system do not enter to the loop() and It means ISRcounter is getting 10, without =0. so system should be resetted.
but It did not worked. did not automatically resetted.

esp8266 always runs the watchdog

by iteself without my code? I saw. but when it resetted like that, it do not rework properly I think. for example, spreading wifi signal as a server...


text:
Reset arduino nano after disabling tx/rx
I know, i am a bit dummy sometimes and i don't know why i actually did this but here it is. I have an arduino nano and i want it to use an external power via the the Vin port using a 12V external power supply. I thought this would be as simple as replacing the usb power supply by my external 12V power supply on the Vin pin.
But nothing works so i did some digging on the problem and after many tries like soldering the pins 25 and 26 of the FTDI or connect the TX/RX pins to the GND. Concerning that last point, because the TX/RX was still flashing after beeing connected to the GND i have put in my program this two lines to force TX/RX to be disabled and this is my mistake :
digitalWrite(0,LOW);
digitalWrite(1,LOW);

And now what a surprise i can't load a program in my arduino nano anymore even using another arduino to burn the bootloader. And i get this message :
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x30
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x2e
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x30
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x30
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x2c
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x33
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x38
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x2e
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x33
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x31

I would like to come back to my factory arduino nano and/or enable once again the TX/RX connections ...

it is not the problem of the code. if you reset the Nano the bootloader runs for 2 seconds and has UART setup correctly and not affected by setup() of your sketch. so remove wires from RX and TX pin

Nothing is plugged on RX and TX pins

After some more tries something actually worked reinitialising the TX/RX pins, but i don't know why really. I wired RX pin to the reset and i loaded an empty code into the arduino, after that i was able to load any program into my arduino again. Problem solved, but why it solved the problem is the question now.

please do not use an "answer" to post a comment

post a new question about it ... include the sketch that "broke" the arduino

You could also do this: in the IDE, select File:Preferences and turn on Verbose outputs.
Press & hold reset, that puts all the IO pins into Inputs, then start a download.
When the compiler process shows "compilation complete, xxxxxx bytes of 32xxx used" or similar, release the Reset button.
That allows the bootloader code to run and talk to the PC over the serial pins - before your sketch has chance to run and write the 2 serial pins low.
It might take a couple of tries to release Reset at the correct time. Be patient try a few times with just a short sketch to clear out the offending code:
void setup();
void loop();

That would do it.


text:
How can I program a ATmega328 au tqfp32 ( SMD ) chip?
I have some experience with the Arduino UNO , Nano , mega etc .. But today I want to upgrade my skills and knowledge to next level . So I am about to design my own PCB for ATmega328 au ( SMD ) but this time I want to use a tqfp32 programmer to get the job done .. I have searched the internet and I have found that people use Universal programmers ( ISP ) such as Top2013 universal programmer or TL86ii but I have no idea how to use them and I don't even know what  software that the youtubers are using ... They are actually uploading some *.hex files it seems I am not sure but they aren't using Arduino IDE . According to my knowledge they are using a tqfp32 to dip28 programming module ( I have attached a pic ) . And then the Module is mounted on top of the ISP . Then they have uploaded code using some unknown software. And few people are using USBasp , can any explain me the scenario and what they have done ..  https://youtu.be/GFyr9tVEHzQ
The link is a reference video .

Please add more info to your question on how this will be used in relation to Arduino. Thanks.

The link to the video in your question is of a "promotional" nature (TQFP32 to DIP 28 converter Zif socket). If you want to know more about their product, click the "SHOW MORE" link. This network is for Arduino questions, not questions about the TQFP32.

To upload compiled code (.hex) to a bare atmega which doesn't have a bootloader installed you can use ISP. As this stands for in-system-programming you don't have to flash the chip before assembly, but you can flash it in-system, so when already soldered onto your pcb. There actually is no need for those adapters like shown in your first picture, which often are a bit expensive. Also, both pictures stand in contrast to the idea of ISP, they seem to show firmware upload via serial connection, which as far as I know only works with a bootloader already installed...
ISP is based on SPI (serial peripheral interface) and you need to break out the corresponding pins to fit this connector. This obviously has the advantage of being able to update a firmware afterwards without the need of a bootloader.
Atmel provides a tool for flashing firmware via ISP which is called avrdude (tutorial) or you can use the atmel studio. To compile your code, you can use avr-gcc.

I use Atmel AVR ISP MKii, which is a dedicated Programmer - it connects via USB to the PC, and to the Power/Gnd/Reset/SCK/MOSI/MISO pins of the SMD device (i.e. the pins that connect to an ICSP header if one were installed).  Then in the IDE you can select Upload Using Programmer, and it will load the .hex file that is created as part of the IDE compilation process into the chip.  This blows away any bootloader that might exist.
The Arduino as ISP does the same, running a sketch on an Uno for example that then interfaces with the PC and the target device to program it via the ICSP connection.
If the pins are not brought to a header, but are accessible via edge connecters, than a Programmer adapter can be used to connect the Programmer to the desired pins.  Imagine this board had a SMD package vs a DIP - then the 6 wires are connected to the desired pins, in this case via flying wires, and programming can be done.  A FTDI module is connected to other pins (5V, Gnd, DTR, Tx, Rx) just to provide power to the board. The AVR ISP MKii only monitors the power level in use (generally 3.3V or 5V) and adjusts its output levels accordingly.

The TQFP socket you show would generally be used to pre-program chips in a manufacturing type environment before they are installed on boards, or by a distributor like Digikey if you were ordering a large quantity of parts.
Making the ICSP pins accessible on board somehow is often not hard, and can be beneficial for making changes.
Here is an example of the same chip in a TQFP package, and you can see the dedicated ICSP and FTDI headers to allow onboard bootloading and then Serial downloads of code being developed.

I find the dedicated hardware very convenient as I bootload and/or program a lot of boards and SMD chips on boards.
I also have this adapter for Atmega328P chips that are installed on a board.  There are 6 little spring-loaded pins that press down onto the chip's ICSP pins from above to allow programming when an ICSP header is not provided, or the signals are not brought out to accessible pins. Unfortunately, hobbyking.com does not stock them anymore, this has gotten me out of a jam on occasion.

Do you have the name of that last item with the spring-loaded pins?

I got it from hobbyking.com. I don't see it listed there now, and I haven't found it anywhere else online. Which is too bad, it's a nice tool to have.

This is the closest I could find http://www.diagnosys.com/DTI/41-0191.PDF Dated 2014 CLIP 41-0191 I don't see a way to buy one tho.


text:
Is it support to use Infrared radiation module in ESP12E?

I have a IR module -->image as shown
is it possible to use the IR module in esp8266?
how to do(sent and receive)?
what is the packet format of IR module?
please explain.
Thanks

is it possible to use the IR module in esp8266?

Yes.

how to do(sent and recive)?

You send by pressing a button on your remote control. You receive by measuring the timing of the changes in the pin state.

what is the packet format of IR module?

Whatever packet format your remote control sends.
It's no different using IR on an ESP8266 compared to an Arduino. There's a library that everyone uses (IRRemote.h), and there are plenty of examples and tutorials on the web (or on YouTube if you can't be bothered to read). I suggest you ask Google for some.


text:
Why do most arduino function return a -1 instead of a 0
Many arduino functions return -1 if something 'fails'. Serial.read for example returns -1 or the infamous ÿ when this function is called while the serial buffer is empty.
As embedded C progammer, I am personally a fan of letting functions return data in the form of modifying pointers which points to passed on addresses and return states with the actual return functionality of a function. I am used to return a 0 if a function is 'not done' or 'failed'.
I see no logic in why many arduino functions return an int type which contains -1 instead of just a 0.
Would it not be better to let functions return a boolean type or an unsigned char type in which false or '0' would indicate a 'failed' process and true or '1' would indicate a 'succesful' process?
Also: if I type:
if(Serial.read()) {/* body */ }
and Serial.read() returns -1 because the buffer is empty. Will the If's body be executed or not?

how would you return a byte with value 0 from read() if 0 would indicate error?

@Juraj I realized that Serial.read() was perhaps a very poor example as this function returns  both return values as a state (-1). Perhaps that Serial.begin() would be a better example

I cannot assert anything for sure, as I was not involved in the design
of the Arduino APIs. However, just like Elliot Alderson, I suspect this
was inspired by the traditional C APIs. The manual page for getchar(),
which is a very old function from the standard C library, states:

fgetc(),  getc() and getchar() return the character read
  as an unsigned char cast to an int or EOF on end of file or
  error.

Given that EOF is usually defined as -1, this is consistent with the
behavior of Serial.read().
Being beginner-friendly is also a major goal of the API. Pointers are
known to be a huge difficulty for beginners.
There may also be some efficiency considerations involved. Arduino
started on the AVR platform. This is a RISC architecture, with a large
number of generic CPU registers (namely 32). The compiler usually
manages to allocate most local variables to registers. The calling
convention ensures that in most cases function parameters and return
values also go through CPU registers. This means we can avoid many RAM
accesses, which are inherently much slower than register access. Using a
return-by-pointer convention defeats these optimizations.
Lastly, it is a good thing that simple things are easy to write. For
example, an interpreter for single-character commands can be very easily
written as:
switch (Serial.read()) {
case 'a':
    do_command_a();
    break;
case 'b':
    do_command_b();
    break;
// etc...
}

with no need to explicitly test for the serial buffer not being empty.
Obviously, a more complex command language will need a full-blown
interpreter, but the focus of Arduino has always been on simple
programs being easy to write.

Arduino API is port of Processing. Processing is Java API to communicate with a MCU running Firmata. Arduino enabled sketches with the same API to run directly on the MCU.
So for example stream functions from Java stream classes were ported to Arduino API. This includes the read() function, to read one byte. Of course Java and Java basic libraries have inspiration in C++.
For other read and write functions, if the return value is count of bytes written or read then 0 is a valid return value and -1 indicates error.
Processing, Wiring and Arduino were created by interactive arts teachers and students, not by embedded systems developers. So you can't wonder about not ideal data types used. Later some things were improved by software developers.

as embedded C developer you should know that:

0 is a valid value to read, so it can't be a value indicating error
'if' executes if the evaluated value is not 0

How does this answer the question? You didn't say anything about return values.

sorry, you are not familiar with the Java read function.. I added a link to JavaDoc of Java read() function. and I addressed the thought error of OP about the error return value of read() in a comment

In an Arduino forum I think you should assume that readers are not familiar with Java. Also, could you include the important information directly in your answer, just in case the link breaks some day?

So to get to the heart of the matter, can you explain why (if in fact it is true) Java functions return -1 instead of 1 (or True) for an error condition? I mean even those functions that are not returning a byte value, but only a pass/fail indication.

@ElliotAlderson, that is explained in your answer :-). I have "inspired in C++", which is inspired in C...

if the return value is count of bytes written or read then 0 is a valid return value

I was unsure if if(something) would also be true, if something was signed AND negative. I hardly use signed value types at all.

Also, as 'embedded C developer' I do know that Serial.read() does not have to be interperted as a charachter. For all you know I use Serial.read() to read an array of numbers which also could contain 255

I suspect that this a legacy from Unix command programming, which was first done in C. For commands that only needed to return status and not data, a return value of zero meant success and any other return value indicated some kind of failure. Individual programmers could designate specific non-zero values for specific error types, if desired.
Remember that the return value comes back to the calling function in a register. And these days the term "Arduino" encompasses a broad range of architectures, including 32-bit ARM Cortex-M. Specifying that the return value is a char offers no advantage in this case.
The boolean datatype is a fairly recent addition to the C language, so it's not surprising that you don't see it used much in existing, portable libraries.
Returning an address from a simple function that just needs to indicate success or failure seems like overkill.
If you really want control over the datatypes, include stdint.h and use the types defined therein. If you want an unsigned 8-bit value use uint8_t and not unsigned char. If you want to allow the compiler to choose the best datatype that is at least 8 bits, use uint_fast8_tf.

-1 is returned when "0" would be a perfectly valid response.
To take your example of Serial.read(): 0 is a valid byte or ASCII character.  -1 isn't.  If you returned 0 for "failure" then there would be no way of differentiating between that and the valid byte value 0.

Are you sure that the Serial.read() can not return binary values rather than just ASCII? I can't find that in the documentation.

What is ASCII? It is just shapes that humans have decided to associate with numbers. Everything is numbers. The numbers 0-255 - and we have decided that certain ones of those numbers will represent letters in our minds. Serial.read() returns the byte that is next in the receive buffer. That byte is 0-255, and if we want 65 to mean "A" then we can. But if there's no byte to return from the receive buffer then something "not a byte" must be returned to mean "there's nuffink there, bruv!", and -1 is not a byte.

Ah, so the missing bit of information is that we are assuming that an int is defined to be bigger than 8 bits, and the Serial.read() returns an int rather than a char. A char value of 0xFF could be a valid return value, but an int of 0xFFFF is not.

That's not an assumption. It's a cold hard fact. An int will always be bigger than a byte.

Agreed, given an ANSI compiler. I shouldn't have said "assuming" I should have said "recognizing".


text:
Problem in fetching http get request after put float number
I have this codes that works correctly!
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

#define PIN_TX    7
#define PIN_RX    8
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,
char http_cmd[] = "GET /index.php?lat=*******&long=******* HTTP/1.0\r\n"
                        "Host: 04d1a36d.ngrok.io\r\n"
                        "\r\n";
char buffer[512];

void setup() {
  mySerial.begin(9600);
  Serial.begin(9600);
    while(!sim808.init())
  {
      Serial.print("Sim808 init error\r\n");
      delay(1000);
  }
  Serial.print("Sim808 init Success\r\n");
  delay(3000);

  //*********** Attempt DHCP *******************
  while(!sim808.join(F("cmnet"))) {
      Serial.println("Sim808 join network error");
      delay(2000);
  }

  //************ Successful DHCP ****************
  Serial.print("IP Address is ");
  Serial.println(sim808.getIPAddress());

  //*********** Establish a TCP connection ************
  while(!sim808.connect(TCP,"39c309ae.ngrok.io", 80)) {
      Serial.println("Connect error");
  }
  Serial.println("Connection success");

  //*********** Send a GET request *****************
  Serial.println("waiting to fetch...");
  sim808.send(http_cmd, sizeof(http_cmd)-1);
  while (true) {
      int ret = sim808.recv(buffer, sizeof(buffer)-1);
      if (ret <= 0){
          Serial.println("fetch over...");
          break;
      }
      buffer[ret] = '\0';
      Serial.print("Recv: ");
      Serial.print(ret);
      Serial.print(" bytes: ");
      Serial.println(buffer);
      break;
  }

  //************* Close TCP or UDP connections **********
  sim808.close();

  //*** Disconnect wireless connection, Close Moving Scene *******
  sim808.disconnect();
  delay(5000);
  }
  void loop(){
  }

Actually i want send two numbers instead of ****** in this line:
char http_cmd[] = "GET /index.php?lat=*******&long=******* HTTP/1.0\r\n"
                        "Host: 04d1a36d.ngrok.io\r\n"
                        "\r\n";

to 04d1a642.ngrok.io/index.php for inserting in a database.
but when i use

sprintf

like this:
void setup(){
sprintf( http_cmd, "GET /index.php?lat=%f&long=%f HTTP/1.0\r\n"
                        "Host: 04d1a662.ngrok.io\r\n"
                        "\r\n", 36.423156, 48.526484);
.
.
.

The module doesn't fetch to server for get response!

Don't use sizeof(...), use strlen(...). Also Arduino cannot use floats in sprintf.

@Majenko - so how i can send float numbers as Get request to my server?

You can use dtostrf() to convert from a float to a char array.

? is inserted instead of the float value with sprintf.

print the string to serial ... see if it is valid

I'm not actually professional in arduino and c! can you help ?


text:
A small problem that I cannot detect, My steppers are not moving for some reason ...?
I'm working on a similar project that can be found in this link
https://howtomechatronics.com/projects/arduino-mecanum-wheels-robot/
It's the same build.
To control the 4 steppers (via the NRF24L01), I have built a remote control ( and you can find the project on the same website).
I have modified a few things and kept on testing on each step that I go through.
For now: my remote control sends X, Y from 1 joystick module and X1, Y1 from a second joystick module, besides mapped value from a potentiometer.
Back to the car, I'm receiving the exact same data and all works fine.
I have tested my circuit,
the power supply is fine and all good.
But I'm facing a problem that I could not detect when it comes to making the steppers move after receiving the data from the transmitter.
This is the code I m using for the receiver:
I'm not familiar with this Library and I feel like I'm only missing a small detail.
(As I said the same circuit was tested with a different code and steppers are running just fine).
Hopefully, you can help me out and spot what's wrong.
Thanks a lot guys.
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <AccelStepper.h>
 RF24 radio(7, 8);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
//unsigned long lastReceiveTime = 0;
//unsigned long currentTime = 0;
// Define the stepper motors and the pins the will use
AccelStepper LeftBackWheel(1, 2, 3);   // (Type:driver, STEP, DIR) - Stepper1
AccelStepper LeftFrontWheel(1, 4, 5);  // Stepper2
AccelStepper RightBackWheel(1, 9, 10);  // Stepper3
AccelStepper RightFrontWheel(1, 41, 40); // Stepper4
int wheelSpeed = 1500;
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j2PotX;
  byte j2PotY;
  byte pot1;

};
Data_Package data; //Create a variable with the above structure
void setup() {
  // Set initial seed values for the steppers
  LeftFrontWheel.setMaxSpeed(3000);
  LeftBackWheel.setMaxSpeed(3000);
   RightFrontWheel.setMaxSpeed(3000);
  RightBackWheel.setMaxSpeed(3000);
  radio.begin();
  radio.openReadingPipe(0, address);
  //radio.setAutoAck(false);
  //radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.startListening(); //  Set the module as receiver
  Serial.begin(9600);
}
void loop() {
  // Check whether we keep receving data, or we have a connection between the two modules
  /*currentTime = millis();
    if ( currentTime - lastReceiveTime > 1000 ) { // If current time is more then 1 second since we have recived the last data, that means we have lost connection
    resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone jas a throttle up, if we lose connection it can keep flying away if we dont reset the function
    }*/
  // Check whether there is data to be received
  if (radio.available()) {
    radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
    //lastReceiveTime = millis(); // At this moment we have received the data
  }

  Serial.print("X1= ");
  Serial.print(data.j1PotX);
  Serial.print("  Y1= ");
  Serial.println(data.j1PotY);
  Serial.println();
  Serial.print("X2= ");
  Serial.print(data.j2PotX);
  Serial.print("  Y2= ");
  Serial.println(data.j2PotY);
  Serial.println(" POT1=  ");
  Serial.println(data.pot1);
  Serial.println();
  delay(1000);
  // Set speed - left potentiometer
  wheelSpeed = map(data.pot1, 0, 255, 100, 3000);

  if (data.j1PotX > 150) {
    moveSidewaysLeft();
  }
  else if (data.j1PotX < 100) {
    moveSidewaysRight();
  }
  else if (data.j1PotY > 160) {
    moveForward();
  }
  else if (data.j1PotY < 100) {
    moveBackward();
  }
  else if (data.j2PotX < 100 & data.j2PotY > 160) {
    moveRightForward();
  }
  else if (data.j2PotX > 160 & data.j2PotY > 160) {
    moveLeftForward();
  }
  else if (data.j2PotX < 100 & data.j2PotY < 100) {
    moveRightBackward();
  }
  else if (data.j2PotX > 160 & data.j2PotY < 100) {
    moveLeftBackward();
  }
  else if (data.j2PotX < 100) {
    rotateRight();
  }
  else if (data.j2PotX > 150) {
    rotateLeft();
  }
  else {
    stopMoving();
  }
  // Execute the steps
  LeftFrontWheel.runSpeed();
  LeftBackWheel.runSpeed();
  RightFrontWheel.runSpeed();
  RightBackWheel.runSpeed();
}
void moveForward() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveBackward() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void moveSidewaysRight() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
   RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveSidewaysLeft() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void rotateLeft() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
   RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void rotateRight() {
  LeftFrontWheel.setSpeed(wheelSpeed);

  LeftBackWheel.setSpeed(wheelSpeed);
   RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void moveRightForward() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveRightBackward() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(0);
}
void moveLeftForward() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(wheelSpeed);
   RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(0);
}
void moveLeftBackward() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void stopMoving() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(0);
   RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(0);
}
void resetData() {
  // Reset the values when there is no radio connection - Set initial default values
  data.j1PotX = 127;
  data.j1PotY = 127;
  data.j2PotX = 127;
  data.j2PotY = 127;
  data.pot1 = 1;
}

I think you should not use delay here. Ditch that delay call. You can time the LCD display like in the BlinkWithoutDelay example

I will try that for sure


text:
How to display float variables on oled display (0.96'')
I have a similar problem than the discussed here : How to display variables on 0.96" OLED with u8glib library?
I'd like to know how can I show float variables in place of int variables. What should i modify in this part of my code ?
char buf[9];
sprintf (buf, "%d", a);
u8g.drawStr(18, 3, buf);

} while( u8g.nextPage() );

delay(200);

}

Thanks in advance =D

Is this code working for you? If not, what happens wrong?

yes, it's working, but just with int variables =/. when i try float ones it do not work.

What means "does not work"? Please describe what actually happens

The printf group of functions in the Arduino library don't implement float and double conversions. For those, you need the function
char *dtostrf(double dval, int8_t width, uint8_t prec, char *buf);
  Convert the double value passed in dval into an ASCII string stored in
  buf. Conversion is done as "[-]d.ddd". The minimum field width of the output
  string (including the '.' and the possible sign for negative values) is given
  in width, and prec determines the number of digits after the decimal. width
  is signed, negative for left adjustment.
  Returns buf.

, which you'll need to call for each float you want to convert.
Note that you could convert several floats into strings, upfront, each into its own character buffer, then use sprintf to format the final buffer - remembering that in sprintf's format string, those buffers contain character strings, which you'll need to specify with '%s' format-specs.

The u8glib library provides the Arduino's standard print()
method. You can the write:
u8g.setPrintPos(18, 3);
u8g.print(a);

and it should work for mostly any type of a.


text:
How can I use a variable to choose which Serial port to interact with?
In my use case I have multiple devices connected to the serial ports of an arduino. Currently I write to them using Serial1.write(), Serial2.write(), etc.
How can I choose the port programmatically, for example:
for(int i = 0; i < numDevices; i++){
  Serial[i].write();
}

what have you tried? ... what errors did you get?

I'm not getting any errors because, as stated, I know how to write it 'hard-coded' but not the way I want. I didn't try Serial[i] because that's obviously wrong, but I can't find any docs on how to write to a variable pin.

You may use an array of pointers to the actual serial ports. For
example, on an Arduino Mega:
const size_t PORTS_COUNT = 4;
const HardwareSerial *ports[PORTS_COUNT] = {
    &Serial, &Serial1, &Serial2, &Serial3
};

void setup() {
    for (size_t i = 0; i < PORTS_COUNT; i++)
        ports[i]->begin(9600);
}


text:
qMenuSystem Oled I2C can't make it work
I'm trying to make the qMenuSystem to work with my I2C Monochrome OLED display but without any luck.
To summarize all here's what's with it :
- the qMenuSystem is using a library called : DigoleSerial but has the things set as SPI connection
- the library itself can work with I2C but i'm receiving some strange errors like this :

Arduino: 1.8.9 (Mac OS X), Board: "Arduino/Genuino Uno"

TestMenu:25:42: error: expected primary-expression before '_disp'
 DigoleSerialDisp mydisp=DigoleSerialDisp _disp(&Wire,'\x3C');
                                          ^
exit status 1
expected primary-expression before '_disp'

Here is the video of what i'm trying to display:
https://www.youtube.com/watch?v=rjON_enuOGs (I already tried what's suggested in the comments)
Here's the code so far:
#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);

void setup()
{
  menu.InitMenu(mnuRoot,cntRoot,1);
  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 the 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;

I'm kinda new and I have no idea how can I make it work. Can anyone please help me figure it out what's wrong ?
Thank you for your time reading all of this.

As the compiler is indicating, the line
DigoleSerialDisp mydisp=DigoleSerialDisp _disp(&Wire,'\x3C');

is broken.
This part:
DigoleSerialDisp _disp(&Wire,'\x3C')

declares and constructs an object named _disp of class DigoleSerialDisp.
You're trying to assign that to another variable, mydisp - that's not valid C++ - you can assign another variable, but you'd need to declare and construct it first, not in the assignment. There's also no need to construct it, name it _disp and then assign it to another variable.
Just do this:
DigoleSerialDisp mydisp(&Wire,'\x3C');

You'll probably want to rewrite
qMenuSystem menu=qMenuSystem(mydisp);

as
qMenuSystem menu(mydisp);

as well.

Thank you very much for your explanation and for your help. Now it's compiling without any error. All's good but I can't see anything on the display. My OLED is working well when I use the Adafruit SSD1306 library with Adafruit GFX library, but I don't know about this DigoleSerial library.  Here's my OLED (sort of , it looks the same) : https://bit.ly/2kgZa6p . It's using the address 0x3C when I use the Adafruit libraries. Is it anything i still missing ? Thank you again for the fast help.

I'm glad this was helpful. If you have another question the best thing to do is accept this as the answer to the question you asked and ask your other question separately. This helps other people with similar problems find the answer to their problem, and lets other people who may be able to help you with your next problem find the question and offer help (they won't find it here in the comments).

Thank you again. I'm new here so i don't really know the flow but I get it. I'll ask a new question in a new topic.

You're doing great :) Thanks!


text:
Best approaches to reading a high-count quadrature encoder?
I have a 24v servo motor coupled to a 2,000 segment optical encoder that runs on 5v.
That's 2,000 "ticks" per revolution at it's base resolution. (Full quad reading allows 8,000 ticks per revolution, which I have no idea how a person could really USE! Egads that's tiny slices of a circle.)
It ALSO has a 'full-circle' index, a "Z" line.
That Z SEEMS to be coincident with A. Meaning that the clear slot in the rotor seems to be in the same place for both ONE of the A ticks and the only Z tick. I do not have an oscilliscope to verify this, but timestamping two different interrupts makes it seem like they do line up (one on A one on Z).
The motor runs at max 1075 RPM. So if I did the maths correctly that means there are 2,150,000 ticks per minute on the A/B lines plus 1075 ticks per minute on the Z line.
35,833.33-ish ticks per second on the A line.
17.9166-ish ticks per second on the Z line.

I have used sample code from a number of sources on both a Nano v3 and an Uno r3. I can't get counting to be accurate on either device, both lose ticks counting the A trigger and the coincidence of the A and Z ticks makes the interrupts 'stack' (both trigger almost instantaneously, but whichever was first gets processed and THEN the other gets processed...)
I do know that I can get IC's that will count for me, but there are MANY models and I do not have the ability to determine which would suit this situation the best.
Despite reading a great number of posts about encoders and the Arduino code to read them I still don't understand if the Nano or Uno COULD do this on their own at this speed.
GOAL:

Accurately track all 2000 pulses per revolution at 1075 RPM.
Accurately track FULL rotation pulses at 1075 RPM.
Use full rotations as error-checking against the 2000 count.
Provide error-checked count as an absolute count to external device.
Provide resettable zero-point to external device (remotely reset the count).

So please, if you would, inform me about or direct me to proven methods and resources for achieving the above goals?

Do you have to track rotation in both directions?

Yes. Intended use is in small CNC machine.

For this you would typically pick a microcontroller that has a quadrature encoder interface in it. You could count the pulses with a timer, but you wouldn't get direction information with that.


text:
How do I code the release of a momentary touch sensor in IDE?
I am a performing musician and quite new to the Arduino community.  Just learning as I go.  I am interested in using a momentary touch sensor with Adafruit's MP3 shield or Wave Shield.  I have successfully connected a touch sensor to the MusicMaker MP3 shield (which is sitting on the Adafruit Metro).  I combined some code from two independently working code sequences: one, to play MP3s and, two, to trigger with the sensor.  This works successfully except that the music starts but does not stop when I lift my finger off the sensor.  I want the music to stop when the touch sensor is not being touched.  When the sensor is touched again, I want the music file to start again from the beginning.  I'm printing the code IDE is running below and attaching an image of the touch sensor I am using.  I appreciate any advice on the code!  Thank you.
/*
  AnalogReadSerial

  Reads an analog input on pin 0, prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/AnalogReadSerial
*/

// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// define the pins used
//#define CLK 13       // SPI Clock, shared with SD card
//#define MISO 12      // Input data, from VS1053/SD card
//#define MOSI 11      // Output data, to VS1053/SD card
// Connect CLK, MISO and MOSI to hardware SPI pins.
// See http://arduino.cc/en/Reference/SPI "Connections"

// These are the pins used for the breakout example
#define BREAKOUT_RESET  9      // VS1053 reset pin (output)
#define BREAKOUT_CS     10     // VS1053 chip select pin (output)
#define BREAKOUT_DCS    8      // VS1053 Data/command select pin (output)
// These are the pins used for the music maker shield
#define SHIELD_RESET  -1      // VS1053 reset pin (unused!)
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

// These are common pins between breakout and shield
#define CARDCS 4     // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

Adafruit_VS1053_FilePlayer musicPlayer =
  // create breakout-example object!
  //Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS, DREQ, CARDCS);
  // create shield-example object!
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  Serial.println("Adafruit VS1053 Simple Test");

  if (! musicPlayer.begin()) { // initialise the music player
     Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
     while (1);
  }
  Serial.println(F("VS1053 found"));

   if (!SD.begin(CARDCS)) {
    Serial.println(F("SD failed, or not present"));
    while (1);  // don't do anything more
  }

  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(20,20);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  if(sensorValue > 100) {
    Serial.println(F("Playing track 001"));
  musicPlayer.playFullFile("/track001.mp3");
  }
 else(sensorValue < 100); {
    Serial.println(F("Paused"));
  musicPlayer.pausePlaying("/track001.mp3");
 }      }

you do it the same way as when you detect the keypress ... when the value of the pin indicates that the button has been released,  stop the music

I don't know the mp3 lib and its methods, but playFullFile() sounds like it may return after the entire file has been played. In that case the button wouldn't be polled while the file is being played

You have a semicolon that doesn't belong in your code. Your current code (With the indentation cleaned up a little)
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  if(sensorValue > 100) {
    Serial.println(F("Playing track 001"));
    musicPlayer.playFullFile("/track001.mp3");
  }
  else(sensorValue < 100); { // <<<--semicolon does not belong here.
    Serial.println(F("Paused"));
    musicPlayer.pausePlaying("/track001.mp3");
  }
}

Should be:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  if(sensorValue > 100) {
    Serial.println(F("Playing track 001"));
    musicPlayer.playFullFile("/track001.mp3");
  }
  else(sensorValue < 100) { // <<<--semicolon removed from this line
    Serial.println(F("Paused"));
    musicPlayer.pausePlaying("/track001.mp3");
  }
}

With the semicolon after the else, your code reads "...else do nothing" and then I would expect it to execute the pause logic no matter what value is in sensorValue.
You should pick an indentation style and then be absolutely consistent with it. Most C/C++ programmers use K&R style, which is what I used in my edit. (Opening braces are on the same line as the if statement/function that begins the scope, code inside braces is indented, and closing brace is at the same indentation level as the line that contains the opening brace.)

As Sim Son have pointed it out, you need to use the proper function.
According to your library's documentation:
boolean playFullFile(char *trackname) - Play the complete file. This function will not return until the playback is complete.
You want to check your touch sensor, so this won't be enough for you.
boolean startPlayingFile(char *trackname) - Begin playing the specified file from the SD card using interrupt-driven playback. This allows your program to perform other tasks as the file is playing.
That documentation missed it, but in the source there is a function that stops your music:
void stopPlaying(void);
You can find this within your Arduino folder: Arduino/libraries/Adafruit_VS1053_Library's Adafruit_VS1053.h and Adafruit_VS1053.cpp files.