text:
Snake head in snake game always diagonal to rest of body
I am trying to create a basic snake game using the arduino UNO along with the MAX72XX module, the LCD module and the analog joystick module. I have made my program using object orientated programming. I have no experience with C++ so I have done really well to get this far in my program (This is the only thing left to help me complete the game!). The only problem that is holding me back is that the snake head is always diagonal to the rest of the body. Here are a few examples of what I mean:

Here is my code if the issue is in here (I have commented what part does what):
#include "LedControl.h"
#include <LiquidCrystal.h>
LedControl lc=LedControl(12,10,11,1);
LiquidCrystal lcd(8, 13, 3, 5, 6, 7);

/*lcd->setCursor(0, 1);
  // print the number of seconds since reset:
  lcd->print(millis() / 1000);*/

class Snake_body//class of each snake body part
{
  //private:

  public:

    int following_direction;
    int x;
    int y;
    int previous_x;
    int previous_y;
    bool enabled;
    /*Snake_body()
    {
      this->enabled = false;
    }*/
    /*Snake_body(int x_value, int y_value)
    {
      this->enabled = false;
      this->following_direction = 1;
      this->x = x_value;
      this->y = y_value;
      this->previous_y = y_value;
      this->previous_x = x_value;
    }*/
    void configure(int x_value, int y_value)
    {
      //this->enabled = true;
      this->following_direction = 1;
      this->x = x_value;
      this->y = y_value;
      this->previous_y = y_value;
      this->previous_x = x_value;
    }

};

class Power_up
{
  private:

  public:
    virtual void init()
    {
      this->x = 0;
      this->y = 0;
    }

    int x;
    int y;
};

Snake_body *snake[64];
int snakes_length;

//Snake_body *snake[0];
Power_up *power_up;

int score;

void setup() {

  Serial.begin(9600);

  lcd.begin(16, 2);

  snakes_length = 1;

  for(int z = 1; z < 64; z++)
  {
    snake[z] = NULL;//makes all snake body parts except head NULL
  }

  snake[0] = new Snake_body();//define snake head
  snake[0]->configure(0,0);//set it up
  power_up = new Power_up();//power up to increase in body size
  //Snake_body snake[0] = new Snake_body();
  // put your setup code here, to run once:
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);
  lcd.setCursor(0, 0);
  score = 0;
  lcd.print("score: ");
  lcd.setCursor(6, 0);
  lcd.print(score);
  pinMode(2, INPUT);
  digitalWrite(2, HIGH);
  power_up->x = random(0, 8);
  power_up->y = random(0, 8);
}

int snake_direction;

void loop()
{
  int x_axis = analogRead(A0);
  int y_axis = analogRead(A1);
  int switcher = digitalRead(2);

   if(x_axis <= 400)//the following 4 directions are for moving the snake
   {
     snake[0]->following_direction = 0;
     //x += 1;
     Serial.println("left");
   }

   else if(x_axis >= 600)
   {
     snake[0]->following_direction = 1;
     //x -= 1;
     Serial.println("right");
   }

   else if(y_axis <= 400)
   {
     snake[0]->following_direction = 2;
     //y -= 1;
     Serial.println("up");
   }

   else if(y_axis >= 600)
   {
     snake[0]->following_direction = 3;
     //y += 1;
     Serial.println("down");
   }

  if(snake[0]->following_direction == 0 && snake[0]->x < 7)//updates the snakes position
  {
    snake[0]->previous_x = snake[0]->x;
    snake[0]->x += 1;
  }

  else if(snake[0]->following_direction == 1 && snake[0]->x > 0)//updates the snakes position
  {
    snake[0]->previous_x = snake[0]->x;
    snake[0]->x -= 1;
  }

  else if(snake[0]->following_direction == 2 && snake[0]->y > 0)//updates the snakes position
  {
    snake[0]->previous_y = snake[0]->y;
    snake[0]->y -= 1;
  }

  else if(snake[0]->following_direction == 3 && snake[0]->y < 7)//updates the snakes position
  {
    snake[0]->previous_y = snake[0]->y;
    snake[0]->y += 1;
  }

  Serial.println("\n");//USED THESE PRINT STATEMENTS TO PRINT VALUES

  Serial.print("previous x: ");
  Serial.print(snake[0]->previous_x);
  Serial.println("");
  Serial.print("previous y: ");
  Serial.print(snake[0]->previous_y);
  Serial.println("");
  Serial.print("direction: ");
  Serial.print(snake[0]->following_direction);
  Serial.println("\n");

  if(snake[0]->x == power_up->x && snake[0]->y == power_up->y)//if the head collides with the power up
  {
    score += 1;
    lcd.setCursor(6,0);
    lcd.print(score);

    power_up->x = random(0, 8);
    power_up->y = random(0, 8);

    for(int j = 0; j < 64; j++)
    {
      if(snake[j] == NULL)//searches for empty snake body
      {

         snake[j] = new Snake_body();//creates new snake body part
         snake[j]->configure(snake[j-1]->previous_x, snake[j-1]->previous_y);//sets up the snake body part

         snake[j]->following_direction = NULL;
         snakes_length += 1;
         break;
      }
    }
  }

  for(int i = 1; i < 64; i++)
  {
    if(snake[i] != NULL)//updates the other body parts appart from the snake head (it was updated before this)
    {
      snake[i]->previous_x = snake[i]->x;
      snake[i]->previous_y = snake[i]->y;
      snake[i]->x = snake[i-1]->previous_x;
      snake[i]->y = snake[i-1]->previous_y;
    }
  }

  lc.setLed(0,power_up->x,power_up->y,true);
  for(int w = 0; w < 64; w++)//drawing body parts onto the screen
  {

    if(snake[w] != NULL)
    {
      lc.setLed(0,snake[w]->x,snake[w]->y,true);
    }
  }

  delay(100);

  lc.clearDisplay(0);
}

I'm not sure if I understand the problem well... in the first example the snake body has three straight dots. This means that before the head was straight compared to the body. Only in the screenshot you made it 'turned'  diagonal (?)

What you can do yourself to 'debug' is to RUN the sketch on a PC. You can do this by creating a class for all Arduino specific classes (like LiquidCrystal, Serial and LedControl) and program all functions (to do nothing or show a simple display, or write just some lines to mimic the output). This will let you easily add break points and step through your code, or see a (long) list of output including history.

And some OO improvements (you did already a good job): you don't have to use the 'new'/dynamic way of allocating in your case, just create elements directly. The normal naming for classes is PascalCasing thus PowerUp instead of Power_up, and make all variables in a class private (move the private  keyword before int x;  in the Power_up class. Instead of snake[0]->y += 1; you can use snake[0]-y++, similar with --.

When a new snake body part is added, let the sketch print out it's position. Check, if that position is correct. I see you are adding the new element at the previous position of the last one, but then you let every part (except for the head) move one step further. Please try to move the adding part to after the body updating part

@MichelKeijzers No the snake can only move vertically and horizontally. In the picture it is moving in a straight line. But for example if the snake's body was on x axis 5 and the snake head was on x axis 4 and if both of their y axis' get moved up by one then their x would be on the same x axis as before but the head would be one place higher than the body.

@chrisl tried putting the adding a new snake part after updating. No luck.

Then please print the position of the new added element. Show the complete Serial output

@chrisl I have had an idea! Could I use the previous direction of the snake head and use the current direction to determine which way the snake turned and then fix the head using the x and y axis' from there.

@chrisl does not matter I fixed the game myself. All that I did was move the previous_x and previous_y out of the if statements

@MichelKeijzers does not matter I fixed the game myself. All that I did was move the previous_x and previous_y out of the if statements

Then please write an answer yourself, so that others might profit from your learning and that this question can be marked as answered by yourself.

Glad you sorted it out yourself. If you have more complicated problems in the future, consider trying some non-Arduino specific parts on a PC, with full debugging capabilities.

when debugging a problem such as yours, it is important to identify the failure correctly .... you say that the head is diagonal from the body ... but that is not what the actual problem is ... the head is not offset at a diagonal, it is offset by one square to left or to right


text:
Arduino Uno CTC mode interrupt is not tiggering
I am trying to generate LED blink after 4 second using Interrupt  but Interrupt is not triggering not even once .
Request: if you have arduino uno r3 please check at your end and let me know result.
I have read Timer counter section multiple times and applied everything i can for example :-

Enabled Global Interrupt
Select CTC Mode
Enable Interrupt for OCIE0A
Prescaling to clk/1024
Initializing OCR0A
When OCR0A equal TCNT0 ,interrupt will generate

int var;
void setup() {
  // put your setup code here, to run once:
    SREG = SREG | (1<<7);          // Gloval interrupt enable
    TCCR0A = TCCR0A | (1<<WGM01); // Clear counter on compare match mode
    OCR0A = 255; // when TCNT equal OCR0 interrupt will generate
    TIMSK0 = TIMSK0 | (1<<OCIE0A); //  Output Compare Match A Interrupt Enable
    TCCR0B = TCCR0B | (1<<CS01) | (1<<CS02);  // Prescaling by 1024
    DDRB = DDRB | (1<<5);
    Serial.begin(9600);      // Testing
    Serial.println("Start");   // Testing
}

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

}

ISR(TIMER0_COMPA_vect){
    var++;
    Serial.print(var); // Testing
    volatile long unsigned i;
    if(var == 246){
        PORTB = PORTB | (1<<5);
        for(i=0; i<30000; i++);
        PORTB = PORTB & ~(1<<5);
        for(i=0; i<30000; i++);
        var=0;
    }
}

clock is 16 00 00 00 Hz
Prescaling by 1024 = 15625
1 Tick = 1/15625 = 0.00 00 64 sec
OCR0 is initialized by 255
TCNT0 Ticks to 255
Total time taken to generate one interrupt = 255 * 0.00 00 64 =
0.01632 sec that means after every  0.01632 sec Interrupt supposed to generate
How many interrupt is required to generate LED after 4 sec =>
4/0.01632 = 246

Update working code
int var;
void setup() {
  // put your setup code here, to run once:
  SREG = SREG | (1<<7);          // Gloval interrupt enable
  TCCR0A =(1<<WGM01); // Clear counter on compare match mode
  OCR0A = 255; // when TCNT equal OCR0 interrupt will generate
  TIMSK0 = (1<<OCIE0A); //  Output Compare Match A Interrupt Enable
  TCCR0B = (1<<CS00) | (1<<CS02);  // Prescaling by 1024

  DDRB = DDRB | (1<<5);

    Serial.begin(9600);      // Initialize the USART
    Serial.println("Start");   // Write the welcome message

}

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

}

ISR(TIMER0_COMPA_vect){
  var++;
 // Serial.print(var);
  volatile long unsigned i;
  if(var == 246){
        PORTB = PORTB | (1<<5);
        for(i=0; i<300000; i++);
        PORTB = PORTB & ~(1<<5);
        var=0;
  }
}

There are a few issues with your code:
First, you should completely overwrite the timer control registers
rather than changing single bits. For example, when you write
TCCR0A = TCCR0A | (1<<WGM01); // Clear counter on compare match mode

You end up with a timer mode that results from the combination of the
bits that were already set there and the ones you are setting. Judging
from the comment, you assume that this will be CTC mode, but this is not
granted, because the Arduino initialization routine has already set some
bits in this register. Since you are taking the timer for your own
usage, just overwrite all the control registers:
TCCR0A = (1<<WGM01); // Clear counter on compare match mode

