Create a dead zone for joystick I'm trying to create a dead zone so the joystick will turn the motor off completely when in the center position. It's much too sensitive and will start the motor if barely touched. How could I fix the code so the off position of the joystick is bigger? This is the original code.
#include <Servo.h> //Using servo library to control ESC

Servo esc; //Creating a servo class with name as esc

void setup()
{
  esc.attach(9); //Specify the esc signal pin,Here as D9
  esc.writeMicroseconds(1000); //initialize the signal to 1000
  Serial.begin(9600);
}

void loop()
{
  int val; //Creating a variable val
  val = analogRead(A0); //Read input from analog pin a0 and store in val
  val = map(val, 0, 1023, 1000, 2000); //mapping val to minimum and maximum(Change if needed)
  esc.writeMicroseconds(val); //using val as the signal to esc
}

Here's how to create the new mapped range with a dead zone. I used Servo.write() which specifies the position in degrees because I couldn't understand what microsecond timings you need, but it should be easy to change it back. I've also added some debug statements to print val as the joystick is moved.
#include <Servo.h>

// Constants for servo angles in degrees.
const int SERVO_MIN = 0;
const int SERVO_MID = 90;
const int SERVO_MAX = 180;

// Constants for raw ADC values of joystick positions.
const int ANALOGUE_MIN = 0;
const int ANALOGUE_MID = 512;
const int ANALOGUE_MAX = 1023;
const int ANALOGUE_THRESHOLD = 100;

Servo esc;

void setup()
{
  esc.attach(9);         // Specify the esc signal pin as D9.
  esc.write(SERVO_MID);  // Move servo to mid position in degrees.
  Serial.begin(115200);
  Serial.println();
  Serial.println("Servo Test");
}

void loop()
{
  static int old_val = -1;   // Initialise to invalid value.
  int val = analogRead(A0);  // Read input from analogue pin A0.

  // Process val if it has changed.
  if (val != old_val)
  {
    old_val = val;
    Serial.print(val);
    Serial.print(", ");

    // Create the dead zone as per Majenko's algorithm.
    val -= ANALOGUE_MID;
    int direction = val < 0 ? -1 : +1;
    val = abs(val);
    val -= ANALOGUE_THRESHOLD;
    if (val < 0) val = 0;

    // Create a new mapped range with a dead zone.
    val *= direction;
    val += ANALOGUE_MID;
    Serial.print(val);
    Serial.print(", ");
    val = map(val, ANALOGUE_MIN + ANALOGUE_THRESHOLD, ANALOGUE_MAX - ANALOGUE_THRESHOLD, SERVO_MIN, SERVO_MAX);
    Serial.println(val);

    // Move servo to new angle in degrees.
    esc.write(val);
  }
}


Can I integrate Arduino in a CI/CD setup? While it seems less valuable to emulate Arduino in a CI/CD setup, are there any experiences/best practices for collaborative teams to automate their acceptance tests where a real Arduino is integrated into a CI/CD toolchain (or, what are comparable practices)?

Minimal example of acceptance testing:

compilation is successful for a given compiler version.

There are different approaches around. I can only point you to some of them:

GitLab CI approach A
GitLab CI approach B
Your specific solution: To build pipelines for Arduino (although its Azure) but you can use this technique on Linux with Jenkins

As a valuable commenter mentioned on your previous question - this does not cover the attached hardware testing (sensors/ motors) - this has to be "integrated" via a test lab station, which you have to control manually (or semi-automated via lab equipment) on defined release/version changes


Shield board with holes, do I need to solder? I have a motor shield.
I can put it on top of my arduino Mega and works perfect.

However, since the shield plugs in on top of the arduino board, I don't have access to 5V and GND from Arduino Mega.

I just have holes on the board with 5V and GND. (look at image)

Do I have to solder a cable there to have access to 5V and GND? or there is another easier way?

Since there are two grounds, a 2-pin terminal block of the type already on the board may fit. Or, since the shield doesn't obscure the far end of the Mega (the end with the high numbered I/Os), you could pick up 5V and Gnd there. The ends of the double-row female header have respectively, 2 each 5V and Gnd connectors. You would pick those up with breadboard wires, though it is admittedly less secure.


Why does this take more byte? I am only replacing a portion of my code where I want to use the first method but as you can see it is making my sketch size little bigger

//if(iBPM >= 40 || iBPM <= 170 )
      {
      char iBPMwav[50];
      String thisString = String(iBPM);
      String stringThree =  "n" + thisString;
      stringThree =  stringThree + ".wav";
      stringThree.toCharArray(iBPMwav, 50);
      tmrpcm.play(iBPMwav);
      }

Sketch uses 29678 bytes (100%)

This is simple but at the end, I want to go from the number 40 up to 170, and this is why I want to use the first method.

//if(iBPM >= 40 || iBPM <= 170 )
  {
      if(iBPM == 71)
tmrpcm.play("n71.wav");
  else if(iBPM == 72)
tmrpcm.play("n72.wav");
  else if(iBPM == 73)
tmrpcm.play("n73.wav");
  else if(iBPM == 74)
tmrpcm.play("n74.wav");
  else if(iBPM == 75)
tmrpcm.play("n75.wav");
  else if(iBPM == 76)
tmrpcm.play("n76.wav");
  else if(iBPM == 77)
tmrpcm.play("n77.wav");
  else if(iBPM == 78)
tmrpcm.play("n78.wav");
  else if(iBPM == 79)
tmrpcm.play("n79.wav");
  else if(iBPM == 80)
tmrpcm.play("n80.wav");
  else if(iBPM == 81)
tmrpcm.play("n81.wav");
  else if(iBPM == 82)
tmrpcm.play("n82.wav");
  else if(iBPM == 83)
tmrpcm.play("n83.wav");
  else if(iBPM == 84)
tmrpcm.play("n84.wav");
  else if(iBPM == 85)
tmrpcm.play("n85.wav");
  else if(iBPM == 86)
tmrpcm.play("n86.wav");
  else if(iBPM == 87)
tmrpcm.play("n87.wav");
  else if(iBPM == 89)
tmrpcm.play("n89.wav");
  else if(iBPM == 90)
tmrpcm.play("n90.wav");
  else if(iBPM == 91)
tmrpcm.play("n91.wav");
  else if(iBPM == 92)
tmrpcm.play("n92.wav");
  else if(iBPM == 93)
tmrpcm.play("n93.wav");
  else if(iBPM == 94)
tmrpcm.play("n94.wav");
  else if(iBPM == 95)
tmrpcm.play("n95.wav");
  else if(iBPM == 96)
tmrpcm.play("n96.wav");
  else if(iBPM == 97)
tmrpcm.play("n97.wav");
  else if(iBPM == 98)
tmrpcm.play("n98.wav");
  else if(iBPM == 99)
tmrpcm.play("n99.wav");
  else if(iBPM == 100)
tmrpcm.play("n100.wav");
  else if(iBPM == 101)
tmrpcm.play("n101.wav");
  else if(iBPM == 102)
tmrpcm.play("n102.wav");
else
 tmrpcm.play("n170.wav");
}

Sketch uses 29024 bytes (101%)

I suggest having simpler file names (same size, always 3 digit numbers)

/// Return a text "n000.wav" ... "n255.wav"
/// depending on the parameter
char* makeFileName(byte i) {
  static char name[9] = "nxxx.wav";
  byte digit = i/100;
  name[1] = '0' + digit;
  i -= digit*100;
  digit = i/10;
  name[2] = '0' + digit;
  i -= digit*10;
  name[3] = '0' + i;

  return name;
}


How can I control 4 DC motors with an Arduino? In a few months, I am planning to construct an Arduino robot with multiple sensors etc. I will use an arduino mega and a 4wd chassis like the one here: Chassis.  The chassis uses 4 DC motors. I was planning to use a motor shield, but I realized that it only fits an Arduino Uno(not Mega) and it controls only 2 DC motors. What can I do to make all 4 DC motors move forward and backward? If I use a motor driver board that controls 2 motors, can I connect the 2 right and 2 left motors in parallel together and the control it through the Arduino?

Yes, you can do this using 2 L293D motor drivers, each motor driver can run 2 motors and it is very easy to use.

You should connect Vcc 1(used to power on the chip) to 5V and Vcc 2 to a power supply that is needed to run your motors, Enable 1,2 and Enable 3,4 are used to enable the 2 sides of the chip and should be connected to 5V. Outputs 1-4 are the outputs to 2 motors and Inputs 1-4 are the inputs from the micro-controller.


Bit Number to Byte Value conversion (AVR Docs) I have hard time to understand what this doc tells me: https://www.microchip.com/webdoc/AVRLibcReferenceManual/FAQ_1faq_use_bv.html

I has a macro called _BV that

  convert a bit number (usually within a byte register) into a byte value

And the example tells this

  _BV(3) => 1 << 3 => 0x08

I am kinda used to bits and bytes etc. But I don't understand what the 3 in this example is? It says it converts a bit number but 3 is not binary it is an integer. And the macro resolves it to 0x08 which is the value of 8 in decimal.

I am very confused. I hope someone can explain to me what is happening here!

The bits within a byte are numbered 0 through 7 from right to left. The
rightmost (least significant) is bit 0, next is bit 1... and the
leftmost (most significant) is bit 7.

The expression _BV(3) builds a byte where bit 3 is set (is 1) and all
other bits are clear (are 0). In binary it looks like this:

position:   7  6  5  4  3  2  1  0
bit value:  0  0  0  0  1  0  0  0

The macro expands to 1<<3, which takes the integer 1 (0b00000001 in
binary) and shifts all its bits by three positions to the left. The
result can be written 0b00001000 in binary, 0x08 in hexadecimal, and 8
in decimal.


Transfer 10-bit via Arduino-to-Arduino SPI protocol The task I need to accomplish is as follows:

I have an analog/digital converter that sends out a 10-bit signal. This signal needs to be transferred to an Arduino Uno using the SPI protocol. Because the SPI protocol works with a 16 bit pattern I need to expand the incoming signal. The slave Arduino then needs to put out the transferred number in decimal.

I imitated the ADC with another Arduino Uno, setting it as master, but unfortunately at the time I only had one Arduino so I couldn't test my code. Furthermore, I don't really have a clue how to "expand" a 10-bit signal to a 16-bit one. Can someone please explain it to me and have a look at my code?

Code for the master Arduino:

#include <SPI.h>
#define SS 10
#define MOSI 11

void setup() {
  pinMode(SS, OUTPUT);
  pinMode(MOSI, OUTPUT);
  SPI.beginTransaction(SPISettings(62500, LSBFIRST, SPI_MODE0));
}

void loop() {
  byte x=0000001101;
  byte y=0011111111;
  digitalWrite(SS,LOW);
  SPI.transfer(x,y);
  digitalWrite(SS,HIGH);
  delay(1000);
}

Code for the slave Arduino:

#include <SPI.h>
#define SS 10
#define MOSI 11

void setup() {
  pinMode(SS, INPUT);
  pinMode(MOSI, INPUT);
}