and same for TCCR0B and TIMSK0.
The second problem is that you misread the “Clock Select Bit
Description” table from the datasheet. Your timer is being clocked from
an external clock source on T0 pin. Presumably you have nothing
connected there, so the timer does not increment. You probably meant
TCCR0B = (1<<CS00) | (1<<CS02);  // Prescaling by 1024

A smaller issue is your delay loop. The program would be easier to
understand if you instead use a proper delay function. The Arduino
delay() will not work, as you have reconfigured Timer 0, but you can
use _delay_ms() from the avr-libc if you #include <util/delay.h>.

Thanks a lot , you are right i miss read Prescaling bits . my code is working now

source: Stack Exchange

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

sort: votes


text:
How to run atmega328p at 8, 4 and 1 mhz?
Instead of using the regular Arduino board I have purchased the atmega328p-pu along with this components:

22pf ceramic capacitor
10K resistor
16mhz crystal
47uF capacitor
3.3 Volts Power supply

The diagram looks like this:

Because the atmega328p chip that I purchased already comes loaded with arduino bootloader I can program this chip right away! This video explains in more detail how to upload the code to the chip. It is very simple.
The reason why I run my atmega328p chip with a 3.3V power supply is because of these reasons:

I have multiple sensors like the NRF24L01 that cannot take 5 volts.
I run this project of a 3.3 battery as well in order to save power.
I do not want to use voltage regulators as they are inefficient and they will waste my battery.
Everything works great.

Even though everything works great if I am running atmega328P at 16mhz @ 3.3V I am not following the specifications. In order to do things correct I will like to run my code at 8mhz so that I am in within the specs
Question
What is the correct way of running this project at 8mhz? If I change the 16mhz crystal for a 8mhz it runs at 8mhz but everything is half the speed. I have to divide all time related functions by 2. Moreover, I cannot upload new code if it has a 8mhz crystal. In order to upload new code I have to place the 16mhz crystal upload the code and then change the crystal again.
Can I still use my 16mhz crystal and run at 8mhz so that I do not have to keep replacing the crystal? I want my millis function and other time dependent functions to have the correct time. I do not want to have to divide everything by 2.
Do I have to burn a different bootloader for this to work? Where can I find a tutorial that can explain me all this?
There are tutorials on how to use the internal 8mhz crystal from the atmega328 chip but still want to use an external crystal as it is much more accurate
Edit
I just found  this link that explains how to do it. Edgar Bonet answer seems a lot simpler so I will stick to that.

If you run your MCU at 8 MHz, everything will run at this frequency: not
only the CPU core but also the timers, including Timer 0 which is used
for millis(), delay(), etc. So you will have to use a modified
version of the Arduino timing functions in order to cope with this clock
frequency.
Fortunately, such version already exists. Actually, it is even supported
by the standard Arduino core, since it supports the 3.3 V version
of the Arduino Pro Mini, which uses an ATmega328P clocked at 8 MHz.
I thus suggest you install an 8 MHz crystal, burn in the bootloader
for the 3.3 V Pro Mini, and tell your IDE that you are using that
board. In the Tools menu:

set board to "Arduino Pro or Pro Mini"
set processor to ""ATmega328P (3.3V, 8 MHz)"

How can I burn the bootloader for the 3.3V Pro mini? Is that a different bootloader than the one that it came with? The rest of the answer I understand perfectly fine. Thanks for the help Edgar.

@TonoNam: you will need an ISP programmer, or an Arduino running the ArduinoISP sketch. The Tools menu of the Arduino IDE has a “Burn Bootloader” item. You can search the internet for instructions on how to use it.

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


text:
the use of the Arduino's EEPROM
I want to know the purpose of using the EEPROM because I can't get it,
I mean I know that it can store values for a long time, but I just can't get the goal here
#include<EEPROM.h>
void setup()
{
  Serial.begin(9600);
  EEPROM.write(0,4);
  int s=EEPROM.read(0);
  int f=10;
  Serial.print(s);
  Serial.print(" ");
  Serial.print(10);
}

void loop()  {}

For example, I'm using EEPROM to see the difference if I print a value inside variable s to the serial moniter using EEPROM and a normal value inside the variable f.
But I couldn't find the difference between both because when unplugging the power and turn it on again, both of them are printed.
Hope you got the idea and I hope to see some feedback.
Thank you..
the LED program
then I made this program that will compare the EEPROM value to num.4 and compares the F variable to num.4
known that both F and the EEPROM values are 4.
and then I changed both of the values to 3.
shouldn't the GREEN LED of the EEPROM still on because it has already stored num.4??
#include<EEPROM.h>
void setup()
{
  pinMode(12,OUTPUT);
  pinMode(11,OUTPUT);
}

void loop()
{

  EEPROM.write(0,4);                 //GREEN LED
  int f=4;                           //RED LED

  if(EEPROM.read(0)==4) digitalWrite(12,HIGH);
  if(f==4) digitalWrite(11,HIGH);
}

from where is this code? Swap the lines with read and write. The run the code. Then change the 4 to 42 and upload again.

In your sketch, the leds will never be off because you write to eeprom and read back its value immediately. It's quite trivial that they are the same. Also, you will kill the eeprom rather soon if you write to it that frequently. Eeproms are typically rated for around 100k write operations, so your sketch might brick the eeprom within a few minutes.

now even if I write it inside the void setup, the GREEN LED will not turn on when I change the value to 3. I mean it should save number 4 inside so that the value will simply stay inside right?

What did you move to the setup()? The entire code that is in loop()? Do you understand what Tom_C wrote in his answer? ONE sketch is not enough to really demonstrate the purpose of an eeprom. Instead you should upload and run a sketch1 which writes a value to eeprom in setup(), then upload and run a sketch2 which reads the eeprom and uses the respective value

I edited my answer

In short:
Once you shutdown an Arduino, every variables on it, which have been calculated by the sketch, are lost. That is because they are stored in RAM, which is not able to store things without power. That is not the problem of EEPROM: values stored there will be available on reboot, and won't need to be calculated again.
This can prove useful is your device is allowing a user to store presets: so a configuration of the program. If this configuration, which can be for instance variables affecting the program behavior, is stored in RAM, it will be lost on next reboot. On the other hand, a value stored in EEPROM during the first execution (entered by user for instance) will still be available on next reboot, if you took the time to write it (on the first run) and to read it (on the second run). Just like saving and then recalling a preset.
Beware that EEPROM does not like to be written too many times and wear out, so you should keep that to a minimum (values that really need to be restored on reboot, and cannot be calculated at this time).

thanks @Tom_C   I've edited my post and added THE LED program and asked why the LED of the EEPROM is not ON, hope that you can give me feedback there as well

@klay just like before, your new example does not ANY advantage of EEPROM. Did you read my answer? Here your write and read eeprom in a row, which is a bit like: "I put a cheese in my fridge, what is in my fridge now? Oooh, a cheese!"

@klay  Furthermore, as said in answer, EEPROM do NOT like to be written often. Your EEPROM.write(0,4); in the loop will kill it in a very (very) short time

I just want to apply the concept of it, you know when you store a value to it, and then use it similar to the smart house for example that works on particular orders, so the idea here is to only change it once to show the principle of EEPROM. even when I write it in the SETUP, the LED will not work as well. so consider writing this sketch inside the void setup, how can I still make it work for only once?

I'm sorry, I do not understand what you want or do not understand. Maybe @Sim Son is closer to what you are looking for. In any case, if you do not see the point of writing in EEPROM, then you probably do not need it ;). Also, if you ran the sketch in your answer now, beware that the first EEPROM memory block is likely to be dead.

"It can store values for a long time" - that's not exactly what an eeprom does, the major property is that the information in the eeprom persists during power cycles and chip resets. In contrast, a RAM looses all information when you unpower the chip.
To get a feeling for eeproms, I suggest you follow the below routine:
1. Upload this sketch:
#include "EEPROM.h"

void setup() {
  EEPROM.write(0,4);
}

void loop(){}

2. Once this sketch has been executed, upload and run the below sketch (you could even unplug the arduino before this step):
#include "EEPROM.h"

void setup() {
  pinMode(12,OUTPUT);
  if(EEPROM.read(0)==4) digitalWrite(12,HIGH);
  EEPROM.write(0,3);
}

void loop(){}

3. Now, the green led will light up.
4. Reset the atmega and now the green led will remain off.
By just using a variable int f which is in RAM, you can not "transfer" a value between those sketches/runtimes.


text:
Arduino UARTS Auto addressing slaves
i'm using this serial topology to connect my Act ATmega328p (Arduino) slaves together to a master ESP32.
They are in total 10 ATmega328p slaves and one master:

With this type of wiring i'm sure that only one slave per time will talk back to master (when requested), now here comes the problem, basically i need dynamic addressing of slaves: they can be many (up to 30) and i need to access in order the slave devices.
In order to solve the "dynamic addressing" problem i'm thinking about that:
The first slaves will be plugged in and will send to the master his default address (i.e.: 0xFF)
The master will check if the address is used and then reply back to the device with the first available address (i.e.: 0x01)
The slave will get back the response from the master and set an internal variable with the new address (maybe it's a good idea to store the variable in a EEPROM like M24C02: enter link description here)
Starting from the next cpu cycle, the master will ask sequentially to all enumerated slaves to (for example) do an analog read using this workflow:
The master will send a message to the serial bus with address 0x01 asking to do an analog read
The respective slave will handle the request, read the analog input and then reply back to the master
I think that this can work, but i've not found any kind of this implementation...maybe i'm totally out of mind?
New idea and concept
Guys, what do you think about sequentially power up the circuits and using the same mechanism to assign dynamically the address?
This assumption will avoid me to save the assigned id to the eeprom and some other id software function defined functionalities like address reset, etc...
It can be a good (and dynamic) method to solve the problem, about that, how I can implement this sequential power up?

I would probably solve the problem using the I2C bus. Each I2C slave would have external inputs to determine the unique address. For 30 devices you would need 5 input pins on each STM board to determine the address. Maybe this is not what you are looking for, so look at my second proposal.
The second solution could be to use the SPI bus, where ESP32 would communicate with the devices using a chip select signal  (CS, SS). I would solve the problem with the lack of pins on the master development kit (ESP32), for example, using an I2C expander.

I forgot to mention that your solution, unlike mine, is non-standard.

I know man that is a non standard solution, but I have a constraint: from the ESP32 to the slave clients I can only have 4 wire cable: Vcc, gnd, RX and TX

In that case you can still use I2C.

How? Please give me an example: I need dynamic addressing of slaves and I can't place any dip switches on the PCB

You did not mention you can not use DIP switches or jumpers or other external signals on STM boards . Without external signals (on STM), of course, it can not be solved in the standard way...

Yep, my fault, in any case... thanks man :)

The first slaves will be plugged in and will send to the master his
  default address

If this happens while the master is talking to one of the other slaves,
you risk a collision.
I suggest a very small variation on your scheme. Each slave has a
default address (0xff). When you turn it on, it doesn't say anything.
The slaves only talk when they are addressed.
Every now and then, the master sends a “ping” message to 0xff. The newly
installed slave responds, then the master gives it a real address, and
goes back to its business of collecting sensor data. If no response is
received for the ping within some specified timeout, the master assumes
there is no unconfigured slave.
Since no slave ever sends unsolicited messages, this should avoid any
kind of collision. You just have to make sure that new slaves are added
at a slow rate: after connecting a slave, you wait for slightly more
than the ping period before connecting another one.

Thanks Edgar, your answer is directly what I was looking for! I'll implement like that, I have two remaining question: 1.) how I can implement the "ping" code and manage the dynamic addressing, are you able to give me an example on your post? 2.) You think that a "conditional" power up of slaves (driving a MOSFET from gpio to give Vcc to relative cascading slave when the preceding slave will obtain the address) will help me to avoid to power up the system and then add manually the devices one by one?

You will probably have to invent your own protocol, where each message sent by the master has a slave address, a message type (ping, configure new address, data request), possibly a data field (the address being given) and maybe a checksum.

Yes, sure! It can be feasible without so much effort...the only doubt that I have is about the serial ping: you suggest to use functions like serial write and serial.available? Or I have to implement some dumb loop that listen on serial for a specific amount of time?

For implementing the timeout, you can check Serial.available() for a specific amount of time.

Upvote, this answer confirm me what I was thinking!

You could also at the start let the master contact every possible slave address in the needed range. That way you can check for which slaves are already connected. An address where the master doesnt get an answer within timeout is not connected.

@chrisl: My understanding is that the OP wants dynamic addressing because he cannot add DIP switches to the PCB and does not want to hard-code addresses into them.


text:
Debugging RN 42 HID Mouse
I'm trying to use the RN 42 and Arduino Uno to control a bluetooth mouse. I configured the RN 42 with the commands S~,6 and SH,0220 and R,1 to put the device in HID mouse mode. Is there anything I missed? Below is the sketch I am using to send mouse reports to the bluetooth. The sketch compiles fine, but moving the joystick does not move the cursor. I included a line of code at the end to print on the serial port whatever data is being sent through software serial to the bluetooth. However when I view the serial monitor, I get back a lot of reversed question marks. Anyone know why this is? Thanks in advance.

const int bluetoothTx = 4;    // TX pin of RN-42, Arduino D2 (configure as RX pin of Ard)
const int bluetoothRx = 3;    // RX pin of RN-42, Arduino D3 (configure as TX pin)
const int button = 5;
const int xAxis = A0;         // joystick X axis
const int yAxis = A1;         // joystick Y axis
int range = 12;               // output range of X or Y movement
int responseDelay = 5;        // response delay of the mouse, in ms
int threshold = range / 4;    // resting threshold
int center = range / 2;       // resting position value

SoftwareSerial BT(bluetoothTx, bluetoothRx); // args SoftwareSerial(RXpin, TXpin)

void mouseCommand(byte buttons, byte x, byte y) {
  BT.write((byte)0xFD);
  BT.write((byte)0x05);
  BT.write((byte)0x02);
  BT.write((byte)buttons);
  BT.write((byte)x);
  BT.write((byte)y);
  BT.write((byte)0x00);
}

int readAxis(int thisAxis) {
  // read the analog input:
  int reading = analogRead(thisAxis);

  // map the reading from the analog input range to the output range:
  reading = map(reading, 0, 1023, 0, 12);

  /* threshold prevents the mouse from reading small unintentional movements.
  If the output reading is outside from the rest position threshold, use it: */
  int distance = reading - center;

  if (abs(distance) < threshold) {
    distance = 0;
  }

  // return the scaled distance for this axis:
  return distance;
}

void setup() {
  pinMode(button, INPUT);
  pinMode(bluetoothTx, INPUT); // bluetoothTX is equivalent to arduino RX pin
  pinMode(bluetoothRx, OUTPUT);
  Serial.begin(115200);  // Begin the serial monitor at 115200bps
  BT.begin(115200);  // RN-42 defaults to 115200bps
}

void loop() {
  // read and scale the two axes:
  int xReading = readAxis(xAxis);
  int yReading = readAxis(yAxis);
  int buttonState = digitalRead(button);

  // move the mouse:
  mouseCommand(buttonState, xReading, yReading);
  delay(responseDelay);

  if(BT.available())  // If there's data being sent to the bluetooth module
  {
    // Send any characters the bluetooth receives to the serial monitor
    Serial.print((char)BT.read());
  }
}

what do you mean control a bluetooth mouse? ... a mouse is an input device, not an output device

I think the OP want to configure and use the RN42 (which is a bluetooth chip) as HID mouse to use with a PC. The Arduino would then read from the joystick and send the data to the RN42 to move the cursor correspondingly on the PC

@Tadashi Have you GPIO11 of the RN42 on high level, when powering up?

Thanks for the responses. The problem with getting no response from the mouse was that the bluetooth did not auto reconnect to the computer after powering down. I solved this by sending the command SM,6 for auto reconnect and then R,1 to reboot.

However, I ran into but fixed a few bugs after I connected the RN 42. For anyone trying to make an HID mouse, I have a few troubleshooting tips. My mouse was swerving to the top left of my screen because the resting position of the joystick was not at the center of the range (12) that I wanted the analog pot values to be mapped to. This was because my joystick did not output 1023 as a max value. I scaled 1023 down by .6 to solve this. Another issue was that upon moving the joystick, my mouse would follow a single trajectory and not move anywhere else. Increasing the response delay solved this.

I know that it's been a long time, i am working on the same project as you Ponderosa, have you been able to make it work? I am using an esp32 board with the same joystick. Hoping to get a reply from you. Thank you

The problem with getting no response from the mouse was that the bluetooth did not auto reconnect to the computer after powering down. I solved this by sending the command SM,6 for auto reconnect and then R,1 to reboot.


text:
EEPROM not consistent over reboot
I'am using a Wemos D1 mini V3.0.0 (esp 8266 core).
I tried to save a structure in EEPROM memory but all data are lost when i reboot the board.
I am using these basics functions :
int cle_verif = 519; //verification key

struct sauvegarde_data {
  int cle; //verification key
  int mode_ecl; //var
  int r; //var
  int v; //var
  int b; //var
};
sauvegarde_data customVar;

void sauvegardeEEPROM() {
  EEPROM.put(0, customVar);
  EEPROM.commit();
}

void chargeEEPROM() {
  // Lit la mémoire EEPROM
  EEPROM.get(0, customVar);
  Serial.println("");
  Serial.println("cle : "+String(customVar.cle));
  Serial.println("mode eclairage : "+String(customVar.mode_ecl));
  Serial.println("r : "+String(customVar.r));
  Serial.println("v : "+String(customVar.v));
  Serial.println("b : "+String(customVar.b));
  if(customVar.cle != cle_verif){ // check if the key is correct
    initialiserEEPROM();
  }
}

void initialiserEEPROM(){
  // Valeurs par défaut
  customVar.cle=cle_verif;
  customVar.mode_ecl=0;
  customVar.r=15;
  customVar.v=15;
  customVar.b=15;
  sauvegardeEEPROM();
}

and then, i ran the following code to initialize the EEPROM memory with default values :
EEPROM.begin(128);
initialiserEEPROM(); // initialisation
customVar.b=2; // change cached var value
chargeEEPROM(); // read EEPROM memory

the output is customVar.b=15 which is correct and it means it has been saved in EEPROM.
Any idea ?
Have a great day.
PS: i use four libraries which are FastLed, EEPROM, ESP8266WiFi, ESP8266WebServer.
My goal is to save the LEDs color for a more pertinent reboot.

So, what exactly doesn't work? You wrote, 15 has been stored correctly... please also post your setup and loop code (at least those parts that are relevant)

I don't see EEPROM.begin(). https://arduino-esp8266.readthedocs.io/en/latest/libraries.html#eeprom

Hello, my loop code is not really relevant as it is only server.handle. I then get an argument over a webpage which updates eeprom with sauvegardeEEPROM(); function but that is all

EEPROM.begin was in my setup function i'm sorry :-/ I edited the post so you can see it :-)

The part which is not working in when i reboot the card, all the data i saved are lost.

It turns out i'm just really stupid. I spent something like 7 hours to make things work but i just selected the wrong card during the whole time.
Sorry for bothering you guys :-/


text:
Blink doesn't work on pin D3,D4 and D0 but works on D7
I am facing a strange issue. I am trying to blink an external LED using Wemos D1 mini V2 board. But it is not working. My sketch is as below.
int LED = D3;
void setup()
{
  pinMode(LED, OUTPUT);
}
void loop() {
  digitalWrite(LED, LOW);   // LED off
  delay(1000);              // Wait 1 second
  digitalWrite(LED, HIGH);  // LED on
  delay(1000);              // Wait 1 second
}

The same problem happens on D0, D3, and D4 pins. I am getting 0 volts constantly on pin D0 and 3.3v constantly on pins D3 and D4.
However, The same sketch works for the D7 pin.
Does anyone know how to fix this?

This code should just work. If you're setting LED to D4 it should blink the internal LED. What happens if you do that? How are you measuring the voltage? Also, please make a habit of properly indenting your code, even with such a small program.

Make sure all your SW and FW is up to date.  Trying to get so many different processor to work like the original Atmel processor on the original Arduino UNO is no easy task.  Even the well known Adafruit.com got the this wrong in the beginning.


text:
Use ISRs inside a library more elegantly
At the moment I try to make a library which uses attachInterrupt(?,?,RISING) to read a sensor. The article of Nick Gammon on Calling an ISR from a class helped me a lot, but his "Glue routines" get pretty ugly with more than 30 potential Interrupt Pins on the ESP32, which all need their own static void. Has anyone got a more elegant idea how to do this "Gluing"?

Can you give more details about the kind of interrupts you want to handle? Type of board? In general, you will need one glue function per interrupt, not necessarily one per interrupt pin. This can make a difference if several pins share an interrupt, which is the case for the pin change interrupts on AVR.

An "Arduino" library, which is ESP32 specific, is a bit problematic. An ESP32 isn't an Arduino at all, strictly speaking.

How about going more low level? attachInterrupt() uses different interrupt types depending on the used pin. Most chips only have 1 or 2 external interrupt pins, so the rest is done via pin change interrupts, which cover a whole port, meaning 1 interrupt for a group of 8 pins. You could configure these interrupts directly via their control registers. Though I'm not sure, how this is organized on an ESP.

As a matter of efficiency, I would favor chrisl’s advise to use the
platform's low-level interrupts if at all possible. This, however, comes
at the cost of portability: you would need an implementation specialized
for each platform you want to support. If you don't want to or cannot
maintain all this platform-specific code, attachInterrupt() may be a
reasonable option.
Then, you will absolutely need all those glue routines: since the
interrupt system calls your handlers with no parameters, you will not be
able to share handlers between interrupts, and you end up with as many
handlers as interrupts you are going to use.
There is, however, an elegant way of creating all these specialized
functions without writing them explicitly: you can ask the compiler to
write them for you on the basis of a template you provide.
Below is a version of Nick Gammon's example code modified to use a
template class. Note that you do not necessarily need a class to use
templates: you could use template functions as interrupt handlers if
that is appropriate for your use case.
template <uint8_t pin>
class myClass
{
    static volatile bool switchChanged;

public:
    static void begin()
    {
        pinMode(pin, INPUT_PULLUP);
        attachInterrupt(digitalPinToInterrupt(pin),
                        switchPressed, FALLING);
    }