void loop() {
  byte x=SPDR;
  byte y=SPDR;
  printf(x,DEC);
  printf(y,DEC);
  delay(1000);
}

A byte is only 8 bits, so your code:

  byte x=0000001101;
  byte y=0011111111;

won't do what you think it does.

A 10 bit value will be stored as an int (which is 16 bits) or 2 bytes.

Assuming it is an int then this will convert it to two bytes.

 const int adcData = 0x03FF;  // From ADC
 byte dataToSend[2] = {0, 0}; // Initialise it to zeros
 dataToSend[0] = (adcData & 0xFF00) >> 8;  // didn't really need the bit mask just to make it clearer.
 dataToSend[1] = (adcData & 0x00FF);
 // Now send dataToSend via the SPI bus.

To reassemble the data on the otherside:

 byte dataReadFromSPI[2];  // Filled with the data read from the SPI
 int adcData = 0;
 adcData = (dataReadFromSPI[0] << 8) | (dataReadFromSPI[1]);


How do I connect this display to an Arduino Uno I am completely new to this, and a novice when it comes to electronics but I want to learn.
Can someone pls tell me how I would connect the display in the photo here with an Arduino Uno (which I have ordered).  The plan is to interface my car with this transparent display to produce a form of HUD.
I have done some searching but to no avail so far, would appreciate being pointed in the right direction.
many thanks

You're in for a lot of work. Everything on the PCB is useless to you, so you'd have to interface the raw panel to the Arduino.

The first matter is to remove the panel from the board. You will need to desolder all of the connections, and then solder either some sort of rigid connector or individual wires to the large ribbon connector. The only advice I can give you is "be prepared to fail".

Once you've done that, you will need to read AVR340 in order to learn how to drive the panel. Note that the Uno itself does not have enough pins to drive the panel directly, so you will need to get an I/O expander or two for this.

Did I mention that you're in for a lot of work? Well, I'm mentioning it again. Good luck though.


Updating a sketch to work with IDE 1.6.6 I've got a MAX7456 chip and I am using this (this is the unmodified one) library with it.
There's a sketch inside the examples folder (Max7456WriteTable) that I need to get to work to update the character table.

I modified three lines and then I got really stuck as I do not know how to continue. This is the modified one.

In file included from Max7456Write.ino:2:0:
/tmp/build4608284042510222737.tmp/sketch/Max7456WriteTable.h:29:69153: warning: narrowing conversion of '243' from 'int' to 'const char' inside { } is ill-formed in C++11 [-Wnarrowing]