    static void switchPressed()
    {
        switchChanged = true;
    }
};

template <uint8_t pin>
volatile bool myClass<pin>::switchChanged;

myClass<2> foo;
myClass<3> bar;

void setup()
{
    foo.begin();
    bar.begin();
}

void loop(){}

Note also that myClass<2> and myClass<3> are two different classes:
you actually have a different class for each pin. This means that
foo::switchChanged and bar::switchChanged are two different class
members even though both are static. Since you should (in principle)
have at most one instance of each pin-specific class, you can make
everything within the class static.
The main caveat of this method is that the pin numbers have now to be
compile-time constants. The great advantage is that you will have a
class created for each interrupt that is actually used: no need for an
array of 32 instances on an ESP32 if only a handful of interrupt pins
are going to be actually used.

Thanks a lot! It works brilliant for me. I mostly got what you did, but there's one question left: Why do we have to initialize our private volatile bool myClass<pin>::switchChanged; outside the class definition?

It's not an initialization, it's a definition. Static class members are declared within the class definition but have to be defined outside of it. Otherwise you get the link-time error “undefined reference to myClass<(unsigned char)2>::switchChanged” (and the same for myClass<3>).


text:
Interleave disassembly + source with avr-objdump
I have a C program for the attiny85, that I want to disassemble and display with interleaved source code.
Here's my program:
test.c
#include <avr/io.h>
int main() {
    for(int i=0; i<100; i++) {
        PORTB=i;
    }
}

Here's how I compile it: avr-gcc -g -O0 -mmcu=attiny85 -o test.elf test.c
Finally, I generate the disassembly with interleaved source-code with the command: avr-objdump -S -D test.elf
The disassembly of the text section shows the following disassembly without interleaved source code:
00000030 <main>:
  30:   cf 93           push    r28
  32:   df 93           push    r29
  34:   00 d0           rcall   .+0             ; 0x36 <main+0x6>
  36:   cd b7           in      r28, 0x3d       ; 61
  38:   de b7           in      r29, 0x3e       ; 62
  3a:   1a 82           std     Y+2, r1 ; 0x02
  3c:   19 82           std     Y+1, r1 ; 0x01
  3e:   0a c0           rjmp    .+20            ; 0x54 <__SREG__+0x15>
  40:   88 e3           ldi     r24, 0x38       ; 56
  42:   90 e0           ldi     r25, 0x00       ; 0
  44:   29 81           ldd     r18, Y+1        ; 0x01
  46:   fc 01           movw    r30, r24
  48:   20 83           st      Z, r18
  4a:   89 81           ldd     r24, Y+1        ; 0x01
  4c:   9a 81           ldd     r25, Y+2        ; 0x02
  4e:   01 96           adiw    r24, 0x01       ; 1
  50:   9a 83           std     Y+2, r25        ; 0x02
  52:   89 83           std     Y+1, r24        ; 0x01
  54:   89 81           ldd     r24, Y+1        ; 0x01
  56:   9a 81           ldd     r25, Y+2        ; 0x02
  58:   84 36           cpi     r24, 0x64       ; 100
  5a:   91 05           cpc     r25, r1
  5c:   8c f3           brlt    .-30            ; 0x40 <__SREG__+0x1>
  5e:   80 e0           ldi     r24, 0x00       ; 0
  60:   90 e0           ldi     r25, 0x00       ; 0
  62:   0f 90           pop     r0
  64:   0f 90           pop     r0
  66:   df 91           pop     r29
  68:   cf 91           pop     r28
  6a:   08 95           ret

The disassembly makes somewhat sense, only that I miss the interleaved source code.
Interestingly enough, the output also includes a stab section, where I also find the main segment disassembled:
#include <avr/io.h>

int main() {
  30:   20 00           .word   0x0020  ; ????
  32:   00 00           nop
  34:   80 00           .word   0x0080  ; ????
  36:   00 00           nop
  38:   00 00           nop
    for(int i=0; i<100; i++) {
  3a:   00 00           nop
  3c:   40 00           .word   0x0040  ; ????
  3e:   00 00           nop
        PORTB=i;
  40:   80 00           .word   0x0080  ; ????
  42:   00 00           nop
  44:   00 00           nop
  46:   00 00           nop
  48:   5a 00           .word   0x005a  ; ????
    for(int i=0; i<100; i++) {
  4a:   00 00           nop
  4c:   80 00           .word   0x0080  ; ????
  4e:   00 00           nop
  50:   00 00           nop
  52:   00 00           nop
  54:   91 00           .word   0x0091  ; ????
  56:   00 00           nop
  58:   80 00           .word   0x0080  ; ????
  5a:   00 00           nop
  5c:   00 00           nop
  5e:   00 00           nop
  60:   b7 00           .word   0x00b7  ; ????
    }

}

Now the output includes source code, but the disassembly is wrong.
How do I get an output were both is correct: the disassembled instructions and the interleaved source-code?
(avr-gcc (GCC) 9.3.0. Interleave Assembly and Source for avr-objdump does not seem to have the problem, although he's using the same compiler flags...)

The .stabs section contains debugging info, not actual code. There is no
point in trying to “disassemble” it. The -D option of avr-objdump
means “disassemble everything, whether or not you believe it's machine
code”. Not what you want. For your purpose, -S should be enough.
I do not know why your main() is displayed without source code. I
tried your exact same program with the exact same commands and I do see
the source interleaved with the assembly. I am using avr-gcc 5.4.0 and
avr-objdump 2.26.20160125 as shipped on Ubuntu Eoan.

Thanks. Indeed, if I downgrade the compiler to 5.4.0 it works as well. I'll try to pinpoint the version that introduced the problem and report a bug once I'm able to reproduce it in a clean environment.


text:
Nothing received from function returning array of strings
My read function returns an array of strings. i.e ssid and password
String* configuration::read() {
    String rw_ssid = "";
    String rw_pswd = "";
    const int keys = 2;
    String read_ssid_pswd [keys];
    if (EEPROM.read(0) != 0) {

      for (int i = 0; i < 32; ++i) {
        rw_ssid += char(EEPROM.read(i));
      }
      for (int i = 32; i < 96; ++i) {
        rw_pswd += char(EEPROM.read(i));
      }
      Serial.print("rPASSWORD: ");
      Serial.println(rw_pswd);
      read_ssid_pswd[0] = rw_ssid;
      read_ssid_pswd[1] = rw_pswd;
      Serial.print("Sending ssid:");
      Serial.print(read_ssid_pswd[0]);
      Serial.print(" Pswd: ");
      Serial.println(read_ssid_pswd[1]);
      return read_ssid_pswd;
    } else {
      Serial.println("Data wifi not found!");
      return read_ssid_pswd;
    }
}

I can see the print in the serial monitor.
Sending ssid:SSID Pswd: password

but where this function is called from I have set it up like this:
void setup() {
  Serial.begin(115200);
  Eeprom::configuration::initialize();
  String* ssid_password = Eeprom::configuration::read();
  Serial.print(">SSID: ");
  Serial.println(ssid_password[0]);
  Serial.print(">Password: ");
  Serial.println(ssid_password[1]);
  Funcs::connection::connectWifi(ssid_password[0], ssid_password[1]);
}

and I get thing in the prints  I thought its not giving any error at compile time so it should be correct.

Majenko has it right, your String array should be allocated in Setup().  Notice that I passed back the success/failure of your initial EEPROM test as the return value.
void setup() {
  Serial.begin(115200);
  Eeprom::configuration::initialize();
  const int keys = 2;
  String ssid_password[keys];
  if (Eeprom::configuration::read(ssid_password)) {
    Serial.print(">SSID: ");
    Serial.println(ssid_password[0]);
    Serial.print(">Password: ");
    Serial.println(ssid_password[1]);
    Funcs::connection::connectWifi(ssid_password[0], ssid_password[1]);
  } else {
    Serial.println("Data wifi was not found!");
  }
}

The String array is the parameter, not the return value.  It is passed by reference.  The copying of EEPROM chars to String doesn't need to be into temporary variables, in fact it's inefficient and pointless; it can go straight into read_ssid_pswd[0] and [1], but I didn't want to change your code excessively, and delete the debugging serial writes.
bool configuration::read(String read_ssid_pswd[]) {
    String rw_ssid = "";
    String rw_pswd = "";
    if (EEPROM.read(0) != 0) {

      for (int i = 0; i < 32; ++i) {
        rw_ssid += char(EEPROM.read(i));
      }
      for (int i = 32; i < 96; ++i) {
        rw_pswd += char(EEPROM.read(i));
      }
      Serial.print("rSSID: ");
      Serial.println(rw_ssid);
      Serial.print("rPASSWORD: ");
      Serial.println(rw_pswd);

      read_ssid_pswd[0] = rw_ssid;
      read_ssid_pswd[1] = rw_pswd;
      Serial.print("Sending ssid:");
      Serial.print(read_ssid_pswd[0]);
      Serial.print(" Pswd: ");
      Serial.println(read_ssid_pswd[1]);
      return true;
    } else {
      Serial.println("Data wifi not found!");
      return false;
    }
}

I see so just because the array in initialised in the setup method I do not have to return the array . thanks for posting an example.

tried your suggestion , but I got this error: expected ',' or '...' before 'read_ssid_pswd' at boolean configuration::read(String[] read_ssid_pswd) {

My bad.  Try read(String read_ssid_pswd[]) {

Thanks for the edits in the if statement and the function definition, both were my mistakes.

You can't return locally defined arrays like that. The array only exists in the function, and all you do is return a pointer to where that array was. As the array has gone when you leave the function your pointer just points to garbage.
Instead you should pass an array to the function that the function then populates.

but the save is in a different cpp file and I am trying to access from setup function of the sketch.

So? How does that affect what you pass to the function?

you said function then populates !

ah  I see just declare the read_ssid_pswd outside teh function module level.

Define your array in setup() then pass that as a parameter to the read function. The read function then uses that passed array which means setup() sees the same data. You can then use the return value to indicate success or failure.

I did that sorry, I got the error sayng incompatible types in assignment of 'String*' to 'String [2]' the function that returns the array is  declared as String* configuration::read(String read_ssid_pswd[2]) {...}

You should have String * as your receiving type.

you mean String* configuration::read(String *read_ssid_pswd) {...} ?

Yep. Just that.

I see, so I got compile working but in serial monitor i am getting massive stacktrace, however earlier what I was trying to do to have an array with only 2 items reserved length.


text:
Master Reader/Slave Sender with Distance Sensor
I am currently working on a project and want to transmit the information from a distance sensor from one arduino the another, but what i receive in the master board are not the correct measurements.
Slave Code
#include <Wire.h>

const int trig = 12;
const int echo = 13;

int state = 0;
int count = 0;
int contor = 0;
int set_distance = 5;
long duration, Distanceincm;

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

void loop()
{
 digitalWrite(trig, HIGH);
  delay(15);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  Distanceincm = (duration / 58);
  if (state == 0 && (Distanceincm < set_distance) ) {
    state = 1;
    count++;
    contor++;
    Serial.print("Distance=");
    Serial.println(Distanceincm);
    Serial.print("Count=");
    Serial.println(count);
    Serial.print("ConuntDay=");
    Serial.println(contor);
  }
  if (Distanceincm > set_distance) {
    state = 0;
  }
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {

  Wire.write(Distanceincm);
  Wire.write(count);
  Wire.write(contor);
}

Master Code
#include <Wire.h>

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

void loop()
{
  Wire.requestFrom(2, 6);    // request 6 bytes from slave device #2
  while(Wire.available())    // slave may send less than requested
  {
    long a = Wire.read();
    Serial.print ("Distance = ");
    Serial.println(a);

    int b = Wire.read();
    Serial.print ("Count = ");
    Serial.println(b);

    int c = Wire.read();
    Serial.print ("CountDay = ");
    Serial.println(c);
  }

  delay(500);
}

What i get on the serial monitor is this :

Your receive event should be reading some data.  If you don't read any data then that while loop becomes an infinite loop.

You should also note that wire.read gets you a byte, not a long or an int.

What I see right away is, that you assign address 4 to the slave, but the master reads from address 2.

You have data coming in over I2C.  Compared to the speed of the processor, that data is coming in really slowly.  When the first byte of the data arrives, wire.available() becomes 1.  Now your code enters that loop.  It tries to read a bunch of stuff from wire, but only the 1 byte has shown up so far.  When you call read and there's nothing available it returns -1 which (as a byte) looks like 255 when it gets stuffed into a byte.  I bet something like that is happening but I don't have time to look at Wire and see how it returns.

@Delta_G Wire.requestFrom() is a blocking call. When it exits the whole I2C message was received. It also returns the number of received bytes, I think.

ok then.  I couldn't open up the library from where I was and I knew that other things inheriting Stream did that.

Your code has some flaws, that I will address here:

The main problem, that you see here, is that you only let the slave write data into the buffer, when it is receiving data. But you never send data to it. So there is never anything in the buffer.
In the slave code you have
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {

  Wire.write(Distanceincm);
  Wire.write(count);
  Wire.write(contor);
}

Besides the unbalanced parentheses (which let's me think, that this might not be the actual code, that you are running currently), you are writing to the buffer only inside the receiveEvent(). That only get's called, when the master does a Master-Write transmission (via Wire.beginTransmission() and Wire.endTransmission()). In the master code you are only using Wire.requestFrom(). If you want to send back data on a request, you need to use the onRequest callback of the Wire library. You need to set the appropriate callback function:
Wire.onRequest(onRequestEvent);

And then write data inside that callback function:
void onRequestEvent(){
    Wire.write(...)
}

I will explain how to write the values correctly in a different point below.
In the receiveEvent() function you want to loop through all received bytes but the last. But you are not doing anything with the data. You aren't even reading it. As your code currently stands, this line does not make any sense.
In your master code you are requesting data from the slave with the address 2. Your slave code initiates the Wire library with the address 4. From that point there should never be a successful I2C transmission, unless you have another slave on the bus with the address 2 (another point, where I suspect, that these codes are not exactly the ones used for the test).
In the master code you are using
while(Wire.available())

because the slave might have send less data, than requested. You are testing, that the number of available bytes is not zero. But then you are reading 3 bytes without checking again, which means, when you received 2 byte, you still would try to read 3 bytes, which cannot give good results.
The condition should be Wire.available() >= 3, to check, if at least 3 bytes are in the buffer, because you are reading 3 bytes from it. But also the loop does not make much sense to me. As you have a binary protocol here, how would you treat additional data (meaning excess data, send after the first valid data frame)? You want to receive 3 values per transmission and you are reading 3 values in one iteration of the loop. If there where more data in the buffer, you would be reading the next 3 bytes, throwing away the first 3 bytes. I don't think, that is what you want.
Instead use the return value of Wire.requestFrom(), which is the number of received bytes. Use it to distinguish valid transmissions, from those, which are too short:
uint8_t n = Wire.requestFrom(4, 3);
if(n >= 3){ // at least 3 bytes where received
    uint8_t value1 = Wire.read();
    uint8_t value2 = Wire.read();
    uint8_t value3 = Wire.read();
}

Any transmission, that is too small, will get ignored. Excess data in too long messages will also be ignored. Note, that I used uint8_t, which is an unsigned integer with 8 bits (1 byte) here for simplicity of that points logic. More about your data types and their implications on your code below.
For the to send datatypes on the slave you have int and long. int is a signed integer with 16 bits, long is a signed long integer with 32 bits. (I suspect you don't need a long for the distance, as ultrasonic sensors mostly reach only 3m, but that is up to you). In contrast the argument of Wire.write() is an uint8_t, which has only 8 bits. That call is used to put exactly 1 byte into the buffer, not more. When you are using
Wire.write(Distanceincm);

you are putting the least significant byte of Distanceincm into the buffer. The rest will just be thrown away (this happens at the cast from long to uint8_t). This works as long, as the value is between 0 and 127 (which is the upper part of the int8_t value range). With higher (or lower) values your received data will be garbage. Instead you need to write every byte of your data into the buffer:
Wire.write(Distanceincm  & 0x000000FF);
Wire.write((Distanceincm & 0x0000FF00) >> 8);
Wire.write((Distanceincm & 0x00FF0000) >> 16);
Wire.write((Distanceincm & 0xFF000000) >> 24);

With bitwise ANDing (&) of the hexadecimal value 0x000000FF, we are deleting all bits, beside the least significant byte (analog with 0x0000FF00 for the second least significant byte, and so on). Then we are shifting the corresponding byte to the position of the least significant byte (8 bits for the seconds least significant byte, 16 bits for the third least significant byte, and so on), which then gets used by Wire.write(). To better understand this, read about bitwise operators on the web.
You have to send both integer values in a similar fashion (though they both have only 2 bytes instead of 4).
Now that we are sending more bytes, we also need to receive and read all these bytes correctly. First we need to request the correct number of bytes. 4 bytes for the long value and 2 bytes for both int values --> 8 bytes. So you need to request 8 bytes:
Wire.requestFrom(4, 8);

Then you need to read these bytes into the corresponding variables:
long distance = Wire.read()
                | (Wire.read() << 8)
                | (Wire.read() << 16)
                | (Wire.read() << 24);

We are using the bitwise OR (|) to put the bytes together, shifting every byte to its correct position in the long value. In a similar way you are putting together the 2 int values.


text:
Is my sketch 'thread safe'?
I come from a .Net background, typically I would 'lock' operations on an integer when I have thread-safe requirements. I'm not sure that applies to my sketch here? Could I potentially bypass an increment from one of my interrupt pins?
In summary, I have 2 interrupt pins - I want to increment a count which (every 5 seconds) writes via serial and resets.
I'm doing this to, kind of, avoid writing serial from within an interrupt - since I've read it's strongly discouraged.
#include <Controllino.h>

const byte interruptPin0 = CONTROLLINO_IN0;
const byte interruptPin1 = CONTROLLINO_IN1;
int counter1 = 0;
int counter2 = 0;
unsigned long previousMillis = 0;
unsigned long interval = 5000;
int a = 60;
char buffer[256];

void setup()
{
  pinMode(interruptPin0, INPUT_PULLUP);
  pinMode(interruptPin1, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin0), pin1Fired, RISING);
  attachInterrupt(digitalPinToInterrupt(interruptPin1), pin2Fired, RISING);
  Serial.begin(9600);
}

void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    sprintf(buffer,"A%d",counter1);
    Serial.println(buffer);
    sprintf(buffer,"D%d",counter2);
    Serial.println(buffer);
    counter1 = counter2 = 0;
  }
}

void pin1Fired()
{
  counter1++;
}

void pin2Fired()
{
  counter2++;
}

There is indeed a race condition in your code: if an interrupt fires
while you are reading one of the counters, you might read garbage. If it
fires between reading and resetting the counter, you loose one count.
The way to prevent the race is to block interrupts while the main thread
(everything that does not run in interrupt context) accesses the
counters. BTW, do not forget to make the counters volatile.
The portions of the code that run with interrupts disabled are called
“critical sections”, and you should keep them as short as possible in
order to limit the interrupt latency they introduce. Typically, within
those critical sections you do nothing more than access the shared
variables. Example:
void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    noInterrupts();  // start of critical section
    int counter1Copy = counter1;
    counter1 = 0;
    interrupts();  // end of critical section
    Serial.print("A");
    Serial.println(counter1Copy);
    noInterrupts();  // start of critical section
    int counter2Copy = counter2;
    counter2 = 0;
    interrupts();  // end of critical section
    Serial.print("D");
    Serial.println(counter2Copy);
  }
}

Excellent! Thanks very much for this, probably saved me a lot of hassle when it came to missing counts! Just one question - during the time in which the interrupts are disabled(?) - are we not vulnerable to missing the interrupt handlers? i.e. still missing counts?

When an interrupt occurs in that time, it will be executed after you turned on the interrupts again.you only loose counts, when 2 or more interrupzs occur in that time. To prevent that you need to keep the disabled time lower than the time between 2 interrupts

@chrisl is right. To be more specific, you loose a count if 2 or more instances of the same interrupt fire during that window. If you get one INT0 and one INT1 you are fine.

Got you, brilliantly explained. Thanks Edgar.


text:
3,6V DC motor spinning with L298N and Arduino
I'm trying to control a re used DC motor from a drill (3,6V) with a L298N and a Arduino. It's powered with a 5V - 60A power supply.
I tried to follow this step by step tutorial (https://www.youtube.com/watch?v=dyjo_ggEtVU) but the motor is not spinning..yet. I can ear a noise, it starts to spin a micron and then stops.
I though that it could be something wrong with the power supply but I connected the 4V battery from the drill and the same thing is happening. If I connect the motor directly to the battery it is spinning nicely...
I though then that it was a code issue but I tried a no load test and measured the voltage without the motor -> I've the 4V required voltage. When the motor is connected I have 300mV instead of 4V.
Do you know what could go wrong? Is the L298 dead? just got it a few hours ago...
Would be nice if you have any clue.
Many thanks.
// Commande moteur
    int enA = 9;
    int in1 = 8;
    int in2 = 7;
void setup()
{
  // Définition des sorties

  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);

  //Sens de rotation du moteur

  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);

  //Vitesse de rotation du moteur

  analogWrite(enA, 200);

  //Delay

  delay(5000);

   //Arrêt du moteur

  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
}

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

}

The L239 is a terrible motor driver. It's the kind of motor driver Noah used to control The Ark.
It requires a power supply that is at least 2.5V more than the "logic input high" voltage, which is rated at 2.3V. That means an absolute minimum of 4.8V, which is borderline for the Arduino's 5V pin, especially if you are running off USB (which can drop as low as 4.75V and still be within specification) and way out when powered from the battery.  It's really designed for driving motors in the 12V+ range.
To drive a low voltage motor like yours you need to pick a more modern MOSFET based motor driver.

Thanks for the feedback, what if I use a 12V power supply and I use the AnalogWrite to drop the motor voltage to 4V?

It might work... until that fateful day when you accidentally send 12V straight to the motor...

I'll try that...  thanks :)

I tried with a 20V DC power supply and it's not going to work because analogWrite(pin,1) gives me a minimum of 12V DC at the motor.

Then you should get a proper motor driver that is suitable for your motor, or get a better motor that is suitable for your power supply. Matching your components to your needs is step one of learning to be an electronic engineer...