This happens for every item in the array. But that is not the only problem. (I'll skip a few hundred lines)

/tmp/build8855411239666100148.tmp/sketch/Max7456Write.cpp.o: In function `setup':
/home/t/Max7456Write.ino:13: undefined reference to `Max7456::Max7456(unsigned char)'
/home/t/Max7456Write.ino:19: undefined reference to `Max7456::activateOSD(bool)'
/home/t/Max7456Write.ino:44: undefined reference to `Max7456::getCARACFromProgMem(char const*, unsigned char, unsigned char*)'
/home/t/Max7456Write.ino:46: undefined reference to `Max7456::sendCharacter(unsigned char const*, unsigned char, unsigned char)'
collect2: error: ld returned 1 exit status
Error compiling.

It takes a huge amount of time for it to abort the compilation.

If I change prog_uchar to unsigned char in both max7456.h and max7456.cpp the hello world example sketch compiles.

In Max7456WriteTable change

Max7456::getCARACFromProgMem(i,currentChar); //Because the table is too big for ram memory

osd->sendCharacter(currentChar,i); //We send currentChar at address i.

to

Max7456::getCARACFromProgMem(tableOfAllCharacters, i,currentChar); //Because the table is too big for ram memory

osd->sendCharacter(currentChar,i, 0); //We send currentChar at address i.

0 is probably the wrong value, but at least it compiles.


How do i fix the "A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header" I have an AI Thinker ESP32-CAM and I've had issues uploading the CameraWebServer sketch, every time I hit upload it says "A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header" and I've tried everything that I can think of, I disconnected and reconnected all the connections on my FTDI board and I've done all sorts of button presses during the connection, I've switched the voltage and I've bought a whole new board and I don't know what the issue is or how to fix it.

ESP32 only works with 3.3 V serial do not switch the FTDL voltage to 5 V

Watch out for the serial connections too

U0R-->TX

U0T-->RX

If you mixed it up it won't work!

First of all you need to connect two pins only when uploading
It is all ready fixed for you need to press the rest button when uploading
and seeing these dots as below image.

ESP32-CAM on-board RST button Press and hold until you see uploading

After a few seconds, the code should be successfully uploaded to your board.

I hope this helped for you!

You can reffer to this link for more info

https://randomnerdtutorials.com/esp32-cam-take-photo-display-web-server/


Switch setting 'running' state boolean doesn't hold I have a rotary encoder and I want to use the switch to stop the rest of my code running, essentially switching off what I have going on.

I have this

boolean running = true;

void setup() {
  pinMode(swPin, INPUT);
  digitalWrite(swPin, HIGH);;
}

void loop() {

  if(digitalRead(swPin) == LOW) {
    running = !running;
  }

  if(running) {
    ...
  }
}

When I enter the if statement catching the switch press running does become false and the rest of the code is stopped. However, once released; running is becoming true again and the rest starts again.

I guess it is because the rotary encoder isn't fixed in the LOW state but I expected the running variable to be set to false and remain since it is declared outside of the loop().

Any guidance would be much appreciated!!

Thanks to @Manjenko's comment I was able to see my error.

Here is my solution:

boolean running = true;
int swReading;
int swPrevious = LOW;

void setup() {
  pinMode(swPin, INPUT);
  digitalWrite(swPin, HIGH);;
}

void loop() {

  swReading = digitalRead(swPin);

  if(swReading == LOW && swPrevious == HIGH) {
    running = !running;
  }
  swPrevious = swReading;

  if(running) {
    ...
  }
}


Can I control my Arduino using just a 2.4GHz Wireless Transceiver and a wireless Xbox 360 controller? I want to control my Arduino using my wireless Xbox 360 controller. I've been looking up tutorials, and they all seem to recommend using a USB shield and the Xbox 360 wireless receiver.

I don't own either of those things, but I do own a 2.4 GHz wireless transceiver. Can I use it to listen to what buttons are being pressed on the controller? For example, if I press the A button on the controller, can I make an LED turn on?

Short answer is no, unless you have the machine and tools to do reverse engineering on the xbox controller proprietary 2.4Ghz protocol and you must have xbox 360 itself to see what goes on between Xbox 360 and the xBox controller. The time and money spent on these tools(hardware and software) aren't worth it.

The easiest way to do this is to buy the xbox controller receiver, Arduino USB shield and you can easily use your xbox 360 controller with your Arduino.


Count fuel liters with Arduino We have created a fuel sensor in our lab with Arduino in order to get fuel data from vehicles. Regarding the code below, I receive an error

  PARSE ERROR: 'attachInterrupt': this function needs to be defined.

Could you please advice?

int pin = 2;
volatile unsigned int pulse;
float volume = 0;
float flow_rate =0;
const int pulses_per_litre = 2000;
int count_pulse;

void setup()
{
    Serial.begin(9600);
    pinMode(pin, INPUT);
    attachInterrupt(0, count_pulse, RISING);

}

void loop()
{
    pulse=0;
    interrupts();
    delay(1000);
    noInterrupts();

    Serial.print("Pulses per second: ");
    Serial.println(pulse);

    flow_rate = pulse * 1000/pulses_per_litre; //

    Serial.print("FUEL FLOW rate: ");
    Serial.print(flow_rate);
    Serial.println(" milliliters per second");

    volume = volume + flow_rate * 0.1; //Time Interval is 0.1 second

    Serial.print("Volume: ");
    Serial.print(volume);
    Serial.println(" milliliters");
}

void count_pulse()
{
pulse++;}

You have declared count_pulse as a variable and NOT as function prototype.

int pin = 2;
volatile unsigned int pulse;
float volume = 0;
float flow_rate =0;
const int pulses_per_litre = 2000;

void count_pulse(); \\ <--- Function prototype

void setup()
{
    Serial.begin(9600);
    pinMode(pin, INPUT);
    attachInterrupt(0, count_pulse, RISING);
}


Can the arduino be recognized if the usb chip is broken? My question might seem one of the million questions out there "Can't upload to arduino uno and receive error avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x01" but as I probably read all the million questions and didn't find the answer I am looking for I decided to write my own.

So my arduino is properly detected in device manager and in the arduino IDE but cant upload sketches to it. The main chip (atmega328p) seems well (13-pin LED blinks 3 times on reset) but the usb chip (ATmega16u2) is what I suspect as the RX and TX LEDs don't blink while uploading (and don't blink in any other situation) but again the arduino is detected and I am sure I chose the right board and port.

The serial monitor is always empty and I tried the loopback test and didn't get any echo at all or even any error message but I think that what I should have expected as the RX and TX not blinking means that there is no data transmission in the first place. Or am I wrong?

So is the USB chip broken or maybe corrupt? How can I be sure? And if not then what could the problem be?

I saw a tutorial in the answer of this question to test the usb chip using another arduino but I don't have that in hand right now or an ICSP programmer for that matter.

It depends on the exact arduino product. An Arduino Uno has a USB programmer chip, that then programs the AtMega 328 Chip. If the programmer is broken, it will likely not register any device when you plug in an arduino uno to your PC.

if the micro-controller is dead, but the programmer is operational, you will get a device in your device manager, but not be able to reprogram the micro controller.

If both the programmer, and the micro-controller are broken, then figuting that out could be difficult. The AVR microcontrolers support other programing methods, and the AtMega 328 IC, supports DebugWire. you could attempt to reprogram the MCU out side of the programmer, if you thought the programmer, was defective.

Here is a great article on using DeBugWire.
https://awtfy.com/2010/02/21/modify-an-arduino-for-debugwire/

another nifty trick I learned, is to take your Digital MultiMeter, set it to diode test, or continuity. then, measure between the ground pin, and the positive voltage pins on the MCU.  If you get a shot, the chip is busted. You will expect to get roughly 0.7Volts, although an OL reading might indicate more about your multi-meter, than the MCU.

Other Arduino devices, that have integrated USB programing, may behave differently. Features of the specific MCU dictate how it can be debugged. You might want to read the datasheet for a specific MCU if you're having trouble.


How do I make a counter that counts the amount of active inputs I want to make a direction guide using green, yellow and red LEDs. The lights need to change when ever the active input1 reaches a set value, for example:

Green when the value is lower than 12;
Yellow when the value is higher than 11 and lower than 20;
Red when its higher than 19.

I've been searching for a few days but I couldn't find any references.

1 By active inputs I mean, a series of buttons being pressed at the same time, if there is 29 buttons then when less then 12 of them is pressed the green light would be turned on.

You need something like:

const int BUTTON_MAX = 29;
const int button[BUTTON_MAX] = { 5, 6, 7, ... };
const int GREEN_LED = 2;
const int YELLOW_LED = 3;
const int RED_LED = 4;
int current_led;

void setup()
{
   // Setup inputs (buttons)
   for (int i = 0; i < BUTTON_MAX; i++) pinMode(button[i], INPUT_PULLUP);

   // Setup outputs (led)
   pinMode(GREEN_LED, OUTPUT);
   pinMode(YELLOW_LED, OUTPUT);
   pinMode(RED_LED, OUTPUT);

   // Initial state
   current_led = GREEN_LED;
   digitalWrite(GREEN_LED, HIGH);
   digitalWrite(YELLOW_LED, LOW);
   digitalWrite(RED_LED, LOW);
}

void loop()
{
   // Count number of active buttons
   int count = 0;
   for (int i = 0; i < BUTTON_MAX; i++) count += digitalRead(button[i]);

   // Map number of active buttons to led
   int new_led;
   if (count < 12)
      new_led = GREEN_LED;
   else if (count < 20)
      new_led = YELLOW_LED;
   else
      new_led = RED_LED;

   // Check for change and update
   if (new_led != current_led) {
      digitalWrite(current_led, LOW);
      digitalWrite(new_led, HIGH);
      current_led = new_led;
   }

   // Add a few milli-seconds for debounce
   delay(20);
}


Multiple defintion error, Linker error Trying to create an elf file for two sets of files in different folders.

LIDARBOT.h
-----------
#ifndef LIDARBOT_H_
#define LIDARBOT_H_

#include <avr/io.h>
#include "drivers/motors.h"

#endif

LIDARBOT.C
----------
#include "LIDARBOT.h"
int main(){
  pwmtimersetup();
    while (1) {
    }
}

motors.h
--------
#ifndef MOTORS_H_
#define MOTORS_H_

#include <avr/io.h>

void pwmtimersetup(void);

#endif

motors.c
--------
#include <avr/io.h>
#include "motors.h"

void pwmtimersetup(void){
  // Timer pre-scalar for ~490 Hz is 8
  TCCR0B &= ~((1<<CS02)||(1<<CS00));
  TCCR0B |=  (1<<CS01);
  // Set Compare Output Mode to Toggle PWM
  TCCR0A &= ~(1<<COM0A1);
  TCCR0A |=  (1<<COM0A0);
  // Waveform Generation Mode: WGM02 = 1, WGM01 = 1, WGM00 = 1
  TCCR0B |= (1<<WGM02);
  TCCR0A |= (1<<WGM01)||(1<<WGM00);
  OCR0A = 125;
  DDRD |= (1<<DDD4)||(1<<DDD2);
  PORTD |= (1<<PORTD4);
  PORTD &= (1<<PORTD2);
}

I can make a consolidated object file but not an elf file to load onto my board. Output below:

avr-gcc -g -Os -Wall -Werror -Wextra  -mmcu=atmega328p -DF_CPU=1000000UL -Wa,-ahlmns=LIDARBOT.lst -o objects/LIDARBOT.o \
source/LIDARBOT.c \
source/drivers/motors.c \
-I/home/manu/C/Arduino/LIDARBOT/libraries/

avr-gcc -g -Os -Wall -Werror -Wextra -mmcu=atmega328p -DF_CPU=1000000UL -o elf/LIDARBOT.elf objects/LIDARBOT.o
objects/LIDARBOT.o: In function `__vector_22':
(.text+0x7c): multiple definition of `__bad_interrupt'
/usr/lib/gcc/avr/5.4.0/../../../avr/lib/avr5/crtatmega328p.o:(.text+0x0): first defined here
objects/LIDARBOT.o: In function `__vectors':
(.text+0x0): multiple definition of `__vectors'
/usr/lib/gcc/avr/5.4.0/../../../avr/lib/avr5/crtatmega328p.o:(.vectors+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [Makefile:191: elf] Error 1

I am kind of lost. What could be my mistake here? If I see an error like this how do i start to debug?

You forgot the -c flag to your first command. That means you have first compiled your program into a full elf file. Then you try to link that elf file with the standard startup libraries again (it already contains them) into another new elf file.

And so you get duplicate entries in it.

Add -c to your first command, which means "compile only, don't link" to create object files not an elf file.


Timer for how long button is not pressed I would like to timer for how long a button is not pressed. So actually if(buttonState == LOW 'for two seconds') than execute the code that comes after it. But the problem is while the user is still pressing the button the timer already starts.

Code:

int ledPin[] = {7,8,9,10};
int ledPin11 = 11;
long randNumber;
const int buttonPin = 2;
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;
unsigned long previousMillis = 0;
const long interval = 2000;

void setup() {
 Serial.begin(9600);
 pinMode(LED_BUILTIN, OUTPUT);
 randomSeed(analogRead(0));
 randNumber = random(1, 16);
 Serial.println(randNumber);
 for (int i = 0; i < 4; i++) {
   pinMode(ledPin[i], OUTPUT);
 }
  pinMode(buttonPin, INPUT);
 }

 void loop() {
  displayBinary(randNumber); //functie 'display binary'
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis >= interval){
    previousMillis = currentMillis;
    if(buttonState == LOW){
    antwoord(buttonPushCounter,randNumber);
    delay(5000);
    displayBinary(randNumber);
  }
 }
 buttonState = digitalRead(buttonPin);
 if (buttonState != lastButtonState) { // als de button word ingedrukt krijgt buttonPushCounter + 1
 if (buttonState == HIGH) {
  buttonPushCounter++;
  Serial.print("Nummer hoe vaak is gedrukt");
  Serial.println(buttonPushCounter);
 } else {
  Serial.println("off");
}
delay(250);
 }
}

void antwoord(int teller, int antwoord) {
 if (teller == antwoord) {
  for (int i = 0; i < 4; i++) {
  pinMode(ledPin[i], LOW);
 }
 digitalWrite(LED_BUILTIN, HIGH);
 delay(250);
 digitalWrite(LED_BUILTIN, LOW);
 delay(250);
 digitalWrite(LED_BUILTIN, HIGH);
 delay(250);
 } else if (teller > antwoord || teller < antwoord) {
   for (int i = 0; i < 4; i++) {
    pinMode(ledPin[i], LOW);
  }
    digitalWrite(LED_BUILTIN, HIGH);
  }
}

void displayBinary(byte numToShow) //van byte naar decimaal
  {
   for (int i = 0; i < 4; i++) {
    if (bitRead(numToShow, i) == 1) {
    digitalWrite(ledPin[i], HIGH);
    } else {
      digitalWrite(ledPin[i], LOW);
    }
   }
  }

I would start a timer when the button changes state. Then you timeout if
the button is released and it hasn't changed state for too long:

void loop()
{
    static int lastButtonState;
    static unsigned long buttonChangeTime;
    int buttonState = digitalRead(buttonPin);
    unsigned long now = millis();

    // Record time when button changes state.
    if (buttonState != lastButtonState)
        buttonChangeTime = now;

    // Timeout if button is not pushed for too long.
    if (buttonState == LOW && now - buttonChangeTime >= interval)
        Serial.println("Timeout.");

    lastButtonState = buttonState;
}

Don't forget to update lastButtonState on each iteration.


Results for GP2Y1010AU0F Dust Sensor I am using Dust Sensor GP2Y1010AU0F

I downloaded the code from the manufacturer here:
http://www.waveshare.com/wiki/Dust_Sensor

/*********************************************************************************************************
*
* File                : DustSensor
* Hardware Environment:
* Build Environment   : Arduino
* Version             : V1.0.5-r2
* By                  : WaveShare
*
*                                  (c) Copyright 2005-2011, WaveShare
*                                       http://www.waveshare.net
*                                       http://www.waveshare.com
*                                          All Rights Reserved
*
*********************************************************************************************************/
#define        COV_RATIO                       0.2            //ug/mmm / mv
#define        NO_DUST_VOLTAGE                 400            //mv
#define        SYS_VOLTAGE                     5000

/*
I/O define
*/
const int iled = 7;                                            //drive the led of sensor
const int vout = 0;                                            //analog input

/*
variable
*/
float density, voltage;
int   adcvalue;

/*
private function
*/
int Filter(int m)
{
  static int flag_first = 0, _buff[10], sum;
  const int _buff_max = 10;
  int i;

  if(flag_first == 0)
  {
    flag_first = 1;

    for(i = 0, sum = 0; i < _buff_max; i++)
    {
      _buff[i] = m;
      sum += _buff[i];
    }
    return m;
  }
  else
  {
    sum -= _buff[0];
    for(i = 0; i < (_buff_max - 1); i++)
    {
      _buff[i] = _buff[i + 1];
    }
    _buff[9] = m;
    sum += _buff[9];

    i = sum / 10.0;
    return i;
  }
}

void setup(void)
{
  pinMode(iled, OUTPUT);
  digitalWrite(iled, LOW);                                     //iled default closed

  Serial.begin(9600);                                         //send and receive at 9600 baud
  Serial.print("*********************************** WaveShare ***********************************\n");
}

void loop(void)
{
  /*
  get adcvalue
  */
  digitalWrite(iled, HIGH);
  delayMicroseconds(280);
  adcvalue = analogRead(vout);
  digitalWrite(iled, LOW);

  adcvalue = Filter(adcvalue);

  /*
  covert voltage (mv)
  */
  voltage = (SYS_VOLTAGE / 1024.0) * adcvalue * 11;

  /*
  voltage to density
  */
  if(voltage >= NO_DUST_VOLTAGE)
  {
    voltage -= NO_DUST_VOLTAGE;

    density = voltage * COV_RATIO;
  }
  else
    density = 0;

  /*
  display the result
  */
  Serial.print("The current dust concentration is: ");
  Serial.print(density);
  Serial.print(" ug/m3\n");

  delay(1000);
}

My results seems rounded or always returning in certain 'steps'.
(below are my results)
Is there a rounded error in the code or something else that could be going on?

The current dust concentration is: 134.84 ug/m3
The current dust concentration is: 134.84 ug/m3
The current dust concentration is: 134.84 ug/m3
The current dust concentration is: 134.84 ug/m3
The current dust concentration is: 134.84 ug/m3
The current dust concentration is: 134.84 ug/m3
The current dust concentration is: 134.84 ug/m3
The current dust concentration is: 124.10 ug/m3
The current dust concentration is: 124.10 ug/m3
The current dust concentration is: 124.10 ug/m3
The current dust concentration is: 113.36 ug/m3
The current dust concentration is: 113.36 ug/m3
The current dust concentration is: 124.10 ug/m3
The current dust concentration is: 124.10 ug/m3
The current dust concentration is: 113.36 ug/m3
The current dust concentration is: 113.36 ug/m3
The current dust concentration is: 113.36 ug/m3
The current dust concentration is: 124.10 ug/m3
The current dust concentration is: 124.10 ug/m3
The current dust concentration is: 124.10 ug/m3
The current dust concentration is: 134.84 ug/m3
The current dust concentration is: 134.84 ug/m3
The current dust concentration is: 124.10 ug/m3

Its because the resolution of the analog read is 10 bits or 1024 discrete values.

In your code the density is basically calculated as:

density = (((5000 / 1024.0) * analog_value * 11) - 400) * 0.2

You can calculate the resolution as:

(5000 / 1024.0) * 11 * 0.2

and you get 10.7421875, which matches your observation.

If your filtering (calculating the average over last 10 values), would calculate and return a float, you would get smoother values.


How to create a log file document which is not editable by a word processor on SD card I'm using a Arduino Mega 2560  and SD card shield to make an industrial logging panel. Is there any way to write log data document in a read-only type file like a pdf on SD card so that the contents cannot be edited once created by word processing software? The data has to presented as a document on a windows machine.

Thanks in advance for your time – if I’ve missed out anything, over- or under-emphasized a specific point let me know in the comments.

There is no such thing as a file that cannot be edited.

If a file can be read it can be edited.

However, there are ways of making it possible to know if a file has been edited - i.e., to integrity check the file. To make it hard to edit a file and maintain the intrinsic integrity of the file.

The simplest method is to create a checksum of the data in the file and store that in the file as well. If the data is, for example, a CSV file, you could include in each row a checksum of the data in that row as an extra column. If the data gets changed the checksum will no longer match. Of course, that doesn't preclude someone calculating the new checksum and entering that.  So maybe adding a checksum of all the checksums at the end of the file as well so you know if any checksums have changed.

Again, it's possible for someone to recalculate that checksum as well.

The most secure method is to digitally sign the file (in the way the PGP or GnuPG does). Without the private key, it's impossible to re-sign the file after modification. However, that kind of operation is comparatively heavyweight and not something an Arduino is particularly suited to doing (I'm not sure if it's even physically possible given the lack of resources an Arduino has).


Why we can wake Arduino Uno from sleep using only pin 2? Can we use other pin as an interrupt to wake Arduino Uno from sleep ?

It's not just Pin 2 that can wake from sleep. Depending on which sleep mode you are in different interrupts (both internal and external) can wake the chip up.

The datasheet contains this helpful table:

The external interrupts (pins 2 and 3 on the Uno, and only "Level" trigger mode), pin change interrupts, I2C address matching, and the watchdog are the only interrupts that can wake the chip from any sleep mode. Other interrupts only work in certain sleep modes since they require parts of the chip to still be running in order for the interrupt to fire.

So that means that yes you can use any pin you like (using the "Pin Change" Interrupts) to wake the chip.


Serial Monitor is printing out weird values and skipping strings I am currently working on a project with some friends. In short, we want to create a setup where when a button is pressed a thermal printer prints out a random sentence.

I am currently trying to get my code to work and to debug it with the Serial Monitor, but it prints out weird stuff.

The baud rate is the same for the monitor and the Serial.begin().

int checkSum[] = {-1, -1};

String stringPool[] =
                      {
                        "Satz 1", "Satz 2",
                        "Satz 3", "Satz 4",
                        "Satz 5", "Satz 6",
                        "Satz 7", "Satz 8",
                        "Satz 9", "Satz 10",
                        "Satz 11", "Satz 12",
                        "Satz 13", "Satz 14",
                        "Satz 15", "Satz 16",
                        "Satz 17", "Satz 18",
                        "Satz 19", "Satz 20",
                        "Satz 21", "Satz 22"
                      };

String chooseRandom ()
{
  bool isMaybeThreeTimes;
  int randomInt;

  do
  {
      randomInt = random( 0, sizeof( stringPool ) -1 );

      // first and further random number chosen
      if( checkSum[0] == -1 ) { checkSum[0] = randomInt; }
      else
      {
        checkSum[1] = checkSum[0];
        checkSum[0] = randomInt;
      }

      if( randomInt == checkSum[0] && randomInt == checkSum[1] )
      {
        isMaybeThreeTimes = true;
      }
      else
      {
        isMaybeThreeTimes = false;
      }

      Serial.print("Current random value: " + randomInt);
      delay(1000);
      Serial.print("Last random value: " + checkSum[0]);
      delay(1000);
      Serial.print("Last last random value: " + checkSum[1]);
      delay(1000);
      Serial.print("Three times in row?: " + isMaybeThreeTimes);
      delay(1000);

   } while ( isMaybeThreeTimes );

  return stringPool[randomInt];
}

void buttonPressed()
{
  String stringToPrint = chooseRandom();
  // Send the string to the adafruit printer.
  Serial.println(stringToPrint);
}

void setup()
{
    Serial.begin(19200);
    delay(2000);
    Serial.println("Setup finished");
    randomSeed(analogRead(0));

}

void loop()
{
    buttonPressed();
}

Any ideas why this is happening? I switched the baud rates changed delays and changed the places on where and how often and in which frequeny the method buttonPressed() is called.

Here a picture of the output:

int checkSum[] = {-1, -1};

const String stringPool[] = {
                        "Satz 1", "Satz 2", "Satz 3", "Satz 4",
                        "Satz 5", "Satz 6", "Satz 7", "Satz 8",
                        "Satz 9", "Satz 10", "Satz 11", "Satz 12"
                      };

const String& chooseRandom () {
  bool isMaybeThreeTimes;
  int randomInt;

  do {
      randomInt = random( 0, sizeof(stringPool) / sizeof(stringPool[0]));
      isMaybeThreeTimes = (randomInt == checkSum[0] && randomInt == checkSum[1] );

      Serial.print("Current random value: "); Serial.println(randomInt);
      delay(1000);
      Serial.print("Last random value: "); Serial.println(checkSum[0]);
      delay(1000);
      Serial.print("Last last random value: "); Serial.println(checkSum[1]);
      delay(1000);
      Serial.print("Three times in row?: ");
      Serial.println(isMaybeThreeTimes?"Yes":"No");
      delay(1000);
      checkSum[1] = checkSum[0]; // for next run
      checkSum[0] = randomInt;
  } while (isMaybeThreeTimes);
  return stringPool[randomInt];
}

void buttonPressed()
{  // has nothing to do with button presses, just a test
  const String& stringToPrint = chooseRandom();  // waits 3 seconds
  // Send the string to the adafruit printer.
  Serial.println(stringToPrint);
}

void setup() {
    Serial.begin(19200);
    delay(2000);
    Serial.println("Setup finished");
    randomSeed(analogRead(0));
}

void loop() {
    buttonPressed();
}

Some fixes, not tested.
Edit: some more fixes, tested.


Matrix keyboard and 7segment display countdown combination I'm working on an escape room for my university with an Arduino Mega.
The last part consists of a 7segment display representing a time countdown, and the participants have to introduce the correct number in a matrix keyboard before it reaches zero.

My problem comes when for representing the seconds in the countdown, I have to use a delay, and this stops the matrix keyboard from getting the numbers.

The code I have so far:

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

byte rowPins[4] = { 5, 4, 3, 2 };
byte colPins[4] = { 9, 8, 7, 6 };

int pinA = 26; //2
int pinB = 34; //3
int pinC = 31; //4
int pinD = 27; //5
int pinE = 25; //6
int pinF = 28; //7
int pinG = 33; //8
int D1 = 24; //9
int D2 = 30; //10
int D3 = 32; //11
int D4 = 35; //12

Keypad mykeypad = Keypad( makeKeymap(keys), colPins, rowPins, 4, 4);

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

pinMode(pinA, OUTPUT);
pinMode(pinB, OUTPUT);
pinMode(pinC, OUTPUT);
pinMode(pinD, OUTPUT);
pinMode(pinE, OUTPUT);
pinMode(pinF, OUTPUT);
pinMode(pinG, OUTPUT);
pinMode(D1, OUTPUT);  //Turns the first digit on.
pinMode(D2, OUTPUT);  //Turns the second digit on.
pinMode(D3, OUTPUT);  //Turns the third digit on.
pinMode(D4, OUTPUT);  //Turns the forth digit on.
}

//
void showTime(){

  digitalWrite(D1, LOW);
  digitalWrite(D2, LOW);
  digitalWrite(D3, LOW);
  digitalWrite(D4, LOW);

 //3
  digitalWrite(pinA, HIGH);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, HIGH);
  digitalWrite(pinE, LOW);
  digitalWrite(pinF, LOW);
  digitalWrite(pinG, HIGH);
  delay(1000);

//2
  digitalWrite(pinA, HIGH);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, LOW);
  digitalWrite(pinD, HIGH);
  digitalWrite(pinE, HIGH);
  digitalWrite(pinF, LOW);
  digitalWrite(pinG, HIGH);
  delay(1000);

  //1
  digitalWrite(pinA, LOW);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, LOW);
  digitalWrite(pinE, LOW);
  digitalWrite(pinF, LOW);
  digitalWrite(pinG, LOW);
  delay(1000);

  //0
  digitalWrite(pinA, HIGH);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, HIGH);
  digitalWrite(pinE, HIGH);
  digitalWrite(pinF, HIGH);
  digitalWrite(pinG, LOW);
  delay(1000);

}

//Receives the chars from the matrix keyboard.
void getCode(){
   char key = mykeypad.getKey();
  if(key){
     Serial.print(key);
  }
}

void loop()
{

  showTime();

}

Any idea on how can I archieve this combination? Have been trying to find something similiar to a Thread, but Arduino doesn't support it.

Thanks in advance.

Try using millis(), it returns the number of milliseconds passed since the Arduino board began running the current program.

When you start the countdown you set a variable for a beginning time

int millisBegin = millis(); //put this at the end of your setup() {}.

You will also need a "border" to know when one second is over, so

int millisBorder = 1000; //one second border

Every time your the loop() {} starts over you can check if one second has passed so far

int millisNow = millis();
if(millisNow - millisBegin >= millisBorder){} //if one second over, do {}

Now I would work on the segment showing thingy. In the {} I would put a new variable, let's call it counter = 4; //4 because I found 3 numbers in your sketch. Every time the if() {} is being executed, you go through more if () {} statements, checking what number to display next.

if (counter == 3)
{
  //show number 3
}

if (counter == 2)
{
  //show number 2
}

if (counter == 1)
{
  //show number 1
}

if (counter == 0)
{
  //show number 0
}
counter = counter - 1;

At the end we take one off the counter, so the next time we enter the if(one second over) the number displayed will get lower

And well now there are multiple ways of doing the keyboard thingy. You can keep checking if there is a key available, and if so you can safe it as a String (most people hate strings, but I never had a problem with them to be honest).

After you've saved the key as a String you can use the strcmp(); method to compare the string with the solution/answer strcmp(key,answer);. If the key and the answer are the same, it will return 1.

if(strcmp(key,answer) == 1)
{
  Serial.println("you made it");
}


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

#define Buzzer 5

#define pwmMot 6

#define halPin 8

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

#define SeEcho 12
#define SeTrig 13

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

int current_level = 1;
int required_level =-1;

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

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

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

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

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

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

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

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

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

int required_level =-1;

it should have a boolean variable for each of the possible levels,
telling us whether a stop was requested for that level.

For convenience, I would number the levels from zero, and hold these
variables in an array:

const int LEVEL_COUNT = 3;
bool requested_stop[LEVEL_COUNT];

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

The part I emphasized doesn't make sense to me. The elevator should go
to the one that was pressed first, irrespective of the distances.
Imagine you are in an elevator at level 5, and press the button for
level 2. As the elevator just starts moving down, another rider presses
the button for level 6. Should the elevator immediately revert to going
up in order to reach level 6, which is closer? Of course not. If it is
going down, it should continue in that direction. Now, if the other
rider presses 3, it should stop by level 3 on its way down, even though
you pressed 2 first.

As stated by chrisl in a comment, a finite state machine is
definitely the solution for this kind of problems. I propose a state
machine with three states, STOPPED, GOING_UP, and GOING_DOWN:

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

And here is my proposed implementation:

void loop() {
    // Check the buttons.
    for (int i = 0; i < LEVEL_COUNT; i++)
        if (digitalRead(button[i]) == HIGH)
            requested_stop[i] = true;

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

This code assumes you have written the function elevator_height() that
measures the height of the elevator, and have defined an array of
constants LEVEL_HEIGHT[].

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


Arduino stop the loop i have a problem with my code, i basically move a motor with the help of 3 relays, when a sensor does not detect the presence of an object part of a call, everything works perfectly, if it was after having called the function CHIAMATA() the arduino loop() stop unexplains, i certainly made a mistake, but i do not understand which.

thanks for your help
this is the code....

#include <swRTC.h>
#include <SoftwareSerial.h>
#include <String.h>

swRTC rtc; //create a new istance of the lib
SoftwareSerial mySerial(3, 2);

const int buttonPin = 19;
const int sensorPin = 9;
const int allarmPin =  13;

int buttonState = 0;
int sensorState = 0;
int relay1 = 8;
int relay2 = 7;
int relay3 = 6;
int var = 0;

// initialize the stepper library on pins 8 through 11:

void setup() {
    rtc.stopRTC(); //stop the RTC
    rtc.setTime(12,0,0); //set the time here
    rtc.setDate(4,6,2012); //set the date here
    rtc.startRTC(); //start the RTC
  Serial.begin(19200); //choose the serial speed here
  mySerial.begin(19200);
  pinMode(allarmPin, OUTPUT);
}

void loop() {

while(mySerial.available()!=0);{}delay(10);

    Serial.print(rtc.getHours(), DEC);
    Serial.print(":");
    Serial.print(rtc.getMinutes(), DEC);
    Serial.print(":");
   Serial.print(rtc.getSeconds(), DEC);
    Serial.println(" ");

//stato riserva croccantini
sensorState = digitalRead(sensorPin);

if (sensorState == HIGH) {
    // turn LED on:
    digitalWrite(allarmPin, HIGH);
    Serial.println("Croccantini esauriti");
    Serial.println("Spia allarme ACCESA");
    Serial.println("Tramoggia DISABILITATA");
    Serial.println("Imposto la chiamata");
    while(sensorState == HIGH) {CHIAMATA(); break;}
  } else {
    // turn LED off:
    digitalWrite(allarmPin, LOW);
    Serial.println("Croccantini OK");
  }
if (sensorState == LOW && rtc.getHours()== 12 && rtc.getMinutes()== 00 && rtc.getSeconds()== 5) {startmotor();}
  //start manuale carico/scarico
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
    if (buttonState == 1) {
      Serial.print("Pulsante alimentazione manuale ATTIVO");
    // turn on:
  // singlestartmotor();
  }

      }

void startmotor(){
//numero di cicli di carico da eseguire (5)
 while(var < 5){
 pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
    pinMode(relay3, OUTPUT);

 digitalWrite(relay3, LOW); //ABILITA TUTTO
 //AVANTI
 digitalWrite(relay1, LOW);
 digitalWrite(relay2, LOW);
 Serial.print("AVANTI");
 delay(1000); // wait 2 seconds

 digitalWrite(relay3, HIGH);//STOP TUTTO
 digitalWrite(relay1, HIGH);
 digitalWrite(relay2, HIGH);
 delay(1000); //ATTESA PER INVERSIONE MARCIA

 //INDIETRO
 digitalWrite(relay3, LOW);//ABILITA TUTTO
 digitalWrite(relay1, HIGH);
 digitalWrite(relay2, HIGH);
 Serial.print("INDIETRO");
 delay(1000); // wait 2 seconds

  digitalWrite(relay3, HIGH);//STOP TUTTO
  delay(5000); // wait 2 seconds

  var++;
}}

void CHIAMATA() {
 mySerial.println("ATD329xxxxx135;");//dial the number, xxxx ix the phone number.
 delay(100);
 Serial.print("Chiamata in corso..."); return loop();}

Don't do return loop(); With that you enter into a never ending recursion. No system can resist that.

See: return loop(); means "evaluate loop() and return whatever it returns". Well, loop is void; it doesn't return anything.

Even worse is the recursion problem: you call loop(), which calls CHIAMATA, which calls loop ... never ending. You blow out the stack.

I don't look any further than that. Probably there are more errors.


Seven-Segment Display doesn't work on two lights This is my code:

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

void loop() {
    digitalWrite(2, HIGH);
}

This is my circuit:

Problem:

Light A and B doesn't work when I plug the red cable to 4 and 5.
All the other lights works just fine.

As jwpat7 states, you need a current-limiting resistor for each segment, between the data pin (on the Arduino) and the segment pin (on the display). Your Fritzing diagram only shows one resistor in the circuit, from the common cathode to GND on the Arduino.

You can not, or should not, share one resistor to ground (assuming that you have a common cathode seven segment display). You need a current-limiting resistor on each anode (again, (assuming that you have a common cathode seven segment display).

If you are sharing the current-limiting resistor between all segments, and then try to light more than more segment, at a time (which it sounds like you are doing ("when I plug the red cable to 4 and 5"), then the current through the current-limiting resistor will increase, and as a result, the voltage will change significantly enough, such that there is not sufficient voltage drop across the LED in order to make it light up.

Remember, 0.7 V is dropped across the LED.

Test each on the segments, one at a time, to make sure they all work, as Ignacio states in his comment.

Also, your sketch should be more complete, along the lines of:

void setup() {
    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
}

void loop() {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(8, HIGH);
}

Connect up all of the pins, using a current-limiting resistor on each anode, and then try it programmatically.

If your seven segment display is a common anode, then, again, you need a resistor between each cathode and the data pins, and bring the pins LOW to light the corresponding segment, i.e.

    digitalWrite(8, LOW);


ESP8266 compilation error: "previous declaration of 'HTTPMethod HTTP_HEAD'" I have an ESP8266 program that used to work but is now failing to compile with this error:

C:\...\Arduino\libraries\WiFiManager/WiFiManager.h:25:24: note: in expansion of macro 'PROGMEM'

 const char HTTP_HEAD[] PROGMEM            = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\"/><title>{v}</title>";

                        ^

In file included from C:\...\MyEsp.ino:14:0:

C:\...AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WebServer\src/ESP8266WebServer.h:33:39: error: previous declaration of 'HTTPMethod HTTP_HEAD'

 enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
                                   ^

I don't recall changing anything, except maybe updating some libraries. Any ideas what could be causing this?  Here are my includes from the ESP8266 program:

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>

#include <DNSServer.h>            //Local DNS Server used for redirecting all requests to the configuration portal
#include <ESP8266WebServer.h>     //Local WebServer used to serve the configuration portal
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager WiFi Configuration Magic

#define SERIAL_BUFFER_SIZE 256

You need a newer version of the WiFiManager.h library. This issue was fixed August last year.


Arduino serial question just a quick question on an oddity I noticed while playing with serial on my Arduino.

I'm using the serial monitor to test an interface I plan to adapt to Bluetooth later. Except I'm noticing if I only read fixed sizes with readBytes I can only ever input data of that exact byte length or my serial connection gets broken.

Example pseudocode:

Serial.write(Serial.available());
if(Serial.available() >= NUM_BYTES){
  Serial.readBytes(buffer,NUM_BYTES);
/* Do stuff */
}

If I input something of length NUM_BYTES + 1, it reads the first NUM_BYTES. But then I can never send more data over the serial monitor. Why is this? Is it part of the serial implementation? (The write would always be 1 afterwards even if I try to send more.)

A fix I had was just to clear the buffer by calling Serial.read() until nothing else was available. As a matter of curiosity too... If anyone cares to answer or give me a link to some reading - is there a way to check before I write to serial to make sure there's buffer space for my message on an Arduino? I read that they have a 64 byte buffer for data but I'm unsure how the protocol caters to sending larger sets of data if the buffer ever overflowed. Perhaps the serial library is using some form of ack behind the scenes?

The purpose of the serial input buffer is to prevent data-loss between your program's Serial.read() calls. If you really want to allow long messages to accumulate in it, here is one of many articles that describes how you can increase the size of the buffer in the Arduino core-code. But this is a system-wide solution to one program's design problem - it imposes the memory overhead of that larger buffer on all programs whether they need it or not, or you have to define a new board-type in the boards file (the technique in the above article) and remember to use it for programs that need the larger buffer.

A better approach is to do your own buffering, by defining within your program, a buffer large enough for your largest message (plus the zero terminator), collect bytes from the serial input buffer into your own buffer often enough to not let the serial buffer overflow; then detect when your own buffer has a complete message before you "/* Do stuff */ ".

You appear to be asking about a situation in which you will know in advance what the length of the next message will be; in that case, you can count bytes until you've collected the whole message.

In other situations, the message may have a terminator such as the NewLine character, or the message may contain the length within the first few bytes, in which case you'd wait for those bytes, convert them to an integer, and use that number to detect the end of message.

Update:

  But it doesn't explain to me really why I can't send it more bytes
  afterwards until I've read the entire input buffer.

I can't offer much help there; I've no experience using .readbytes(); I just read bytes as they arrive until I've got what I wanted. But my notes on it say it "Reads chars into a buffer. Terminates when len bytes have been read, or it times out" (1 sec, I think; there may be a call to change that, too). I'd also consider the possibility of the 64 byte serial buffer having over-flowed; doesn't sound like it but strange things can cause strange things....

"but I rarely work this close to the hardware"
That's the fun and the challenge of embedded systems!


How can I hook up multiple MMA8451 accelerometers, (I2C protocol) using one Arduino Mega? How can I hook up four (adafruit) MMA8451 accelerometers (using I2C protocol) using one Arduino Mega? What I'm confused about is I only have one SDA and SCL on the Arduino Mega obviously. So how can I connect these all? Multiplexer? I need four because I have one on each leg of a robot. Or is perhaps this impractical to put an accelerometer on each leg of robot? I'm a little new to electronics so please explain in depth if you could. Thanks.

Note to moderators: I just would really love an answer to this even if this doesn't meet the super strict question guidelines. It seems every time I post here there's always that one person who takes it down for any number of trivial reasons. Please let me get an answer at least. Thank you!

Brief explanation: When you talk to the slave device through I2C you start with (slave) device address. Then you send the message. It is like calling your colleague in an office with many other people. You say: "John", and when he is aware you continue with message, like "let's go for coffee".

This arrangement allows for adding up to 127 devices on one I2C bus. Each device must have different address (sorry, you cannot have two John's in the office, it will cause conflict). Generally two different type of devices will have different I2C addresses, but it may happen you need to use two (or more) of the same (like in your example). In this case, see below.

Many devices with I2C interface allows for address change. Using this facility you are able to communicate with many of the same devices through the same pair of cables.
You can check if your chosen accelerometer has possibility for address change: On picture below there is one with Address tab. When jumper is not fitted, you will get one address, when is fitted, the address of this device will be different, allowing of two of this accelerometers on one I2C bus. Unfortunately in this example there will be possibility of maximum of two of the same devices.

Of course there are devices with more than two possible addresses, you need to search for them.
And, yes, it is fine to use one Arduino to communicate with many I2C devices.

EDIT:
Looking after some of Adafruit accelerometers, I have found this page: https://learn.adafruit.com/i2c-addresses

And small off topic note: If you struggling on finding I2C with more than 2 addresses, check if it is easier to use SPI protocol. In this case you need (edited to correct bus lines names after user CrossRoads comment) MISO, MOSI, SCK and CS (chip select) wires. Chip select is individually connected to each slave device. This allows selecting particular device without addressing issue.


ESP-NOW with esp32 and esp8266 I want to use ESP-NOW with esp32 and esp8266. The esp32 will mostly send data to esp8266.I was not able to find any good tutorial on YouTube to achieve this. The only videos I found was for either communicating with esp32 to esp32 or esp8266 to esp8266. Is it possible to do this if yes how.

In general, ESP-NOW uses the WIFI radio in an ESP processor as a physical layer.  But uses it's own protocol which likely looks like garbage to a normal WIFI equipment.  So, it's like being in a meeting room with a bunch of people only knowing German and occasionally someone pipes up taking French.  As no one understands the French speaker, the French speaker is ignored.
Other things you need to know.  ESP-NOW is more like UDP.  There is not a higher layer looking out for you like in TCP.  Any number of reasons can cause your ESP-NOW "blurp" from being received.  For this reason ESP-NOW is better suited for periodically repeating information.  Like reporting the temperature.  Or for situations where the user can provide immediate feed back of success.  Such as a remote control.

The esp32 will mostly send data to esp8266

This infers reversing the direction of data flow over the ESP processor's WIFI radios.  While this may be possible it may not be a trivial task.

Is it possible to do this (communicate between an esp32 and esp8266) if yes how.

This shouldn't be problem.  This link provided by Majenko appears to be a good place to start.  Espressif them selves maintains this ESP-NOW web site.  Likely, after programming the ESP8266 and ESP32 using the correct libraries, they will be able to send data over an ESP-NOW link.


Is there any arduino microphone that can record heart sound? I'm currently undergoing a project where I record heart sound (mechanical response) and send it over bluetooth to an app.

However I'm finding it really hard to find an arduino microphone or just general microphone that can listen to heart sound.

Any guide would be highly appreciated.

Thanks

First, there is no such thing as an Arduino microphone. There are boards specifically for Arduino which have a microphone, but also these are just generic 'electronic sound sensors'.

In principle any microphone would be a valid choice, but you have to test what are the requirements (distance to heart, environment noice). You also could use piezo sensors for vibration checking possibly.


How to Set the Control Register on the DS3231 RTC module for Arduino UNO R3? I am using the DS3231 RTC connected to an Arduino UNO R3 for a project. I won’t go into detail, but I need to save power, therefore I am using the DS3231 Alarm Interrupt to wake the Arduino from sleep. The Alarm Interrupt works fine when the Arduino is sleeping and connected to the 5V and GND pins of the Arduino, however it turns out that the DS3231 won’t fire a square wave interrupt when on battery power. In order to turn it on, I need to set bit 7 of the Control Register (0Eh) to logic 1, and bit 6 to logic one. I can’t find any documentation on how to do this, except for a few forums talking about it. What is the specific code to do this, and where would I place the code?

DS3231 Data Sheet (Control Register on p.13)

#include <Wire.h>
#include <RTClibExtended.h>
#include <LowPower.h>

#define wakePin 2    //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
#define ledPin 13    //use arduino on-board led for indicating sleep or wakeup status

RTC_DS3231 RTC;      //we are using the DS3231 RTC

byte AlarmFlag = 0;
byte ledStatus = 1;

//-------------------------------------------------

void wakeUp()        // here the interrupt is handled after wakeup
{
}

//------------------------------------------------------------

void setup() {
  //digitalWrite(wakePin,HIGH);
  //Set pin D2 as INPUT for accepting the interrupt signal from DS3231
  pinMode(wakePin, INPUT);

  //switch-on the on-board led for 1 second for indicating that the sketch is ok and running
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  delay(1000);

  //Initialize communication with the clock
  Wire.begin();
  RTC.begin();
  RTC.adjust(DateTime(__DATE__, __TIME__));   //set RTC date and time to COMPILE time

  //clear any pending alarms
  RTC.armAlarm(1, false);
  RTC.clearAlarm(1);
  RTC.alarmInterrupt(1, false);
  RTC.armAlarm(2, false);
  RTC.clearAlarm(2);
  RTC.alarmInterrupt(2, false);

  //Set SQW pin to OFF (in my case it was set by default to 1Hz)
  //The output of the DS3231 INT pin is connected to this pin
  //It must be connected to Arduino D2 pin for wake-up
  RTC.writeSqwPinMode(DS3231_OFF);

  //Set alarm1 every day at 18:33
  RTC.setAlarm(ALM1_MATCH_HOURS, 16, 19, 0);   //set your wake-up time here
  RTC.alarmInterrupt(1, true);
}

//------------------------------------------------------------

void loop() {

  //On first loop we enter the sleep mode
  if (AlarmFlag == 0) {
    attachInterrupt(0, wakeUp, LOW);                       //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
    digitalWrite(ledPin, LOW);                             //switch-off the led for indicating that we enter the sleep mode
    ledStatus = 0;                                         //set the led status accordingly
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);   //arduino enters sleep mode here
    detachInterrupt(0);                                    //execution resumes from here after wake-up

    //When exiting the sleep mode we clear the alarm
    RTC.armAlarm(1, false);
    RTC.clearAlarm(1);
    RTC.alarmInterrupt(1, false);
    AlarmFlag++;
  }

  //cycles the led to indicate that we are no more in sleep mode
  if (ledStatus == 0) {
    ledStatus = 1;
    digitalWrite(ledPin, HIGH);
  }
  else {
    ledStatus = 0;
    digitalWrite(ledPin, LOW);
  }

  delay(500);
}

Also, how would I set it to go to sleep after the alarm?

Thanks!

P.s sorry about that Thomas, I'm a bit new here.

I took a look at the FabioCuomo-DS3231 library, as I
guess that is what you are using, and I saw nothing related to setting
those two bits. However, you can take inspiration from the code in the
library to implement the functionality yourself.

I would try this:

void enableAlarmInLowPower(void) {
    // Read the control register.
    Wire.beginTransmission(DS3231_ADDRESS);
    Wire.write(DS3231_CONTROL);
    Wire.endTransmission();
    Wire.requestFrom((uint8_t)DS3231_ADDRESS, (uint8_t)1);
    uint8_t value = Wire.read();
    Wire.endTransmission();

    // Update it.
    value |= bit(6) | bit(7);  // set bits 6 and 7

    // Write it back.
    Wire.beginTransmission(DS3231_ADDRESS);
    Wire.write(DS3231_CONTROL);
    Wire.write(value);
    Wire.endTransmission();
}

Warning: not tested.


Arduino + L9637 K-Line reader - 10400 baud on SoftwareSerial? I know this question has been asked many times before in different flavours, but all of the previous questions I have found seem to pre-date the current SoftwareSerial library, which afaik now (unlike when the previous questions were asked) allows any baud rate to be set as it calculates the values for the timings.

So I currently have the L9637 monolithic bus driver connected to pins D0 and D1 of my Arduino Uno. I am trying to create an ECU reader to communicate with my car over the KW1281 protocol, and from testing I have discovered I need to do the 5 baud init and then communicate at 10,400 baud.

First off I want to say I have successfully managed to run the 5 baud init. Now, I realise the pins (D0 & D1) are capable of hardware serial, however when trying to use the hardware serial I couldn't get any connection to the car. I think it's because the hardware serial doesn't like the pin modes to be changed after setup - however this is required to perform the 5 baud init. So I have decided to use the SoftwareSerial library for the following 10,400 baud communication.

With this library I successfully receive three (incorrect) response bytes from the ECU when setting a baud rate of 9600, however the response bytes - despite being correct in the number of them (3) - are wrong in terms of their value and seem to just be zero values.

Now as my car requires 10,400 baud communication, I instead setup the serial port to 10,400 baud. I know from experience that using 9600 baud will give incorrect response bytes and 10400 baud solves this. So I expected this would work and solve my problem, however it didn't. I still get 3 bytes containing 0. Just to be clear the three correct values should be: 55 01 8A

So I was wondering:

Am I right in assuming the SoftwareSerial library will work for any baud rate, even 10,400?
If yes to point 1, can anyone suggest why I might be getting data bytes containing 0 instead of the correct values?

As the full code is too long to post, the code for setting up the UART at 10,400, and then receiving the bytes is as follows:

#include <Wire.h>
#include <SoftwareSerial.h>

SoftwareSerial obd(pinKLineRX, pinKLineTX, false); // RX, TX, inverse logic
obd.begin(baudrate);

uint8_t data = 0;
int recvcount = 0;
char s[3];

while (obd.available())
{
   uint8_t data = obd.read();
   s[recvcount] = data;
   recvcount++;
}

And then to print the data I do the following:

#include <Adafruit_GFX.h>
#include <UTFTGLUE.h>

UTFTGLUE lcd(0x9488,A2,A1,A3,A4,A0);

char textout[30];
int xVal = 50;
cursorY = 10;
for (int i=0; i < size; i++)
{
  uint8_t data = s[i];

  sprintf(textout, "%i ", data);
  lcd.print(textout, xVal, cursorY);
  xVal += 10;
}

cursorY += 10;

The output on the LCD is

  0 0 0

When it should be

  55 01 8A

I've found 9600 baud to be the receive limit among standard baud rates (transmission can go faster). You're proposing an 8% increase over 9600 which sounds like it has a good chance of working but you'll need to experiment to find out.

You also asked why might your data (on the LCD) be wrong.

You'll do your sanity a big favor and do two separate experiments:

First, get known data (literal strings or terminal input) to display correctly on your LCD, before you try to use the LCD to confirm or debug your communications.
Second, get SoftwareSerial running (or find out that it doesn't...) at 10400 baud. In fact try to get up to, say, 12000 baud, or at least push the rate to find out where it starts to fail so you know how much head-room you'll have at 10,400. The simplest way would be to use two Arduinos if you have access to another one. Again, use your terminal or some literal strings on MCU 'A' to send to MCU 'B', MCU 'B' should receive a line and echo it back to 'A', who prints it on its terminal. Printing it on 'B's terminal wouldn't be a bad idea either.

You'll be in a lot better position to combine the two techniques once you have confidence that each one works; especially if you copy-and-paste known-working code segments.


ATmega168a Breadboard - can't load via Arduino IDE I have ATmega168a on a breadboard. I am programming it via the Arduino IDE and a FT232RL USB adapter. When I select my board for 168 and upload, I get the following error:

stk500_getsync(): not in sync: resp=0x00

Normally this error means that either:

My wiring is not correct
I choose the wrong board

So to double check my wiring, I replace the 168 with a 328p. I am able to program the 328, so I think its the board selection.

I have tried Ardiono Diecimila or Duemilanove w/ ATmega168 and I also have a custom board entry:

atmega168bb.name=ATmega168 breadboard (16 MHz internal clock)
atmega168bb.upload.protocol=stk500
atmega168bb.upload.maximum_size=14336
atmega168bb.upload.speed=57600

atmega168bb.bootloader.low_fuses=0x62
atmega168bb.bootloader.high_fuses=0xDF
atmega168bb.bootloader.extended_fuses=0xF9
atmega168bb.bootloader.path=arduino:atmega
atmega168bb.bootloader.file=ATmegaBOOT_168_atmega328_pro_16MHz.hex
atmega168bb.bootloader.unlock_bits=0x3F
atmega168bb.bootloader.lock_bits=0x0F

atmega168bb.build.mcu=atmega168
atmega168bb.build.f_cpu=16000000L
atmega168bb.build.core=arduino:arduino
atmega168bb.build.variant=arduino:standard

Also, I am able to program the 168 via my AVR Programmer/Debugger. If you are wondering why I should just use the AVR Dragon, there reason is that I a sometimes don't want to remove the chip from the bread board while developing and programming.

Any suggestions I can try?

Have you burned a bootloader?
The standard Arduino IDE upload requires that you have a bootloader on the chip.
You can burn a bootloader with the Arduino IDE and your AVR dragon


Firmata C++ library for host? Firmata seems to be a popular protocol for communicating between the Arduino and host computer. However, there only seems to be C/C++ libraries for the Arduino. Most Firmata libraries for the host appear to be in Python. I've found a few C/C++ Firmata libraries for the host, but they seem incomplete and unmaintained. Is anyone aware of a full-featured C++ Firmata library designed to run on the host computer?

openFrameworks appears to have this capability. It's written in C++.

From openFrameworks - Communication:

  Arduino and other serial devices communication

  The communication module has classes to communicate with other devices
  by now through the serial protocol. This mainly allows to communicate
  with devices like the Arduino. There's 2 classes in this module,
  ofSerial which allows to communicate with any device through the
  serial protocol. It can be used to send custom commands to for example
  an Arduino sketch that will receive them and do something in response
  like turn an LED on, move a motor... It also works the other way
  around, you can send messages from the Arduino (or any other serial
  device), for example the read from a temperature sensor to
  openFrameworks.

  The second class, ofArduino, is specific to the arduino, it uses a
  protocol called firmata to send messages to and from the arduino that
  way you don't need to care about implementing the communication
  protocol from the Arduino sketch to openFrameworks and viceversa but
  instead you can just send and read values directly to and from any pin
  in the Arduino.


Can't create a RTC_DATA_ATTR var inside a class I'm trying to create a deepSleep class for my ESP32 project, but I get this error : section attribute not allowed for 'clock_beforeSleep' The only place it compiles, is outside the class.

How should I declare it ?

EDIT1: Add Code

#include "EEPROM.h"
#include "time.h"
#include "WiFi.h"

RTC_DATA_ATTR long clock_expectedWake = 0;
RTC_DATA_ATTR int bootCounter = 0;
RTC_DATA_ATTR int driftRTC = 0;
RTC_DATA_ATTR long clock_beforeSleep = 0;

class esp32Sleep
{
#define EEPROM_SIZE 16
#define DEV_NAME "ESP32lite"
#define uS_TO_S_FACTOR 1000000ULL /* Conversion micro seconds to seconds */

private:
  char sleepstr[250];
  // RTC_DATA_ATTR long clock_expectedWake = 0;
.
.
.

You can't put an RTC_DATA_ATTR qualified variable inside a class because the class is stored in normal RAM. The RTC_DATA_ATTR qualified variable is, by definition, stored in RTC RAM.

The definition of RTC_DATA_ATTR includes a section attribute (__attribute__((section(".rtc.data")))) that tells the compiler where abouts in memory the variable should be stored (in this case the 8kiB of "slow" RTC memory). That is mutually exclusive with where the compiler decides to store the class.

It's like you have a diamond necklace which the has to be kept in a safe at all times, but you want to wear it around your neck whilst at the same time storing it in the safe. You can't do it.


Why ESP8266 slower than Arduino nano? I'm using the same script(and standard wire and serial library only) one uploaded to Arduino nano one uploaded to ESP8266. However, despite ESP8266 running at 160MHz, 10 times faster than nano, it's taking 3.5 ms to complete the loop, compare to 2.5 ms than that of nano.

How could that be?  why ESP8266 was slower?

However, despite ESP8266 running at 160MHz, 10 times faster than nano, it's taking 3.5 ms to complete the loop, compare to 2.5 ms than that of nano.

There's a number of reasons for that. Chiefly:

The ESP8266 has no I2C hardware, so has to use software "bit-banging" to emulate I2C. That is slower to execute.
The ESP8266 also has to manage the WiFi hardware which takes a portion of the processing power away from the user

The result is slower execution for I2C operations and "jitter" added to timings of loops and such.

  will the same thing (wire) happen to esp32?

No (or not as much). The ESP32 has hardware I2C so it doesn't need to use bit-banging to emulate it, so it will be faster. Also it is dual core and one core is used for "system management" including managing the WiFi and Bluetooth, while the second core is used to execute your sketch, so there is no (or little1) interruption by the WiFi slowing down your sketch.

1: Two cores accessing the same area of RAM causes some contention as only one core can access the same block of RAM at a time, so it's not perfect. You may still get slight delays, but they will be minuscule compared to the processing needed for the ESP8266's WiFi code.


HMC5883L tilt compensation I have a HMC5883L 3-axis magnetometer. I would like to add tilt compensation to my Arduino Uno project.

Since the IC has 3 axis that it measures (X,Y,Z) is it possible to add tilt compensation without an accelerometer? If yes would this how do I find an equation to do the calculation. Is this equation found from http://bluelemonlabs.blogspot.fi/2013/08/arduino-simple-compass-with-hmc5883l.html correct?

No. You need an accelerometer.

If you read the article you link to you can see this bit:

  There are many margin of improvement. First, we ought compensate the potential tilt of the device using the accelerometer data from the ADXL345, for example using the info on my previous post!

To do tilt compensation you need three axes of both magnetometer data and accelerometer data to scale and merge those three axes.


Using Arduino with Assembly on MacOS I'm trying to use an Arduino UNO board with Assembly on MacOS, but I couldn't find any documentation about it.

How can I compile and upload Assembly files to the Arduino with MacOS?

You can add source code to the sketch in the Arduino IDE. When adding a new source code file make sure the extension is uppercase .S

Files with .S extension will be compiled as Assembly.

There is an Arduino IDE for the mac but if you want to use an external editor you have many options.

The simplest is to switch on File>Preferences>External Editor in the Arduino IDE. This makes the IDE work in "read-only/auto-reload" mode allowing edit in a different code editor but compile and upload (without reopening the code) in the Arduino IDE.

There are also the File>Preferences Verbose Compile and Verbose Upload options in the Arduino IDE. These options will show you the commands used to compile, link and upload. You will see that the IDE runs other programs, outside of the IDE, such as avrdude and g++. Therefore a small script file can be created to call the same commands from a different IDE if the external editor doesn't have a facility to run external commands.

The verbose output will show where the tools and sources for build and upload are located. Normally for Uno (avr) they are below [IDE Folder]\hardware\arduino.


What does an Arduino do if the serial connection is closed on the other end? I have a simple method that simply waits for an input, computes a response, and sends it:
void loop() {
  if (Serial.available() > 0){
    input = Serial.read();

    if (input == 10){
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);

      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);

      duration = PulseDuration(echoPin, HIGH, 6000);
      distance = duration * 0.00034/2;  // 0.00034 m/us is speed of sound

      Serial.println(distance, 4);
      }
  }
}

My question: What happens to the arduino if I close the serial connection from the receiving end while it's printing out data (in the last line of the loop)?
Context and motivation:
The program works well most times. I can open a python program that sends the requests and prints out the reply using pyserial. After I close the python side and reopen it, connection is set and I can start listening on the side nicely just like the first time. Sometimes, however, when I try to restart the python program, I get a connection error saying that the port is already opened (I'm running in Windows.. there are tons of posts about this problem, but none of them have been helpful). Some other times, when connecting with the python program (which connects with connection = serial.Serial(self.arduino_port, 9600, timeout=0) it just blocks and doesn't connect, it doesn't give the "port already opened" error, and it doesn't advance to the next statement.
I am confident I did close the previous python run before attempting a new one (process explorer shows no active python programs running, it also shows no open processes using a serial handler). I'm not here to solve that problem directly, though, just to ask a related question.
I'm also confident running connection.close() does not terminate the arduino program, as I have been able to restart my python program without having to reset the arduino or anything, suggesting the arduino kept running its loop after I closed the connection on the python side.
All that to say that my latest hypothesis is that these issues arise when I close the serial connection connection.close() while the arduino is printing, but because the port is closed, that Arduino is stuck and cannot do the Serial.println(), as the USB never asks to flush the data in its buffer.
Is this possible/does it make sense? What happens to the arduino if I close the serial connection while it's printing out data?
I'm not posting my python program here as it's not directly relevant to the question and I can't seem to make a minimum reproducible program that doesn't expose confidential code.

That's some strange Intel monstrosity. It's impossible to know what it does or how. Intel's foray into the Arduinosphere was brief and somewhat abortive.
In general though (for most cores) the DTR signal (and sometimes the RTS signal too) of the CDC/ACM protocol is used to "gate" the serial data - if it's asserted then serial data gets sent through to the host PC. If it's not asserted then it just gets thrown away.
I have seen cores where if DTR is not asserted the data gets buffered until the TX buffer is full and then blocks, but that is rare.
You might find your answer if you delve into the core's source code, but you may find that big chunks of it are hidden away in closed source pre-compiled libraries, and the fact it seems to run some custom RTOS means it'll be even more obfuscated. YMMV...


How do I run a bipolar motor with an arduino uno? At the risk of looking like a complete idiot on the internet, I'll preface with this; I'm incredibly new to this. I'm new even to coding, and not sure what questions I should be asking.

I'm trying to run a bipolar motor with an Arduino Uno. I'm fairly sure it should be as simple as set a pin to high, plug the motor into that pin and a ground and it should run. I did this a week ago, and it worked then.

Now I'm trying to essentially run a modified version of blink with this motor running instead of the LED. Running the code with pin 13 as my positive does still flash the LED. If I set my pin to high with the motor, the motor no longer runs. However, It does run when plugged into the 5V and ground. The motor also runs straight off of the two poles of a 9V battery.

I'm unsure what I'm doing wrong. Do I need to step up the voltage of my pins somehow?

Thanks in advance.
-Alec Rosso

Edit 1:Here's the code:

int motorPin1 = 13;
int interval= 5000;

void setup() {
pinMode(motorPin1, OUTPUT);
digitalWrite(motorPin1, HIGH);
}

void loop() {
digitalWrite(motorPin1, HIGH);
delay(interval);
digitalWrite(motorPin1, LOW);
delay(interval);
}

As far as voltage or current specifications, it says DC 12V.

Edit 2: it is not a stepper motor. The serial number is TS-32GZ370-950. It's apparently a "DC geared motor."

Final Edit: I've got it working using an L298. I used a 9-volt battery in addition to my arduino's 5 volts, and everything works like a dream. Thank you for your help.

Just for your knowledge and future reference - Arduino digital pins can deliver maximum of 40mA each. If you power Arduino by USB, Arduino UNO can draw maximum of 1A, and Nano maximum of 500mA. That is, the 5V pin can deliver that current, not a digital pin. Therefore pin 13(digital pin) can deliver 40mA at 5V, which is 200mW power.

Now, looking at your motor, TS-32GZ370-950,from datasheet at maximum efficiency the current needed is 140mA. Stall current is 480mA, therefore you should be able to deliver close to 480mA @ 12V for the motor to work under all possible loads. Now, that is 5.6W or so. Your 5V pin making the motor work simply meant that the load is low to medium. But you are unable to use the motor's full potential anyway.

Your driver choice is ok, because L298 can deliver up to 2 A, which is fine.
The 9V battery(Alkaline I suppose?) will work, but the lifespan will be very very short. You can look at discharge graphs here : https://www.powerstream.com/9V-Alkaline-tests.htm

It will last about 1 hour at moderate load. Consider using other types of batteries. Your motor accepts voltage up until 24V, so feel free to experiment.

Best of luck!


How do I measure speed and manipulate the speed based on distance covered? I'm doing a project on arduino. I'm using a online simulator to design the circuit. I have a dc motor. How do we measure the rpm,speed at that rpm,distance covered by the motor in a given time. For example,

When motor starts, it starts rotating slowly and gradually increases it's RPM. When it covered a distance of 50 meters, the motor slows down and stops. After 10 seconds, the motor starts again at that 50 meter point and goes to 100 meters point and stops. Like this it stops for every 50m. For this we need to keep track of the distance travelled by motor and control it's speed.

How do I achieve the above working. I have tried alot and verified many tutorials but couldn't understand what to do. Please help me out.
(The online simulator I'm using has a L293D motor driver, IR sensor and a ultrasonic distance sensor in it's component list.)

They key point here is to know the distance. The simplest way of finding that distance is to know how many times the wheel has completed an entire revolution. Multiply that number of revolutions by the circumference of your wheel and you have the distance the wheel has covered.

Depending on how precisely you want to measure that distance you may get away with a simple magnet and hall effect sensor. Place the magnet on the wheel, and locate the hall effect sensor so the magnet passes it close enough to trigger. Each pulse from the sensor is one rotation of the wheel.

You could increase the resolution by adding more magnets - 4 magnets set at 90° points around the wheel will give you a pulse for each quarter of a revolution (so multiply pulses by a quarter of your circumference).

If you want better resolution and accuracy you could attach a rotary encoder to the axle of the wheel. This, depending on the encoder, can give you far better resolution than simple magnets. Some will also give you the angle the wheel is at (not that such information would be of interest in this project).


is it possible to power esp8266 with button cell is it possible to power esp8266 wifi module with button cell for long period(1 year ) real time applications??
 Needs only wifi features (no need of gpio)

what will be voltage and current of the cell??

No. It has to wake up to do something and turn on the wifi. At that moment it requires too much power for a button cell. It needs about 150mA, mostly for wifi.

The BLE (Bluetooth Low Energy) is specifically designed for low power usage. Also some RF modules (433MHz, 868MHz, 915MHz) can be used with a small battery.


Best practice to declare a 'static' text and save memory I'm working on a project where I need to create a JSON to send back state of an object. I created the code to achieve it and all works fine, but I used this to declare the JSON fields:

static const String JSON_FIELD_A;

then in the .cpp file

const String MyClass::JSON_FIELD_A = "field_a";

In this way I can use that in several point inside my class (eg. to create and parse JSON) without needs to write the field name each time which may cause inconsistency after a refactoring.

I'm not sure about this way anyway... is there a more efficient way to achieve that? Using #define may be a solution?

The "traditional" way is to use PROGMEM and use const char * strings.

I don't use the "traditional" way. Instead I use some "helper" classes and macros that WString.h provides.

This does mean, though, due to limitations in C++, that you have to create your string constants in two stages.

First is to define your variables:

const __FlashStringHelper *stringOne;
const __FlashStringHelper *stringTwo;

Then you need to assign the actual strings to those variables within a function. This could be in setup(), but I prefer to define an initializeStrings() function that setup() calls:

void initializeStrings() {
    stringOne = F("This is the first string")
    stringTwo = F("This is the second string");
}

void setup() {
    initializeStrings();
}

You can then pass these objects (they're not really objects, it's all just some magic casting done by the compiler) as parameters to other functions using const __FlashStringHelper * as the type.  They can also be passed directly to any of the .print() and .println() functions provided by the Print class (which all Stream objects ultimately inherit).

If you want to use the standard C string library functions _P variants for manipulating the strings (concatenating them to other strings, for instance), you can simply cast them to PGM_P:

char temp[50];
strcpy_P(temp, (PGM_P)stringOne);
strcat_P(temp, (PGM_P)stringTwo);

Another alternative to all that is to use precompiler macros.

#define STRING_ONE F("This is the first string");
#define STRING_TWO F("This is the second string");

Again, you can cast those to PGM_P to use the _P variants of the standard C string library functions, and pass them directly to print functions, since they are replaced verbatim as F("This is the first string"), and F() does a reinterpret-cast to const __FlashStringHelper *.


Can I disable the TX pin by setting its mode to INPUT while still receiving data on the RX pin of a UART? I'm using the ATmega328PB in a personal project with MiniCore. My board streams data in on the RX pin from another microcontroller, but my board also has a DIP switch connected to the TX pin, that's used for configuration. My board has already been manufactured, so a hardware solution means a board redesign and extra cost/time.

This DIP switch is connected between TXD (Arduino pin "1") and GND. Upon startup, I read the value of this pin when in mode INPUT_PULLUP. However, when I go to start the Serial, if this switch is in the closed position, it shorts the TXD pin to GND.

Is it possible to disable the TX pin by putting it into INPUT mode while still receiving data on the RX pin?

Well, I ended up answering my own question in a few minutes of forum research.

You can disable the TX pin of the hardware UART with:

UCSR0B &= ~bit (TXEN0);


Main loop delay behaviour with interupt This question is not for a project, I am just trying to understand what happens and why.

The sketch below works as expected as long as the ISR trigger is FALLING. The red led in the main loop is blinking, apparently without any disturbance from the interrupts.
The question is what goes wrong, and why, when the ISR trigger is set to LOW.

int sensorPin3=3;
int ledPinGreen=12;
int ledPinRed=11;
int sensorStatus;
byte ledGreenStatus;

void setup() {
pinMode(ledPinGreen,OUTPUT);
pinMode(ledPinRed,OUTPUT);
pinMode(sensorPin3,INPUT_PULLUP);
ledGreenStatus=HIGH ;
Serial.begin(9600);
}

void loop() {

attachInterrupt(digitalPinToInterrupt(sensorPin3), sensorOn, LOW);
digitalWrite(ledPinRed,HIGH);
delay (5000);
digitalWrite(ledPinRed,LOW);
delay (5000);
}

void sensorOn()
{
static unsigned long lastInterruptTime=0;
unsigned long interruptTime=millis();
if(interruptTime-lastInterruptTime>100)
{
digitalWrite(ledPinGreen,ledGreenStatus);
ledGreenStatus =! ledGreenStatus;
lastInterruptTime=interruptTime;
}
}

If the sensor is activated and the signal on interrupt pin 3 is LOW, sensorOn will be executed. What happens if the ISR has been executed once? Does the program return to the main loop to the place where the interrupt was initiated and then right back to the ISR, or does it stay in the ISR without getting back to the mainloop for as long as the signal stays LOW?

If the sensor is activated for a couple of seconds:
1) if the program keeps running the ISR, I would not expect activity from the red led (main loop), but that led is blinking, with delay of about 2 seconds (without the interrupt that should be 5 seconds).
This way it looks to me that the program returns to the main loop, but the delay time is wrong, so it doesn’t return to the right place, or the timing is not correct anymore. Why doesn’t this happen with the ISR trigger set to FALLING? Is the amount of interrupts disturbing the timing of the main loop delay?

2) if the program keeps executing the ISR but returns to the main loop every time in between, I would expect the millis() to be updated every time. In that case I would also expect the green led to blink because of the debouncing time. However the green led is not bliking. This makes me think that the program stays in the ISR so the millis() are not updated and the green led won’t blink.
But that doesn’t match with the red led behaviour.

3) if the sensor is only activated for a short amount of time, the red led turns on or off the moment the signal on the interrupt pin is no longer LOW. No visible delay. I don’t understand why a longer LOW time on the interrupt pin makes a blink with about 2 seconds delay and a short LOW time makes no delay at all.

Thank you in advance for your help!

The question is what goes wrong, and why, when the ISR trigger is set to LOW.

edge vs. level triggered interrupts.

Read the datasheet.


How millis() resets itself to 0 Looking at the documentation for the millis() function , it says:

  Returns the number of milliseconds since the Arduino board began
  running the current program. This number will overflow (go back to
  zero), after approximately 50 days.

How's this possible? Is Arduino detecting when millis() overflow then resets the value to 0? If so, how does it do it? I just want to know what exactly is going on under the hood with the variable that is being returned by the millis() function.

It is not an exclusive property of millis(). Any counter with a limited number of digits eventually returns to zero. For example, a 4 digit tally counter returns to zeros after 9999.

Under the hood, the variable for millis() is of type unsigned long, which is 32 bits on the Arduino. In this case, the 32 bits (binary 0's and 1's) are similar to the digits (0 thru 9) on the tally counter.

The maximum is 11111111 11111111 11111111 11111111. Once there, millis() returns to zero when you add 1.  The maximum (32 "ones") is 2^32 - 1, which equals 4294967295 in the decimal number system. The maximum value for the counter is, therefore, 4,294,967,295 milliseconds.   Converted to days you get approximately 49.71 days.