text:
Blank project gives errors while uploading Arduino Leonardo on Linux Manjaro
I'm on Linux Manjaro. I plugged my Arduino Leonardo clone (that I know works correctly). And tried to flash a blank project on it:
(My IDE version is 1.8.12)
void setup() {
  // put your setup code here, to run once:

}

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

}

It gives me this error:
Sketch uses 3410 bytes (11%) of program storage space. Maximum is 28672 bytes.
Global variables use 149 bytes (5%) of dynamic memory, leaving 2411 bytes for local variables. Maximum is 2560 bytes.
processing.app.debug.RunnerException
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:152)
    at cc.arduino.UploaderUtils.upload(UploaderUtils.java:77)
    at processing.app.SketchController.upload(SketchController.java:732)
    at processing.app.SketchController.exportApplet(SketchController.java:703)
    at processing.app.Editor$UploadHandler.run(Editor.java:2047)
    at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: processing.app.SerialException: Error touching serial port '/dev/ttyACM1'.
    at processing.app.Serial.touchForCDCReset(Serial.java:107)
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:136)
    ... 5 more
Caused by: jssc.SerialPortException: Port name - /dev/ttyACM1; Method name - openPort(); Exception type - Permission denied.
    at jssc.SerialPort.openPort(SerialPort.java:170)
    at processing.app.Serial.touchForCDCReset(Serial.java:101)
    ... 6 more

The TL;DR of this overly verbose error message is “/dev/ttyACM1: Permission denied”.

Im currently reinstalling Arduino IDE (with my bad internet its gonna take a few minutes). So should I try to start Arduino IDE in sudo?

See https://arduino.stackexchange.com/search?q=Linux+permission+denied

Join the correct group(s). Give your user the correct permissions. Then reboot and try again.

this is a textbook example of what a question should look like ... minimal code, full error message printout ... a question asking how to determine the cause of the error, or asking what usually causes the error, or asking how to decode the error printout would complete the post .... i think that it deserves an upvote even though the question has been asked before

@jsotola lol thanks
I will post teh exact answer how to repair it for my distro tomorrow coz today I have no more time to play with arduino

https://www.arduino.cc/en/Guide/Linux#toc6

Okay I found a way to do this.
Open Terminal and type:
ls -l /dev/ttyACM*

you will get something like:
crw-rw---- 1 root dialout 188, 0 5 apr 23.01 ttyACM0
The "0" at the end of ACM might be a different number, or multiple entries might be returned. The data we need is dialout (is the group owner of the file).
Now we just need to add our user to the group:
sudo usermod -a -G dialout <username>

So for me that would be:
sudo usermod -a -G dialout john

BUT it seems to work with dialout on ubuntu/debian based distros. I am on Manjaro and instead of dialout I had to use uucp (and in general on Arch based distros) so:
sudo usermod -a -G uucp john

You will need to log out and log in again for this change to take effect.
This is the procedure to access the serial port from the Arduino Software (IDE) if you get an error
After this procedure, you should be able to proceed normally and upload the sketch to your board or use the Serial Monitor.
Although for me that wasn't over. After doing this the only error I got was Arduino IDe simply saying that it doesn't have permission to write to that port. So I had to start Arduino IDE by:
sudo arduino

in the terminal. After that everything works just fine.
I found help at those links:

https://www.arduino.cc/en/Guide/Linux#toc6
https://forum.manjaro.org/t/how-to-enable-putty-usb-serial-converter-access-without-sudo/82736


text:
Output of mlx90614 to mcufriend tft/lcd, not getting displayed
Newbie here !! Im trying to display the output of my MLX90614 sensor on mcufriend tft display (with arduino UNO). But unable to do so. I can only see the TFT being lit to white color, text -> "Target" flashes on screen for millisecond and then again white lit screen.

But I tried tft-lcd sample codes, which are working fine &
I also tried mlx90614 (mlxtext code), which is also working fine.

But I combined the two codes so as to output it on TFT, which doesnt work. Hence I think this code might have some issue.
Im a beginner pls help!!
#include <Adafruit_TFTLCD.h>
#include <Adafruit_GFX.h>
#include <TouchScreen.h>
#include <Wire.h>
#include <Adafruit_MLX90614.h>

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4

#define BLACK   0x0000
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
Adafruit_MLX90614 mlx = Adafruit_MLX90614();

boolean buttonEnabled = true;

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

  mlx.begin();
  tft.reset();
  uint16_t identifier = tft.readID();
  tft.begin(identifier);
  tft.setRotation(1);
  tft.fillScreen(WHITE);
  tft.drawRect(0,0,319,240,YELLOW);

}

void loop() {

  tft.setCursor(0,1);
  tft.setTextSize(2);
  tft.print("Target  ");
  tft.setTextColor(BLACK);
  tft.print(mlx.readObjectTempC());
  tft.print(" C");
  Serial.print("*C\tObject = "); Serial.print(mlx.readObjectTempC()); Serial.println("*C");
  Serial.println();
  delay(500);

}

look at #define LCD_CS A3 ... do you see it conflicting with another define? ... look for other conflicts

@jsotola, deleted all the unnecessary defines, still not working

start with working tft code ... add a couple lines of mlx code an test ... repeat until failure

The Adafruit library Adafruit_MLX90614 already includes the wire library in the .h file and the constructor calls wire.begin in the .cpp file. Please try removing the wire library you've included in your sketch. If that doesn't solve the problem, follow jsotola's suggestion and add 1 line of code at a time to the working example until it "breaks".


text:
GPS stream question
I have an adafruit Ultimate GPS unit, its working fine. I am reading the GPS stream, via the command line, and one of the details, is "Angle: 167.97"
I looked at a page about GPS sentences, but I'm still confused. Angle, is the direction of wind, or rudder, or angle at altitude. In this case i would guess its either rudder (because I don't know what rudder it may be referring to) or wind angle. Its changing frequently, but the device is stationary in my shed.
My questions are: What is angle referring to? as in, is it wind or rudder?
And where is it referring to? obviously, its not getting that data from its present location, so is that data coming from a whether station or something?
pardon me if this is the wrong exchange to post in, Im not sure where to ask.

Can we see the entire sentence?

It will be referring to the angle of travel. But since it's not travelling that angle is meaningless.

Sure, ill post the entire sentence soon.

It will be referring to the angle of travel. That is, if you're moving (say driving in a car) what direction that movement is in.
But since you aren't moving the angle is meaningless. Instead it's trying to work out a direction from the random noise of the slight changes in the calculated location.
Unless your shed is in a tornado and flying through the air then the angle is not something you need to care about. Ignore it.

+1 for a sense of humor  :)


text:
Is it possible to use Pi's output signal as Arduino's input signal?
I have a relay attached to an Arduino Uno which I want to control using my raspberry pi 3b. And yes I know it can be done by attaching the relay directly to Pi but I cannot do so. Don't ask me why. That is why I want to know whether it is possible to use Pi's output signal as input for the Arduino or not. I do not have spare parts so I don't want to experiment. If anyone knows about this, please tell me.

What type of "signal" do you want? A simple pin, that can be set high or low from the Pi? Or a real data connection like Serial (UART)?

This way is fine: the Pi is a 3.3V based board, so connecting one of the GPIO pin from the pi to an Arduino will not damage it. Furthermore, the 3.3V are sufficient to be considered as HIGH even on a 5v Arduino like the UNO.
The other way around: connecting the output of a 5V Arduino to the input of a pi, will very likely damage the raspberry Pi!
So beware of your Pinmode before doing such a connection!


text:
Long term stability of bluetooth connections
I have two Arduino Megas with HC-05 on Serial1 connected to a Raspberry Pi 3b+ via bluetooth, using the HC-05 and the RPi's built-in bluetooth, and python's pySerialTransfer library to make the connections.
For reasons I am still trying to root cause, the bluetooth connection gets severed a few times an hour. Ideally, I'd get hours to perhaps a day between severed connections; is this a realistic goal?
Over a course of a few days, my testing has shown:

Mega#1 median connection duration is 10 minutes & 88 minute max duration; 25 bytes sent by RPi->Arduino, and by Arduino->RPi every 0.2sec
Mega#2 median connection duration is 38 minutes & 153 minute max duration; 4 bytes sent by RPi->Arduino, and by Arduino->RPi every 0.2sec

During this testing, they're completely stationary within about 12" of each other, so range should not be an issue.
My RPi code detects a lost connection by virtue of failure to receive a message within 5 seconds, and attempts to reestablish the connection, and that is successful about 80% of the time.  I have a second-tier of lost-connection recovery - resetting the HC-05 via an Arduino-triggered MOSFET - if a message isn't received by the Arduino in ~20 seconds, that works in the remainder of the cases, so I'm ultimately able to systematically recover within a max of about 30 seconds.  However, this lost connection for ~10-30 seconds every 10-60 minutes causes a poor user experience for my remote controls.
The Python errors given for about 95% of the failures are a lack of a receipt of a heartbeat message from the Arduino to the RPi python; about 5% give a unspecific [Errno 5] Input/output error error.
While I'm running down multiple theories via day-long stability tests (longer byte transmissions are more error prone? there's some bug in my Arduino code causing crashes, so remove all logic except the send/receive code to test?), I've read a few posts about how finicky & fragile bluetooth can be, and so I'm curious for some thoughts about the general goal / attempt to get a longer-term (hours to a day or more) connection.
Have folks been able to achieve this with the HC-05 on Arduino?  Or is a dropped connection every 10-60 minutes just something one needs to deal with through robust code?  Thank you.

Speaking only from my personal experience, I've found the Bluetooth implementation on RPi (the 3B+ in particular) to be virtually useless. I've spent hours troubleshooting, but it was never relaible, and in many cases would not connect at all. From reading other Q's on RPi SE I've formed the opinion that others have had similar experiences. Also, I think it's true that RPi 3B+ has only a single antenna for WiFi and BT - which of course makes things difficult if you need them both.

I ultimately found a solution, but for the benefit of others, wanted to share the tests that also did not prove fruitful. TL;DR: Reducing message rate from Arduino's to RPi solved the problem.
My hypotheses to test:

Hypothesis: Faulty Arduino code written by myself. Test: Remove all logic except read / write.
Hypothesis: Something to do with message size. Test: Add an extra arbitrary 80 bytes to the Mega#1 message.
Hypothesis: Too many small messages for RPi to deal with. Test: Reduce message frequency.
Hypothesis: Timing problem or other HC-05 fault as suggested by @stefan-wyss. Test: Swap modules with a 3rd one.
Hypothesis: Faulty RPi python code written by myself. Test: Return to basic python test harness that does nothing except exchange bluetooth messages.

Hypotheses #1 & #2 led to no appreciable difference in failure rate or failure mode.
However, hypothesis #3 was the winner, with both Arduinos running for 12+ hours so far with no severed communications.  (So I did not bother to test #4 & #5).
Specifically, in the original "problem code", there were 20 messages sent every second (and 40 read attempts; I have "overclocked" the receiving in relation to the sending make sure buffers don't fill up due to slight variations in RPi vs. Arduino clocks):

5 sends of 25 bytes by Mega#1 to RPi per second
5 sends of 25 bytes by RPi to Mega#1 per second
5 sends of 4 bytes by Mega#2 to RPi per second
5 sends of 4 bytes by RPi to Mega#2 per second

Some of those didn't really need that frequency to achieve my design goals; so I changed to:

1 send of 25 bytes by Mega#1 to RPi every 2 seconds
5 sends of 25 bytes by RPi to Mega#1 per second
1 send of 4 bytes by Mega#2 to RPi every 2 seconds
5 sends of 4 bytes by RPi to Mega#2 per second

So now, instead of the RPi receiving 10x/second, it receives 1x/second.  (It's still attempting to read 10x per second on each of the two Arduinos to minimize latency, but most of those return no data received). The RPI still has to send 10x/second (5x to each of the two Arduinos).
This simple change fixed the problem. I have no insight as to why the RPi couldn't handle the faster rate of message receipt; some benchmarking on my Python code showed that processing of the received heartbeat messages was not a bottleneck. But the important part, at least for me & the project, is that the problem is solved.

Bluetooth communication works with fixed time intervals that both communication partners have to agree during the advertising and connection phases. Such an agreement could be: "While connected, lets' meet every second. If one does not show up during 3 meetings, let's leave the connection state".
From this you can see that timing is a very important factor in bluetooth communication. So both communication partners need a very accurate clock. No two clocks have exactly the same speed, one is always lagging the other.
It could be that one or multiple of the clocks of your HC-05's do have too much clock drift, so the connection will be lost. Maximum clock deviation allowed for a bluetooth clock is ±40 ppm (i.e. ±40 parts-per-million!) over the entire temperature range.
You could check this theory with multiple HC-05s. If individual modules lead to individual connection lengths, then this could be your problem.

Thanks, Stefan - I'll add that to the test list, and will report back (even if to share still unknown) in a few days after I've run each test for a day or so. Appreciate it.

You can also measure the clocks directly at the crystal if you have access to a timer/counter measurement device and a low capacitance (<1pF) probe.


text:
i build quadcopter using USB HOST SHIELD + NRF24L01 but the data transmit is wrong
I am building mini Arduino quadcopter project. I am using USB host shield for joystick support and nrf24l01 to transmit the data. Unfortunately, I got wrong data transmitted at the receiver and tried many things but doesn't work. I hope you can help me to further my understanding. It is my own first arduino project and it means a lot for me to keep this momentum. Please, guide me. So, i am using maniac library for nrf24l01 https://github.com/maniacbug/RF24/archive/master.zip . USB host shield is use https://www.arduinolibraries.info/libraries/usb-host-shield-library-2-0 . Help me to find out how to get the value that i send instead of getting error value on serial monitor...
This is the serial monitor GettingStarted from tmrh library

Now sending 26291...ok...Failed, response timed out.

Now sending 27494...ok...Got response 27494, round-trip delay: 22

Now sending 28518...ok...Got response 28518, round-trip delay: 22

Now sending 29541...ok...Failed, response timed out.

Now sending 30742...ok...Failed, response timed out.

Now sending 31944...ok...Got response 31944, round-trip delay: 23

Now sending 32968...ok...Got response 32968, round-trip delay: 23

Now sending 33991...ok...Got response 33991, round-trip delay: 23

Now sending 35014...ok...Failed, response timed out.

Now sending 36215...ok...Got response 36215, round-trip delay: 23

Now sending 37239...ok...Got response 37239, round-trip delay: 23

Now sending 38262...ok...Got response 38262, round-trip delay: 23

Now sending 39285...ok...Failed, response timed out.

Now sending 40486...ok...Got response 40486, round-trip delay: 23

Now sending 41510...ok...Failed, response timed out.

This is the output I send from transmitter (Now, I'm using maniac library, because tmrh give irrelevant response and only a joystick response to this, pretty sure)
X: 128   Y: 32   Hat: 0  Twist: 128  Slider: 15  Buttons A: 128  Buttons B: 0
X: 128   Y: 32   Hat: 0  Twist: 128  Slider: 15  Buttons A: 128  Buttons B: 0
X: 128   Y: 32   Hat: 0  Twist: 128  Slider: 15  Buttons A: 128  Buttons B: 0
X: 0     Y: 32   Hat: 0  Twist: 128  Slider: 15  Buttons A: 128  Buttons B: 0
X: 0     Y: 32   Hat: 0  Twist: 128  Slider: 15  Buttons A: 128  Buttons B: 0
X: 0     Y: 32   Hat: 0  Twist: 128  Slider: 15  Buttons A: 128  Buttons B: 0
X: 0     Y: 32   Hat: 0  Twist: 128  Slider: 15  Buttons A: 128  Buttons B: 0

This is what I receive
Throttle: 0    Yaw: 127    Pitch: 127    Roll: 127    Aux1: 0    Aux2: 0
Throttle: 0    Yaw: 127    Pitch: 127    Roll: 127    Aux1: 0    Aux2: 0
Throttle: 0    Yaw: 127    Pitch: 127    Roll: 127    Aux1: 0    Aux2: 0
Throttle: 0    Yaw: 32    Pitch: 0    Roll: 128    Aux1: 15    Aux2: 128
Throttle: 0    Yaw: 32    Pitch: 0    Roll: 128    Aux1: 15    Aux2: 128
Throttle: 0    Yaw: 32    Pitch: 0    Roll: 128    Aux1: 15    Aux2: 128
Throttle: 0    Yaw: 32    Pitch: 0    Roll: 128    Aux1: 15    Aux2: 128
Throttle: 0    Yaw: 32    Pitch: 0    Roll: 128    Aux1: 15    Aux2: 128

Here is my transmitter coding
#include <usbhid.h>
#include <hiduniversal.h>
#include <usbhub.h>

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#include "le3dp_rptparser.h"

RF24 radio(9, 8); // select  CSN  pin
const byte address[6] = "00001"; //IMPORTANT: The same as in the receiver

//byte throttle = 512;       // min: 0 | max: 1023 | center: 512
//byte yaw = 512;       // min: 0 | max: 1023 | center: 512
//byte pitch = 8;       // up: 0 | right-up: 1 | right: 2 | right-down: 3 | down: 4 | left-down: 5 | left: 6 | left-up: 7 | center: 8
//byte roll = 128;   // min: 0 | max: 255 | center: 128
//byte AUX1 = 0;    // min: 0 | max: 255
//byte AUX2 = 0;
//byte joyButtonsB = 0;

  byte throttle ;
  byte yaw ;
  byte pitch ;
  byte roll;
  byte AUX1;
  byte AUX2;
  byte joyButtonsB;

struct MyData {
  byte throttle;
  byte yaw;
  byte pitch;
  byte roll;
  byte AUX1;
  byte AUX2;
};

MyData data;

void resetData()
{
  //This are the start values of each channal
  // Throttle is 0 in order to stop the motors
  //127 is the middle value of the 10ADC.

  data.throttle = 0;
  data.yaw = 127;
  data.pitch = 127;
  data.roll = 127;
  data.AUX1 = 0;
  data.AUX2 = 0;
}

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#include <SPI.h>
#endif

USB                                             Usb;
USBHub                                          Hub(&Usb);
HIDUniversal                                    Hid(&Usb);
JoystickEvents                                  JoyEvents;
JoystickReportParser                            Joy(&JoyEvents);

void setup()
{
  //Start everything up
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();

//  radio.setPayloadSize(32);
  resetData();

  Serial.begin( 115200 );
#if !defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
  Serial.println("Start");

  if (Usb.Init() == -1)
      Serial.println("OSC did not start.");

  delay( 200 );

  if (!Hid.SetReportParser(0, &Joy))
      ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1  );

}

void loop()
{
    //Print all the values into the serial monitor:
    Usb.Task();

  data.throttle = throttle;
  data.yaw      = yaw;
  data.pitch    = pitch;
  data.roll     = roll;
  data.AUX1     = AUX1;
  data.AUX2     = AUX2;
    radio.write(&data, sizeof(MyData));

    Serial.print("X: ");
    Serial.print(data.throttle);
    Serial.print("\t Y: ");
    Serial.print(data.yaw);
    Serial.print("\t Hat: ");
    Serial.print(data.pitch);
    Serial.print("\t Twist: ");
    Serial.print(data.roll);
    Serial.print("\t Slider: ");
    Serial.print(data.AUX1);
    Serial.print("\t Buttons A: ");
    Serial.print(data.AUX2);
    Serial.print("\t Buttons B: ");
    Serial.println(joyButtonsB);
}

void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt)
{
  //Put the values from the joystick in another variable:
  throttle = evt->x;
  yaw = evt->y;
  pitch = evt->hat;
  roll = evt->twist;
  AUX1 = evt->slider;
  AUX2 = evt->buttons_a;
  joyButtonsB = evt->buttons_b;
}

This is the receiver

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
const byte address[6] = "00001";

RF24 radio(9, 8);

struct MyData {
byte throttle; //We define each byte of data input, in this case just 6 channels
byte  yaw;
byte pitch;
byte roll;
byte AUX1;
byte AUX2;
};

MyData data;

void resetData()
{

data.throttle = 0;
data.yaw = 127;
data.pitch = 127;
data.roll = 127;
data.AUX1 = 0;
data.AUX2 = 0;

}

/**************************************************/

void setup()
{
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
}

/**************************************************/

unsigned long lastRecvTime = 0;

void recvData()
{
while ( radio.available() ) {
radio.read(&data, sizeof(MyData));
lastRecvTime = millis(); //here we receive the data
}
}

/**************************************************/

void loop()
{
recvData();
unsigned long now = millis();
//Here we check if we've lost signal, if we did we reset the values
if ( now - lastRecvTime > 1000 ) {
// Signal lost?
resetData();
}

Serial.print("Throttle: "); Serial.print(data.throttle);  Serial.print("    ");
Serial.print("Yaw: ");      Serial.print(data.yaw);       Serial.print("    ");
Serial.print("Pitch: ");    Serial.print(data.pitch);     Serial.print("    ");
Serial.print("Roll: ");     Serial.print(data.roll);      Serial.print("    ");
Serial.print("Aux1: ");     Serial.print(data.AUX1);      Serial.print("    ");
Serial.print("Aux2: ");     Serial.print(data.AUX2);      Serial.print("\n");

}

/**************************************************/

What is the actual result that you are getting? What values are you receiving and how do they correspond to the values that you are sending?  Break your project down to get each bit working properly first. eg, try sending static data instead of data read from the joystick.

Maniacbug's RF24 is rather ancient. Could you please update to TMRh20's RF24, run the GettingStarted sketch on your boards and post the output?

@majenko sure i will post the result I m getting

they give random value only when I turn a joystick to the left
Throttle: 0    Yaw: 127    Pitch: 127    Roll: 127    Aux1: 0    Aux2: 0 Throttle: 0    Yaw: 127    Pitch: 127    Roll: 127    Aux1: 0    Aux2: 0 Throttle: 0    Yaw: 32    Pitch: 0    Roll: 128    Aux1: 15    Aux2: 128 Throttle: 0    Yaw: 32    Pitch: 0    Roll: 128    Aux1: 15    Aux2: 128
this is example I'm sending from transmitter
 X: 128  Y: 32  Hat: 0  Twist: 128  Slider: 15  Buttons A: 128  Buttons B: 0 X: 24  Y: 0  Hat: 0  Twist: 128  Slider: 15  Buttons A: 128  Buttons B: 0

@Avamander i tried both and found out the same output from here tmrh http://tmrh20.github.io/RF24/
I have done the testing for simple code, and it works. the difference i made for this, i think the integer value is assuming the value from joystick is byte and sending it and try to receive it in same byte value. but doesn't work, i still don't get it ... please, really need your helps...

 I have done the testing for simple code, and it works. well then you have made a mistake in your code. Are you aware that there's a limit to how big one payload can be?

correct me if i m wrong, theoretically, 32 bytes maximum, i m sending 6 variable uint8_t cost 4 bytes each total of 24 bytes. I think the value from joystick is not in uint8_t format, i dont know how to know the type of integer of joystick value that I m getting from USB host shield..

can anyone help me, i m so stuck right now, please!


text:
Assigning an element of a multidimensional array to a second array
I have two arrays. The first array is a multidimensional array holding color values.
The 2nd array stores an active color from the 1st array.
How can I assign an element from the multidimensional colors array to the 2nd EXCLUSIVE_COLOR array?
int colors[][3] = {
  { 255, 0, 0 },
  { 0, 255, 0 },
  { 0, 0, 255 },
  { 253, 7, 210 }
};
int EXCLUSIVE_COLOR[3] = {0};

I tried the following but neither seemed to work:
    EXCLUSIVE_COLOR = {
      colors[0][0],
      colors[0][1],
      colors[0][2]
    };
    // error: assigning to an array from an initializer list

    EXCLUSIVE_COLOR = colors[0];
    // error: invalid array assignment

what is the type of EXCLUSIVE_COLOR. you want a pointer to the array or a copy of the array?

Either one would work. EXCLUSIVE_COLOR is a 3 element int array.

int* EXCLUSIVE_COLOR = colors[0];. and then you can use EXCLUSIVE_COLOR[i]

Why do you use a two-dimensional array, if you have a one-dimensional array of Color elements in reality?

You can copy the array:
EXCLUSIVE_COLOR[0] = colors[0][0];
EXCLUSIVE_COLOR[1] = colors[0][1];
EXCLUSIVE_COLOR[2] = colors[0][2];

but this doesn't work in an initialization.
Alternatively, you can declare EXCLUSIVE_COLOR as a pointer to an
array of 3 integers:
int (*EXCLUSIVE_COLOR)[3]; // pointer to array 3 of int

Then you can have this point to a row of the 2D array, either by
assigning the pointer or in the initialization:
int (*EXCLUSIVE_COLOR)[3] = &colors[0];  // initialization

// Later in the program:
EXCLUSIVE_COLOR = &colors[1];

Note that when using this pointer, you will have to explicitly
dereference it:
for (int i = 0; i < 3; i++)
    Serial.println((*EXCLUSIVE_COLOR)[i]);

Edit: As pointed out by Juraj in a comment, you can instead make
EXCLUSIVE_COLOR a pointer to int. In this case you will make it point
to the first element in the row you want:
int* EXCLUSIVE_COLOR = &colors[0][0];

One nice thing of this approach is that you can use the “decay to
pointer” feature of the language to simplify the syntax:
int* EXCLUSIVE_COLOR = colors[0];

// Later
Serial.println(EXCLUSIVE_COLOR[i]);

a pointer to pointer? it doesn't look right

@Juraj: It's not a pointer to pointer, it's a pointer to an array.

Use arrays only where appropriate:
struct Color {byte r, g, b;};
const Color colors[] = {
  {0,255,0},
  {255,0,0}
};
const Color red = colors[1];

This works without const as well. But you should consider using const wherever possible.


text:
How can I list only files that begin with "/LOG?"
Trying to list root directory of LittleFS; but only files beginging with "/LOG."
String str;

                     if (!LittleFS.begin())
                     {
                          Serial.println("LittleFS failed to mount !");
                     }
                     Dir dir = LittleFS.openDir("/");
                     while (dir.next())
                     {

                        if(strncmp(dir.fileName().c_str(), "/LOG", 4) == 0)
                        {

                            str += "";
                            str += dir.fileName();
                            str += "";
                            str += "    ";
                            str += dir.fileSize();
                            str += "
\r\n";
                        }
                     }

                     client.print(str);

If I comment out "if(strncmp(dir.fileName().c_str(), "/LOG", 4) == 0)" and associated braces; all files list.  Code with "if(strncmp(dir.fileName().c_str(), "/LOG", 4) == 0)" no files are listed.
How can I list only files that begin with "/LOG?"
William

And you're sure that the filenames do begin with precisely the characters /LOG ?

Just a sanity check here. But isn't / used as path separator? In my world / is an invalid character for file or directory names. Listed file names in directory / should not contain / then.

@Kwasmich Unless the result of dir.fileName() is the fully qualified absolute path of the file. Which is why I was asking if the filenames really do start /LOG

@Majenko true. Just to make sure nothing gets overlooked. strncmp is case-sensitive!

@Kwasmich Indeed. Not a problem if it's using 8.3 filenames, but could be a problem if the FS uses LFN.

you have a String object returned by fileName and you take the c-string from it to use it in strcmp? String has startsWith. And I guess the listed files don't start with /.

Give a filename String to text...
String text = "/LOGsdfsdf";
if(text.startsWith("/LOG")){
//wee file begins with /LOG
}else{
// wops wrong file.
}

Look in here
https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/
Method url startsWith("");
https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/startswith

FileZilla shows filename as "LOG0608.TXT."  Naming convention is "LOG + Month + Date + '.TXT'."    I could have carried the "/" over from the web server.

Need "dir.fileName()" to compare acutal filename to LOG0608.TXT.  I only want files starting with "LOG" to be displayed.

Dose dir.fileName() gives a string as "LOGXXXX.TXT" or "/LOGXXXX.TXT"

Used:  String file_name = dir.fileName();
        if(file_name.startsWith("LOG"))
        {                                                                               Thanks!

gr8 glad I can help you


text:
When trying to write multiple bytes to a serial port, all 0x00s are skipped
I am using a dynamixel XL320 servo, and am trying to control it using an Arduino Uno. I’m trying to send a simple packet that turns on an LED. I believe the correct format of this packet according to the dynamixel documentation is the following: FF FF FD 00 01 09 00 03 19 00 01 00 00 00 3F 1D (However, the correctness of this packet at the moment is ultimately unimportant to my problem). Before actually writing any more of my servo library, I decided to try to just send an array using Serial.write, to ensure that would transmit properly. I used puTTY session logging, and then a hex editor to track what was actually sent. The results are:
FF FF FD 01 09 03 19 01 3F 1D.
I’ve seen other issues where 0x00 is interpreted as null in a string and so a string like 0x10, 0x00, 0xDD would only send 0x10. But here as an array that shouldn’t be a problem. Here, it seems like the 00’s are just being skipped. Would really appreciate help here, and please let me know if more clarity is needed this is first time posting here.
My code for this test is as simple as I could think to make it:
Serial.begin(9600);
while(!Serial) {;}
uint8_t data[16]= {0xFF, 0xFF, 0xFD, 0x00, 0x01, 0x09, 0x00, 0x03, 0x19, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3F, 0x1D};
Serial.write(data, sizeof(data));```

Works for me. Are you sure PuTTY is not messing up with your bytes?

I would certainly second Edgar's sentiment. The biggest suspect is your receiving setup, not the Arduino.

I’m not sure, that could be true. How did either of you set up the receiving end?


text:
How to write to the second line of a display?
I got this 4 line display from Mouser: https://www.gravitech.us/20chbllcd.html, and I get it to work fine for lines 1 and 3 (as line 3 is just the 21st character of line 1). But I am struggling to get lines 2 and 4 working. If I understand correctly, these are "line 2" for the HD44780 controller, and I should set the DDRAM address to 0x40 before I write there.
But, when I try that, nothing happens.
I tried writing 0x04 to the DDRAM address counter, and I can see the cursor jumping there, but when I write to that address, no text shows up. If I omit the command, text pops up correctly.
Also, when changing the contrast of the display (using the potentiometer on the Vdd and Vo pins), only lines 1 and 3 change contrast.
My code:
This method I use for convenience:
void set(int _rs, int _rw, int _d7, int _d6, int _d5, int _d4, int _d3, int _d2, int _d1, int _d0) { ... }

To set the DDRAM address to 0x40:
set(0,0,1,1,0,0,0,0,0,0);

The general timing and control is correct, as I can get text on the display, and also a function like "shift" works fine.

You're not using the standard LiquidCrystal.h library?

@Majenko no, not yet. If I cannot get this to work myself, I'll try and see if that can work. I looked at the LiquidCrystal source code though, and I didn't see anything I could use.

Personally I would start with the known working, well tested, and properly supported LiquidCrystal.h library, and then pare it down to just the code I needed (if code size were an issue). As it is we can't really help you since we don't know your code or setup.

Line 1 starts at address 0x00 | 0x80 0b10000000 and ends at 0x13 | 0x80 0b10010011
Line 2 starts at address 0x40 | 0x80 0b11000000 and ends at 0x53 | 0x80 0b11010011
Line 3 starts at address 0x14 | 0x80 0b10010100 and ends at 0x27 | 0x80 0b10100111
Line 4 starts at address 0x54 | 0x80 0b11010100 and ends at 0x67 | 0x80 0b11100111

That 0x80 0b10000000  is the HD44780 command for set DDRAM address. The other bits 0b1xxxxxx define the address.

You'll find more details at Arduino with HD44780 based Character LCDs

Yes. That's what I said.

You need to setup the HD44780 in 2-line mode. The command is | 0 | 0 | 1 | DL | N | F | X | X | with:

DL: 0 = 4-bit / 1 = 8-bit interface
N: 0 = 1 line / 1 = 2 lines (this is the bit to set)
F: 0 = 5x7 / 1 = 5x10 font size

Most probably you have that command already in your program to set the width of the interface, but with N = 0.
Note: The common algorithm is to send the command 0x33 three times to make sure to be in 8-bit mode. The first can be the second part of a half-done 4-bit command, possibly not changing the interface width. Then the second and third will switch into 8-bit mode. If the device is already in 8-bit mode, or gets into it in the course, it makes no harm to repeat.
Since in 4-bit mode only D7 to D4 are used, you can change 0x33 into 0x38 to enable the 2-lines mode.


text:
SIM800L and DTH22
I am very new to arduino. I am build a model that will require SIM800L and DTH22. I want to know if I can power both from my arduino. DTH22 has a wide range of input voltage but I doubt of SIM800L. It says 3.4V-4.4V but one arduino forum said that it requires 2Amps of current. But many people simply connect it to arduino 3.3V. Can anyone with experience tell me about this? (I am asking as I fried the microcontroller in my previous project.) Should I get externel power supply or go forward with arduino?

What does the documentation with your SIM800L module say about how it should be powered? The Data Sheet states a maximum current of 2.0A during Tx burst and 200-450 mA in other modes. I would not recommend using the Arduino internal power supply. The DHT22 uses almost no power at all and can be easily powered from the Arduino.

Do not connect any GSM module to an Arduino board 3.3v
This SimCom GSM modules like sim800L or sim800C can take burst current of 2Amp in low network area to provide proper network and another thing is that below 3.4v and above 4.4v it will shut down automatically and you will get an Undervoltage & overvoltage warning AT response on UART before shutdown.
Another thing is that the 3.3v voltage regulator on the Arduino board can only handle up to 1Amp max and above 500ma consumption its temperature will rise and near 1A even more.
So the conclusion don't provide supply to sim800l from Arduino.