Replacing large lookup table with switch statement My arduino needs to take a 14-bit number and convert it to a 10-bit number. Can't use a formula for it since the data is quite random. So I created a lookup table with 2^14 elements, each containing a 10-bit value. But it's too big to fit on the arduino. So I thought of using a switch statement instead. Would this result in a significant speed decrease?

Say, for example, that the input value is 16383. How much longer would it take for the arduino to iterate through the 16384 cases compared to accessing index #16383 of an array?

EDIT: This code compiles fine and reports a program memory usage of 1000 bytes.

int xval;
int yval;

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  xval = random(0,16383);
  switch (xval) {
  case 0:
  yval = 0;
  break;
  case 1:
  yval = 4;
  break;
  case 2:
  yval = 4;
  break;
  case 3:
  yval = -60;
  ...
  case 16383:
  yval = 1023;
  break;
}
}

However, I haven't tried if it really works so maybe the compiler is optimizing away too much.

EDIT 2: Added the line Serial.println(yval); so that I'm actually doing something with yval as Majenko commented. And now it doesn't compile :'( :'( :'(

So, I'll tackle my problem in some other way.

214 is 16384 entries. Each entry takes 2 bytes. That's 32768 bytes. That's all the flash the ATMega328P has.

The most efficient storage will be an array in flash, and that will take 100% of it. Using a switch will take more space.

So in short: no. Just no. It won't work whatever you try. You need to come up with a radically different storage solution (external flash memory?) or use a larger chip.

As a side note, with "bit packing" you could reduce the storage to 20480 bytes, but doing a lookup of the data within that packed data (4 10-bit entries taking 5 bytes) will be slow to do since you have to work out exactly what combination of bits and bytes you need to reconstruct your 10-bit value.


Sodaq Moja — Accessing SW2/SW3 user switches I have a Sodaq Moja, from supporting the project on Kickstarter, and I didn't have much time until now to play with it. Unfortunately, the online documentation for the Moja has disappeared, and only the docs for the new version, the Mbili, is accessible. And nowhere can I see where to access the user switches. Which, to boot, have been reordered in the Mbili, can cut down from 3 to 2.

Would anyone have an idea?

Cheers,

According to the schematics and pictures of the Moja, the Sodaq Moja has no "User Switches".

There are 2 buttons and 1 switch.  The switch is a general power on-off switch.  One button (SW2) is the master reset button for the ATMega328P.  The other button, SW3, is the reset for the X-Bee daughter board.

None of those can be used programmatically.


Detecting if a push button was pressed and released I want to detect if a push button was pressed and released again. So I thought the right approach would be to first wait while the pin yields LOW and then wait while the pin yields HIGH:

void push(int pin) {
  // wait until button was pushed down...
  while (digitalRead(pin) == LOW);
  // ... and released again
  while (digitalRead(pin) == HIGH);
}

That function can be easily reused. The code works fine, but I am just wondering if that solution is considered clean and a good practice.

No, I wouldn't consider that good practice - for one good reason: it's blocking.

Your system can't be doing anything else at all while you're waiting on the button. That may be fine for some situations, but far from ideal for 99% of others.

It is better to remember the state of the button and detect that change of state.

Personally, to make it properly portable, I would implement a class to contain all the state information.  Something like:

class Button {
    private:
        bool _state;
        uint8_t _pin;

    public:
        Button(uint8_t pin) : _pin(pin) {}

        void begin() {
            pinMode(_pin, INPUT_PULLUP);
            _state = digitalRead(_pin);
        }

        bool isReleased() {
            bool v = digitalRead(_pin);
            if (v != _state) {
                _state = v;
                if (_state) {
                    return true;
                }
            }
            return false;
        }
};

Then you can do something like:

Button myButton(3);

void setup() {
    myButton.begin();
    Serial.begin(115200);
}

void loop() {
    if (myButton.isReleased()) {
        Serial.println(F("Released"));
    }
}

Every time myButton.isReleased() is called the current button state is compared against the state it was last time it was called. If it's changed then the button must either have been pressed or released. So you remember that change. If it's been released then you return a true, otherwise return a false.

You can now easily have it work with many buttons:

Button myButton(3);
Button myOtherButton(4);

void setup() {
    myButton.begin();
    myOtherButton.begin();
    Serial.begin(115200);
}

void loop() {
    if (myButton.isReleased()) {
        Serial.println(F("Released 1"));
    }
    if (myOtherButton.isReleased()) {
        Serial.println(F("Released 2"));
    }
}


Can i store a SqlLite DB into an (old) ESP32? (not using SD card) I would like to know if it is possible to store a (little, basic) SqlLite DataBase (or of any other type) into the (old) ESP32.
I don't want to use an SD card for that (for which I already know it is possible).
Thanks in advance for any hint on this

I found these two post to be a useful answer to my question:

ESP32: Best way to store data frequently?

Sqlite3 Library for ESP32 Arduino Core


Arduino Simulator for Windows that can be detected by Arduino IDE through a Virtual COM Port Hello is there an Arduino Simulator for Windows that can be detected by Arduino IDE through a Virtual COM Port?

I've seen simulator online but I can't seem to find a simulator that can be programmed using the Arduino IDE through a Virtual COM port.

One of the option is using Proteus simulator with Arduino library. You can build the program via Arduino IDE, then export the compiled binary (.hex file). Proteus also provided virtual terminal feature (not Virtual COM).


How do I get more than 64 characters of message from serial I am trying to make a moving message board using an Arduino Uno, HC-05 Bluetooth module and DMD board.
Sending message to the DMD through the Bluetooth module can only give a not more than 62 character message.
I need help in what to do to get up to 200 or more. Thanks.

First: There is no such concept of a message on the Serial bus, unless you implement it yourself. On hardware level only individual bytes are transmitted, and you don't even know, when each byte will be transmitted exactly. Since there are only individual bytes in the first place, there is no limitation on how many bytes can be transmitted.

Yes, the Serial library has a limited buffer of 64 bytes, but as Majenko wrote it is not intended for buffering all bytes for one of your messages. It should only buffer the bytes, until the main sketch can read them from the buffer. On reading the bytes will be removed from the buffer, leasing buffer space for new characters.

The buffer size of the Serial library can be increased by changing the numbers in HardwareSerial.h in the following lines

#define SERIAL_TX_BUFFER_SIZE 64

#define SERIAL_RX_BUFFER_SIZE 64

But this is not really the solution to your problem. When first filling the buffer and then read the whole message you just arbitrarly
constrain yourself to a insufficient solution.

Instead of waiting for all the messages bytes (and finally filling up the buffer) you should steadily check, if new bytes are available and then load them into your own buffer. You can use a delimiter byte to mark the end of a message, mostly "\n" (newline character) is used for this. Copy the bytes into your own buffer, until you read the delimiter byte. Then use the message as a whole for your application. Don't forget to clear your buffer afterwards.

The examples for the Serial library, especially the SerialEvent example show how to do this in your code.


How do I send an IR signal from an Arduino I want to send a generic (not Sony, etc.) remote's signal from my Arduino.  I have already used a IR decoder program to capture the timing of the signal:

int IRsignal[] = {
// ON, OFF (in 10's of microseconds)
    88, 88,
    174, 88,
    86, 86,
    88, 86,
    88, 88,
    86, 86,
    88, 174,
    86, 88,
    86, 88,
    174, 174,
    86, 88,
    86, 2252,
    88, 88,
    174, 88,
    86, 86,
    88, 88,
    86, 88,
    86, 86,
    86, 176,
    86, 88,
    86, 88,
    174, 174,
    86, 88,
    86, 0};

Now I need to send this through the IR LED.  I have never written a program that can modulate a signal at this microsecond level.  How would I do this?

Please, take a look at Ken Shirrif's  IRRemote library, as it is what you need. I used it in some project and worked better than other solutions that I coded.


PCF8575c changes address in I2C Scanner I want to connect a PCF8575c pin extender to an ESP32, so that I can light 12 LEDs. The problem is that after the connection, when I try to use an I2C Scanner, it shows me a lot of different addresses, not a constant one. Could this happen from a pin fault? I am using this library:
https://github.com/xreef/PCF8575_library

Also, the I2C scanner can be found here: https://playground.arduino.cc/Main/I2cScanner/

And the pins that I use for the LEDs are defined this way:

  pcf8575.pinMode(P0, OUTPUT);
  pcf8575.pinMode(P1, OUTPUT);
  pcf8575.pinMode(P2, OUTPUT);
  pcf8575.pinMode(P3, OUTPUT);
  pcf8575.pinMode(P5, OUTPUT);
  pcf8575.pinMode(P6, OUTPUT);
  pcf8575.pinMode(P11, OUTPUT);
  pcf8575.pinMode(P12, OUTPUT);
  pcf8575.pinMode(P14, OUTPUT);
  pcf8575.pinMode(P15, OUTPUT);
  pcf8575.pinMode(P16, OUTPUT);
  pcf8575.pinMode(P17, OUTPUT);

The link to the exact PCF8575c:
https://www.aliexpress.com/item/2038559527.html?spm=a2g0o.productlist.0.0.3f8331ebu0zuwr&algo_pvid=5e9fc157-a422-4847-acf4-8618a2d365ea&algo_expid=5e9fc157-a422-4847-acf4-8618a2d365ea-2&btsid=0ab6f82415840969999872503e3228&ws_ab_test=searchweb0_0,searchweb201602_,searchweb201603_

Look at the back of the module. There are 3 groups of 3 solder pads each, marked with A0, A1 and A2. With these pads you can set the 3 least significant bits of the address.

On the images in your product link these pads are unconnected. The middle pin is the address pin. The left pad (which is connected to a trace) is Vcc, the right pad (which is connected to the big trace area) is ground. By connecting the middle pad with ground, you set the address bit to zero. By connecting it to Vcc, you set it to 1.

As the pads are unconnected, the address pins are floating. In that state, the pin is reacting to random electrical noise, thus changing state randomly. So also the address changes randomly.

You need to connect every address pin to either ground or Vcc by adding a solder bridge to the pads.


Why I can't exit this while loop by reading from the Serial? I'm trying to work with the FastLed libraries and i'm controlling a Led Stip via a WEMOS D1 MINI based on the ESP8266, what I'm trying to achieve is to jump from fastled animation to another one..those animations are inside a While loop as shown in the code, so , i thought to just read again from the serial in order to change an integer to exit those while loop, but for some reason is not working as expected. Anyone can help me to uderstand?
CRGB leds[NUM_LEDS];
int incomingByte = 0;
int exit = 0;
void setup() {
    Serial.begin(115200);
    delay( 1000 );
    FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
    FastLED.setBrightness(  BRIGHTNESS );
}

void loop()
{
    while (Serial.available()>0)
    {
      Serial.write("Serial.available");
       incomingByte = Serial.read();

       switch (incomingByte)
        {
          case '1':
            GreenYellow();
            break;

          case '2':
            Sparkle();
            break;
        }
    }
}

void Sparkle() {
    while(exit = 0){
        int Pixel = random(NUM_LEDS);
        setPixel(Pixel,random(255),random(255),random(255));
        FastLED.show();
        delay(50);
        setPixel(Pixel,0,0,0);
        if(Serial.available()>0){
            incomingByte = Serial.read();
            if(incomingByte != '2'){
                exit = 1;
            }
        }
    }
  }
}
void GreenYellow()
{
  for(int x =0; x< NUM_LEDS/2; x++){
    leds[x]= CRGB::Green;
  }

  for(int x =NUM_LEDS/2; x< NUM_LEDS; x++){
    leds[x]= CRGB::Yellow;
  }
  FastLED.show();
}

void setPixel(int Pixel, byte red, byte green, byte blue)
{
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
   FastLED.show();
}
void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  FastLED.show();
}

Bonus question: I read that there is no thread programming on the ESP2866 via the Arduino IDE, am I right?

The problem is that you check inside the two functions Sparkle and GreenYellow for another serial byte. Then when it's unequal, you move back to the while loop where you wait for the next serial byte, but I think you need to use the same one to decide to go to the correct function instead of waiting for a next serial byte.
Probably the easiest is to not read serial in the while loop but check the incomingByte global variable  (containing the last read byte, and e.g. 1 initially), and ONLY in the two functions set that global variable. Then, when returning to the while loop, you check that global variable to jump to the correct function.
So you make a setup function that sets the global variable to 1 (or you do it in the initialization itself):
int incomingByte = 1; // Start with GreenYellow

Then, in the loop function, you use:
void loop()
{
       switch (incomingByte)
        {
          case '1':
            GreenYellow();
            break;

          case '2':
            Sparkle();
            break;
        }
}

If you don't want to start in either one, then use 3 values (0, 1, 2), and ONLY in the loop function read the Serial byte, but don't read it in the functions.
This way it's a bit more cleaner as it separates the LED functionality with the Serial functionality.
The result (using the last method), results in the following code (compiles, not checked).
Comments:

Used an enumeration for the mode

Split functionality of serial data, processing the mode and RGB routines

I added some initialization lines (i.e. constants) to make it compile.
#include <FastLED.h>

#define NUM_LEDS 60 // number of led present in your strip
#define LED_PIN 6
#define BRIGHTNESS 100

enum EMode
{
  ModeNone,
  ModeSparkle,
  ModeGreenYellow
};

CRGB leds[NUM_LEDS];
EMode mode;

void ParseSerialData();
void ProcessMode();
void GreenYellow();
void Sparkle();
void setPixel(int Pixel, byte red, byte green, byte blue);

void setup()
{
    Serial.begin(115200);
    delay( 1000 );
    FastLED.addLeds<WS2811, LED_PIN, EOrder::RGB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
    FastLED.setBrightness(  BRIGHTNESS );
    mode = EMode::ModeNone;
}

void loop()
{
  ParseSerialData();
  ProcessMode();
}

void ParseSerialData()
{
  while (Serial.available() > 0)
  {
    Serial.write("Serial.available");
    char incomingByte = Serial.read();

    switch (incomingByte)
    {
    case '1':
      mode = EMode::ModeGreenYellow;
      break;

    case '2':
      mode = EMode::ModeSparkle;
      break;

    default:
      // Ignore
      break;
    }
  }
}

void ProcessMode()
{
  switch (mode)
  {
  case EMode::ModeNone:
    // Do nothing
    break;

  case EMode::ModeGreenYellow:
    GreenYellow();
    break;

  case EMode::ModeSparkle:
    Sparkle();
    break;

  default:
    // Ignore
    break;
  }
}

void Sparkle()
{
    int Pixel = random(NUM_LEDS);
    setPixel(Pixel,random(255),random(255),random(255));
    FastLED.show();
    delay(50);
    setPixel(Pixel,0,0,0);
}

void GreenYellow()
{
  for(int x =0; x< NUM_LEDS/2; x++)
  {
    leds[x]= CRGB::Green;
  }

  for(int x =NUM_LEDS/2; x< NUM_LEDS; x++)
  {
    leds[x]= CRGB::Yellow;
  }
  FastLED.show();
}

void setPixel(int Pixel, byte red, byte green, byte blue)
{
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
   FastLED.show();
}

void setAll(byte red, byte green, byte blue)
{
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  FastLED.show();
}


Identification of IoT For a school project I Have to make an IoT solution in the retail. We were thinking of a smart clothing hanger. We want to make the hanger smart enough to recognize what clothing is hanging on it. In order to do so the clothing has to be able to send some sort of ID to the hanger.

first thing we thought of was RFID but the hanger next to an one hanger would pick up the signal from the other hanger so that wouldn’t be an option.

Does anyone have any other ideas on what we could try to let the piece of clothing talk to the hanger?

Well I guess the signal strength could be measured but clothes hanged in wardrobe are too close to each other to distinguish them. Maybe close range NFC?

I have other solution to be considered.

Maybe you look at the wrong touchpoint of that interaction. What if the desired action occurs not while it's already hanged but when user put the clothes on hanger? During that, it's not with other clothes (as you grab the hanger in your hand to put the clothes on it).

There are a few things to consider. I guess people put things only on one hanger at once while having clothes in second hand. How many % of users puts clothes on hanger by grabbing it outside of wardrobe (as mundane event/behavior)?

Why it's important?

During that interaction there is a moment when user tries to pair single cloth with single hanger separated from the rest.

The hanger could have additional sensor to know when it happens:

Magnetic field sensor and small magnet in collar?
Capacitive sensor?
Accelerometer?

...so the device will know when that interaction occurs and then activate the reading from single rfid tag.

I guess my answer is more about user experience and the aesthetics of interaction but it can give you some clues to finish your project.


Simple Script controlled by Raspberry not working I can't figure out why the next script is not working. I have attached the Arduino to one USB port of the raspberry pi, in which I've installed pyserial. I just want to turn off/on a led depending of the number I write on the Raspi console (1-> on, 2-> off).

    int led=13;

void setup(){
  Serial.begin(115200);
  pinMode(led,OUTPUT);
}
void loop(){
  if(Serial.available()){
     mode(Serial.read() - '0');
  }
}
void  mode(int n){

    if (n== 1){
         digitalWrite(led,HIGH);
    }
    if (n== 2){
        digitalWrite(led,LOW);
    }
  }

PS: I double checked and the baudrate is configured also at 115200 at the raspi side.
In addition, if I place digitalWrite(led,HIGH) just before  the line  "mode(Serial.read() - '0');" the led turn on when I send some information from the raspi shell (so, works well).

Finally I've found the error, it was the serial communication baud rate: 115200. It seems that at higher speeds it not works properly, lowering it to 9600 do the trick.


Making an automated watering system with Arduino I am trying to make an automated watering system using an Arduino.

Here is my wiring diagram:

And here is my circuit wired up:

Here is the code that I'm using with Arduino. The code seems alright and the wiring on the Arduino seems okay as well, but I don't know where to place a speaker on the Arduino. The biggest problem is that the program doesn't run like I coded. After I uploaded this code to Arduino, the water pump just keeps running forever. Can anyone check up my code to make this run properly?

/**automated watering program **/

#include <avr/sleep.h>
#include <avr/wdt.h>
#define BEAT 300 // define time for the tone.
#define PINNO 12

int led = 13;

void setup() {
  // setup code to run once:
  pinMode(led, OUTPUT);
}

void loop() {
  // main code here, to run repeatedly:
  tone(PINNO,262,BEAT); // C(do)
  delay(BEAT);
  tone(PINNO,294,BEAT); // D(re)
  delay(BEAT);
  tone(PINNO,330,BEAT); // E(mi)
  delay(BEAT);
  tone(PINNO,262,BEAT); // C (do)
  delay(BEAT);
  tone(PINNO,294,BEAT); // D(re)
  delay(BEAT);
  tone(PINNO,330,BEAT); // E(mi)
  delay(BEAT);
  tone(PINNO,392,BEAT); // G(so)
  delay(BEAT);
  tone(PINNO,330,BEAT); // E(mi)
  delay(BEAT);
  tone(PINNO,294,BEAT); // D(re)
  delay(BEAT);
  tone(PINNO,262,BEAT); // C(do)
  delay(BEAT);
  tone(PINNO,294,BEAT); // D(re)
  delay(BEAT);
  tone(PINNO,330,BEAT); // E(mi)
  delay(BEAT);
  tone(PINNO,294,BEAT); // D(re)
  delay(BEAT);
  delay(1000); // Wait for 1 second
  digitalWrite(led,HIGH); //Make No. 11pin output HIGH = 5V
  delay(500); // Watering time
  digitalWrite(led,LOW); //Make No.11 pin output LOW = 0V
  // Shut down program to save battery using by watchdogtimer 24h standby mode
  int var = 0;
  while(var < 10800) {
    delayWDT(9); // 9seconds of shutdown
    var++; // 10800times repeat ＝24h
  }
}

void delayWDT(unsigned long t) {
  // delay excute while using powerdown mode
  delayWDT_setup(t); // watchdog timer setting
  ADCSRA &= ~(1 << ADEN); // ADEN bit clear and stop ADC
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Powerdow mode
  sleep_enable();
  sleep_mode(); // sleep mode
  sleep_disable(); // WatchDog Timer times up and start working again
  ADCSRA |= (1 << ADEN); // turn on the ADC
}

void delayWDT_setup(unsigned int ii) {
  // setting up timer
  // 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms
  // 6=1sec, 7=2sec, 8=4sec, 9=8sec
  byte bb;
  if (ii > 9 ) {
    // get rid of strange numbers
    ii = 9;
  }
  bb =ii & 7;
  if (ii > 7) {
    bb |= (1 << 5);
  }
  bb |= ( 1 << WDCE );
  MCUSR &= ~(1 << WDRF); // MCU Status Reg. Watchdog Reset  Flag ->0
  // start timed sequence
  WDTCSR |= (1 << WDCE) | (1<<WDE); // allow to edit watchdog
  // set new watchdog timeout value
  WDTCSR = bb;
  WDTCSR |= _BV(WDIE);
}
ISR(WDT_vect) {
  // the work after time up, WDT
  //  wdt_cycle++;
}

Problems with your setup:

Your pump is connected to pin 11 but you are controlling pin 13 (int led = 13;)
You have an LED in line with your transistor base. That should be a resistor, and the LED should be in parallel with the base (with its own resistor).
Your transistor is wired wrong. According to the datasheet the pins are C-B-E as viewed from the angle in your wiring diagram. You have the Arduino connected to E instead of B, the pump connected to B instead of C, and ground connected to C instead of E.
You don't have a flyback diode across the motor.

simulate this circuit – Schematic created using CircuitLab


Communication between python script and Arduino sketch I'm trying to transfer data beetween the two scripts. I'm already using the YunMesseger library (https://github.com/plotly/YunMessenger). But it only make the

Arduino -> Python

communication.
I would like to know how to make the reverse way.

I would like to point that I'm search for a solution that doesn't involve the use of the Bridge, because I don't want to have concurrency problems.

One option is to use spacebrew. This is a cloud-based service, however you can run your own server which is based on node.js, so it should work on the Yun.

Your Arduino can then send or receive data using yunSpacebrew, and you can connect it to python using pySpacebrew. This is a pure python library, so it ought to run fine on the Yun.


Is it possible to upload an arduino sketch through the serial port (RX) instead of USB In another words, is it possible to develop a custom bootloader so sketches can be uploaded via serial connection made using the RX/TX pins and not via the USB connector (I am using Pro Micro boards)?
Thanks!

No need to have a specific bootloader. The basic bootloader can do that (in Arduino that's the case so I hope this answer will apply in your case. But if not, the principle is certainly the same).

Once you perform a reset on the board, the bootloader look at the serial port during a short time. If something come, it checks if it's an hex file and if yes it send it to flash. The USB just use the RX input.

So you can send data using a direct connection or using for example a Bluetooh like HC-05. I do that for some project in order to update via Android: the Android app send an order to the Arduino, through Bluetooth.
Receiving this, the Arduino RESET itself, and then the Android App send immediatly data.

On Arduino side: connect for example A0 to RESET PIN and perform a digitalWrite(PIN_RESET,HIGH);
Have also a look at Reset an Arduino Uno in code

After the RESET, the board will reply with 0x14 0x10 (so it send this to TX and so if you have a bluetooh module, you'll received than on your Android App (eg))

You must then send  0x50 0x20 to the board to tell it you enter programming mode.
Then send 0x75 0x20 to get the id of the board in order to be sure you will send the HEX file for the right hardware.
You will receive 0x14 XXX 0x10 where XXX = id of the board

Then you can send the HEX file.

For that, you will send it by blocks of 128 bytes

So start by dividing the HEX to know the number of blocks then loop against this  number:
Start at ADR=0 (adresse dest in flash) and send:

For each block:

1) Send 0x55, low byte of ADR, high byte of ADR, 0x20

2) check reply (must be 0x14 0x10)

3) Send the 128 bytes: 0x64, 0x00, 0x80, 0x46 then the 128 bytes and finish by 0x20 (0x80 is the size)

4) check reply (must be 0x14 0x10)

5) update ADR. Take care: ADR is a word pointer (2 bytes). So ADR = ADR+0X40

Loop on num of blocks

Finish the job by sending 0x51 0x20 (exit programing mode)

Some details:

0x46 before the 128 bytes tells you want to write in flash. Other codes are available eg for checking, getting data etc..

It seems mandatory to send each time 128 bytes. So if your last block is smaller, you need to add some '\0' to get a total of 128. I've been unable to get good results trying to change the 0x80 value and send less bytes. :(

It's not very easy and need tests to get a good code but that really fine to be able to have an Arduino the user can update.

Hope this will help.


How to convert a delimited string of hex numbers to an int array I am sending a string to the Arduino via serial, I made the program that sends the data, so I can change it to anything, but for now it sends a string of hex numbers delimited by ':', so for example 00:AA:FF and I need to get that into an int array onto the Arduino, the main problem is I don't always know how big the array will be, sometimes just 2 indexes, other times 16 indexes.

As I said, I made the program sending the data so I can make the data anything, I just need to get an int array to the Arduino and get it back as an int array via serial

You could store the hex numbers in a int array using strtok() and strtol().

char str[] = "00:AA:FF:7FFF";
int intArray[16]; // Maximum number of hex numbers.

void setup(){

  Serial.begin(9600);

  int counter = 0;
  char * pch = strtok(str, ":");

  while(pch != NULL){
    intArray[counter] = strtol(pch, NULL, 16);
    pch = strtok(NULL, ":");
    counter++;
  }
  Serial.print("Item Count = ");
  Serial.println(counter);

  for(int i = 0; i < counter; i++){
    Serial.println(intArray[i]);
  }

}

void loop(){}


Any idea why my LED fails to operate with the if statement I have tried several workarounds without success.

#include <LiquidCrystal.h>
float tempC;
int tempPin = 0;// BS E D4 D5 D6 D7
int buzzer = 4;
int LED =2;
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
unsigned char i;
void setup()
{
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Temp        C ");
pinMode(LED, OUTPUT);
pinMode(buzzer,OUTPUT);//initialize the buzzer pin as an output
}
void loop()
{
tempC = getTemperature();
lcd.setCursor(6, 0); // Display Temperature in C
lcd.print(tempC);
delay(500);
}
float getTemperature()
{
int tempReading = analogRead(tempPin); // This is OK
double tempK = log(1000000.0 * ((1024.0 / tempReading - 1)));
//Temperature in Kelvin
tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK )) * tempK );
return (tempK - 273.15);

if (tempC>0)
digitalWrite(LED,HIGH);
else
digitalWrite(LED, LOW);
}

The LED fails to operate with the if statement because calling the return statement Terminates a function and returns a value from a function to the calling function, if desired. Try your sketch with the return statement as the "last thing" in the function.

#include <LiquidCrystal.h>

float tempC;
int tempPin = 0; // BS E D4 D5 D6 D7
int buzzer = 4;
int LED = 2;
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
unsigned char i;

void setup() {
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Temp C ");
  pinMode(LED, OUTPUT);
  pinMode(buzzer,OUTPUT);//initialize the buzzer pin as an output
}

void loop() {
  tempC = getTemperature();
  lcd.setCursor(6, 0); // Display Temperature in C
  lcd.print(tempC);
  delay(500);
}

float getTemperature() {
  int tempReading = analogRead(tempPin); // This is OK
  double tempK = log(1000000.0 * ((1024.0 / tempReading - 1))); //Temperature in Kelvin
  tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK )) * tempK );
  if (tempC>0) digitalWrite(LED,HIGH); else digitalWrite(LED, LOW);
  return (tempK - 273.15);
}


All of the sudden the Nano will not accept programming I have been working merrily along with CH340 to make Com10 work.  It has been working flawlessly but now I am getting various messages like it can't open the port then the programmer is not responding.  It tries several times before giving up.

This was working fine yesterday.

I tried uploading to a raw board not connecting to anything and am getting the same result.

Suggestions?

This problem occurs quite often with all the boards. Here is how to troubleshoot it.

1 - Unplug the Arduino.

2 - Upload the program WITHOUT any boards connected to your computer.

3 - Replug your Arduino.

4 - Upload the program WITH your Arduino connected to your PC.

If this doesn't work, read this post by Nick Gammon.


Algorithm to detect motion using ultrasonic sensor I have a PIR sensor which sometimes give false readings and I have added a ultrasonic sensor to compensate for that. I think my algorithm can work, however currently it is very prone to give false positives.

Algorithm theory

My idea is to have an arduino which will obtain six samples and wait 25 milliseconds between each sample and then calculate the variance. If the variance exceeds a specific threshold, which I have set to a thousnad, it will send an motion event over the serial bus.

Problem with the algorithm

Ultrasonic sensors can give faulty responds which usually isn't hard to detect. My HC-SR04 sensor can only accurately read the distance between 2 cm and 400 cm. All the faulty readings are usually way over 400 cm or lower than 2 cm, therefore if is not within these boundaries a new try will be made to get a value within the boundaries, if it fails for three times it will assume the distance is exactly 400 cm.

It is redundant to wait for more than 23280 µs because 400*29.1*2 is the corresponding microseconds it would take for the distance to be 400 cm. pulseIn has a timeout value which can be used for this.

In theory this sounds great to me but very often this algorithm will erroneously send motion events. My belief for this is that when the ultrasonic sensor transmitts a wave and wait for it come back, pulseIn will timeout and retry and yet again ask the sensor to send a wave. This happens before the first wave has come back thus the distance will be incorrect and vary from time to time making the variance higher than my threshold.

If the distance is much lower than 4 metres my algorithm works very well.

What I tried

I figured I might be able to block for some time until the echo pin on the ultrasonic sensor turns low or a time of 100ms has passed. The code hanged and I couldn't communicate with my arduino any more. I can't see the problem with my code to obtain the distance pursuant to the ultrasonic sensor.

for(tries=3;tries;--tries) {
  digitalWrite(TRIG_PIN), LOW); // Set trigger pin low.
  delayMicroseconds(2); // Let signal settle.
  digitalWrite(TRIG_PIN, HIGH); // Set trigger pin high.
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW); // Ping has now been sent.
  unsigned long duration = pulseIn(ECHO_PIN, HIGH, 23280); // Duration is in microseconds
  unsigned long time = micros();
  while(!(PINB & 0b00000010)) { // ECHO_PIN is PB1 or digital pin 9
    if((micros() - time) >= 100000) {
      continue;
    }
  }
  if(duration >= 116L && duration <= 23280L) { // Is duration within boundaries?
    return ((float)(duration)/2.0) / 29.1;
  }
}
return 400.0f;

This just blocks my program indefinently and I had to upload a new program removing that code for my arduino to respond again.

So my question boils down to: how can I resolve this issue where my algorithm very frequently sends motion events erroneously? Is there a better way to detect motion with an ultrasonic sensor?

(EDIT: I was really tired when I wrote the code above and Majenko corrected me, I changed the code for this

for(tries=3;tries;--tries) {
  digitalWrite(TRIG_PIN), LOW); // Set trigger pin low.
  delayMicroseconds(2); // Let signal settle.
  digitalWrite(TRIG_PIN, HIGH); // Set trigger pin high.
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW); // Ping has now been sent.
  unsigned long duration = pulseIn(ECHO_PIN, HIGH, 23280); // Duration is in microseconds
  unsigned long time = micros();
  while(PINB & 0b00000010) { // ECHO_PIN is PB1 or digital pin 9
    if((micros() - time) >= 100000) {
      goto retry;
    }
  }
  if(duration >= 116L && duration <= 23280L) { // Is duration within boundaries?
    return ((float)(duration)/2.0) / 29.1;
  }
  retry:
  continue;
}
return 400.0f;

The main blocking part of your code is this bit:

while(!(PINB & 0b00000010)) { // ECHO_PIN is PB1 or digital pin 9
  if((micros() - time) >= 100000) {
    continue;
  }
}

That is saying "While the echo pin is low, check the time.  If too much time has passed then carry on with the loop".

So basically that will loop until the echo pin goes high, regardless of the time.

The continue command means to jump back to the beginning of the loop that it's in, be that a while, for, or do loop.  In this case it jumps back to the beginning of the while loop it's in.

Instead you should consider using break, which means "Terminate this loop and carry on with what comes next".

Ultrasound sensing with pulseIn(), while simple to perform is rarely particularly accurate.  Any interrupts that occur during the sensing will affect the outcome, and it's only as accurate as the micros() function allows it to be.

If you need a more precise and reliable measurement you should consider using one of the Input Capture modules in the ATMega.  I don't know if there is a library to do it off hand, but programming it through the registers shouldn't be that difficult - just read the datasheet to find out how it all works.

Briefly the operation of IC is:

Send trigger pulse
Start IC timer counting
Pulse arrives
IC stops counting automatically and interrupt is triggered
Read counter value and convert to microseconds.
Set flag to indicate a result is available

The timing source is the main system clock and counting happens in the background completely parallel to the operation of the CPU, so nothing can interrupt it or delay it. Even if the execution of the IC interrupt routine is delayed by another interrupt running the counter value will have already stopped incrementing, so it will have been "captured" and give the correct result every time.


atmega328 raspberry pi 2 communication I have an atmega328p (running on it's internal 8mhz clock) receiving data over rf. I need the data received to be communicated to the raspberry pi 2 using its gpio pins, I cannot use USB. I don't have the budget for a gertduino. Is there any way to do this directly? I only need to be able to receive serial output on the pi, no uploading sketches.

Both the Arduino and the Raspberry PI have interfaces like SPI, I2C and UART. These interfaces will make it easy for you to communicate between the two. I suggest you search for UART unless you need a very high data throughput, then you need to go for SPI. But unless you want to send over a thousand messages per second UART will work just fine.


how to interrupt the loop function and restart it? I have a project with some NeoPixels and other LEDs and an Arduino UNO.
Once switched on, the defaultLEDAnimation with colors and blinking, etc. starts.

I want to trigger some other animations, so I connected two buttons to the Arduino. Whenever you press button1, the Arduino should stop everything it is doing and run animation1. The same goes for button2. if you press it, the Arduino should run animation2. All animations are quite complex and run for several seconds and even minutes.

Now for the challenge: How do I use the two buttons to immediately stop every animation happening and display the appropriate animation?

The tried using interrupts and connected the two buttons to pin 2 and 3.
However, when I press the buttons, the animation starts after several seconds delay. Is there any way to restart the loop function immediately after the interrupt has been made? Or is there another way to trigger my animations with those two buttons?

The code looks something like this:

#define button1 2
#define button2 3

volatile bool shouldPerformButton1Action = false;
volatile bool shouldPerformButton2Action = false;

void setup() {
    attachInterrupt(digitalPinToInterrupt(button1), button1Pressed, RISING);
    attachInterrupt(digitalPinToInterrupt(button2), button2Pressed, RISING);
}

void loop() {
    if (shouldPerformButton1Action) {
        doAnimation1();
        shouldPerformButton1Action = false;
    } else if (shouldPerformButton2Action) {
        doAnimation2();
        shouldPerformButton2Action = false;
    } else {
        runDefaultAnimation();
    }
}

void button1Pressed() {
    shouldPerformButton1Action = true;
}

void button2Pressed() {
    shouldPerformbutton2Action = true;
}

void doAnimation1() {
    for(int i=0; i<10; i++){
        neoPixelStrip.setPixelColor(neoPixelArray[i], neoPixelStrip.Color(255, 0, 0, 255));
        neoPixelStrip.show();
        delay(100);
    }
    delay(1000);
    for(int i=0; i<10; i++){
        neoPixelStrip.setPixelColor(neoPixelArray[i], neoPixelStrip.Color(0, 0, 0, 0));
        neoPixelStrip.show();
        delay(100);
    }
}

The function doAnimation1 is just an example. It will be much more complex.

"How to interrupt the loop function and restart it?"

You don't. That's not how you write Arduino code. You need to have your loop function call a series of non-blocking functions that check to see if it's time to do something, do a very small bit of work if it is time, or just return if it's not time yet.

What I've done is to create a class ArduinoObject that has a setup function,  a start function, a stop function, a loop function, and a boolean property running. My main program has a global variable that holds an array of ArduinoObjects.

Every time through the loop, I check all the ArduinoObjects in the array, and call their loop functions.

The first thing each object does is check its running flag. If running==false, it exits immediately.

Each object uses unsigned long values to track the next millis() time count when it should do something.

Let's say the object does an animation, so it has an unsigned long nextAnimationStepTime. In the loop() function, if nextAnimationStepTime<millis(), it doesn't do anything. If instead nextAnimationStepTime>=millis(), the object advances the animation to the next step, and sets nextAnimationStepTime = millis() + animationStepDuration. That way, next time the object is called, it will wait until it's time to advance the animation yet another step.

Each object is written to only do a tiny bit of work on each pass through the loop, and return as quickly as possible.

With this design, I can add an arbitrary number of objects/tasks to my loop, and all of them get attention on every pass through the loop. Most objects simply decide they're not running, or it's not time to do anything, and return.

You can then add control logic that starts and stops individual objects based on things like button presses.

With this approach you'd have your button 1 press stop animation 2 if it was running and run animation 1. Conversely, pressing button 2 would stop animation 1 if


Leds become dimmer after they reach a certain brightness, why? Even if I don't use buttons and I do an automated thing that makes the led brighter(Even the non-rgb one)after sometime it resets itself to a dimmer light, why?*
int Gled = 5;
int Bled = 6;
int Rv;
int Gv;
int Bv;

int b1 = 7;
int b2 = 8;
void setup()
{

  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  Rv = 0;
  Gv = 0;
  Bv = 0;
  analogWrite(Rled, Rv);
  analogWrite(Gled, Gv);
  analogWrite(Bled, Bv);

}

void loop()
{

  if(digitalRead(b1) == LOW)
  {
    Rv += 10;
    analogWrite(Rled, Rv);
  }
  if(digitalRead(b2) == LOW)
  {
    Gv += 10;
    analogWrite(Gled, Gv);
  }

}

The described behavior stems from 2 important facts:

The loop() function will run very fast (microsecond range), while the button presses of a normal human will be rather slow (in the tens or even hundreds of milliseconds). That means, that with only one button press you will enter the corresponding if statement many times, everytime adding 10 to the value. You don't have control how many times exactly the if statement will be entered, so the value, that comes out after your button press is somewhat randomly growing.

While the analogWrite() function takes an int as the value parameter (16 bits on AVR), internally it assigns that value to the corresponding Timer register, which is only 8 bits big. So it can only hold values between 0 and 255 anyway. If you provide a bigger number as a parameter, the higher part will just be cut off. For example: Providing 257 will result in a value of 1 (= 257 % 256 = 257 % 2^8 --> 257 modulo 256). The higher values get wrapped around back into the range of 0 to 255.

So together you have a value, that is growing very fast and somewhat randomly, while the analogWrite() function will only take the lower 8 bit of that value. The outcome is a rather erratic, somewhat random LED brightness, which is difficult to control.
What to do now? That depends on what behavior you want to have exactly:

One button click (press + release) should increase the value of the corresponding LED by 10:

Currently you are checking, if the button is being pressed. Instead you have to look for the transition between not-pressed and pressed, so a HIGH to LOW transition. You can do that by saving the last read value in a variable at the end of the button reading part and comparing this previous value to the newly read value at the start of it. Though that still leaves you with the bounce problem. There are many measurements, that you can do, to debounce the button (you can google that easily), though here I just will suggest using the Bounce2 library. You can find it here on github or in the library manager (I think). It makes it much easier to read buttons reliably. It has good examples to learn how to use it.

The value should rise, while the button is pressed, and stopping to rise, when it is released again:

Here you should limit the rate in which the if statement is entered. You can do this by limiting the execution rate of the loop() function with a simple call to delay(), though that isn't a good coding practice and can limit you, when adding more functions to your code (because it's blocking the execution of other code). Instead you can use the non-blocking coding style involving the millis() function, that you can see in the BlinkWithoutDelay example. You use a timestamp variable to save the last time, when the if statement was executed. The if statement should then check (additionally to the button state), if enough time has passed, meaning if the difference between millis() and the timestamp is high enough. You can change the interval for this comparison to change the rate, in which the value is increased.


Optocoupler on Tinkercad acting weird So, maybe it's my understanding that is at fault or maybe it's tinkercad. It's probably the former. But anyway here's my problem

I've connected it according to picture

https://imgur.com/a/h2HYgUE

There is no power going through the anode. The cathode is going to ground.
On the upper side 5v is going to base and the emitter sends signals to an input on pin 12.

If i digitalRead pin 12 and Serial.write it. it says 1. which is weird, least for my understanding.

As i understood there needs to be power going through the anode which lights up the diode inside the optocoupler. however there is no power going through the anode yet the emitter gives off a signal.

Anyone mind helping me out in understanding why this is?

Please ignore the resistors on the image

You connected 5V to the base of the transistor inside, so the transistor is turned on all the time.

Move the 5v pin one to the right (middle pin on the 4N35, i.e. the collector), and it should work.


Can I hook up an Analog multiplexer to Arduino Nano? I want to increase the analogue inputs for the Nano. So is it possible to hook up a CD74HC4067 analog multiplexer to it?

Thanks.

yes. those using IO expanders offers more flexibility.


Using XBee and OLED screens with Timer Interrupts I have an Arduino board with a sensor, an OLED screen and an XBee module. I've setup the timer interrupts in timer1 to sample the sensor every one second.
I've done the following:

tried to update the OLED screen with the reading and it works.
tried sending the reading from inside loop over XBee and it works.
tried doing both of the above and the Arduino seems to shut down after a bit.
tried sending the reading from inside the timer interrupt handler and it doesn't work.

Are there limitations on what interrupt handlers can do that I'm not aware of? (Other than using time delays)

Source code

#include <XBee.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

XBee xbee = XBee();
ZBRxResponse response = ZBRxResponse();
ZBTxRequest sensorml_level_0_zbTx = ZBTxRequest(addr64, sensorml_payload_level_0,sizeof(sensorml_payload_level_0));
ZBTxRequest keepalive_level_0_zbTx = ZBTxRequest(addr64, keepalive_payload_level_0,sizeof(keepalive_payload_level_0));

union u_tag {
   uint8_t b[4];
   float fval;
}
u;

void setup() {
   display.begin(SSD1306_SWITCHCAPVCC);
   Serial.begin(9600);
   xbee.setSerial(Serial);
   noInterrupts();
   TCCR1A = 0;
   TCCR1B = 0;
   TCNT1  = 0;
   OCR1A = 62500;
   TCCR1B |= (1 << WGM12);
   TCCR1B |= (1 << CS12);
   TCCR1B |= (1 << CS10);
   TIMSK1 |= (1 << OCIE1A);
   interrupts();
}

ISR(TIMER1_COMPA_vect){
   reading =  analogRead(SENSORPIN);
   reading = (1023 / reading)  - 1;
   reading = SERIESRESISTOR / reading;
   reading = -0.15784 * reading + 305.17;
   sendObservation(reading,00);
}

void sendObservation(float value, int id){
   char idBuffer[] = "00";
   sprintf(idBuffer,"%02d",id);
   uint8_t frame[] = {'0','1','|','0','0','#','0','0','0','0'};
   frame[3] = idBuffer[0];
   frame[4] = idBuffer[1];
   u.fval = value;
   for (int i=6;i<10;i++){
      frame[i]=u.b[i-6];
   }
   ZBTxRequest request = ZBTxRequest(addr64, frame, sizeof(frame));
   xbee.send(request);
}

I skipped most variable declarations to keep the code short.

I suspect send() is blocking.

XBee::send() calls _serial->flush() (see code). Serial.write() buffers data to be written, sets transmitting = true, clears TXC0 and enables the USART data register empty (DRE) interrupt. Bytes will be sent out when the DRE interrupt triggers. However, since you are currently in interrupt context, this will not happen until your ISR returns. flush() spins until TXC0 is set, but since the DRE interrupt never triggers, it spins infinitely. I am basing this on this code.


Why does increasing resistance make a capacitive sensor more sensitive? From the Capacitive Sensor Page on the Arduino website, it states the following:

  The capacitiveSensor method toggles a microcontroller send pin to a new state and then waits for the receive pin to change to the same state as the send pin. A variable is incremented inside a while loop to time the receive pin's state change. The method then reports the variable's value, which is in arbitrary units.

AND

  Use a 1 megohm resistor (or less maybe) for absolute touch to activate. With a 10 megohm resistor the sensor will start to respond 4-6 inches away. With a 40 megohm resistor the sensor will start to respond 12-24 inches away (dependent on the foil size)...

However, as mentioned above, what I'm measuring is the time taken to change state, and I understand that more resistance = more time taken = higher value, how exactly does increasing the resistance make the sensor more sensitive, allowing it to respond without even touching it (i.e., inches away)?

Am I not simply increasing the time taken to change state by increasing resistance? How would that make it more sensitive?!?

A capacitor is created from two conductors with a dielectric between them. The capacitance of the capacitor is determined by the surface area of the conductors and the distance between them. The larger the conductive surface, the higher the capacitance. The further apart the conductors, the smaller the capacitance. Using a higher resistance means that you can use a smaller capacitance, i.e. be further away from the sensor, to get the same results.


Assign and control Digital pin from String Here is modified version of Blink example

#define D8  13

String p = "D8";

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(D8, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  byte pin[2];
  p.getBytes(pin, sizeof(pin));

  digitalWrite(D8, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(D8, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

D8 defined above is a byte of length 2. So LED turns on/off if I mention D8 on digitalWrite(D8, HIGH). Similarly I am getting the same byte D8 from String p = "D8", and converting it into byte of length 2, but assigning pin to digitalWrite(pin, HIGH/LOW) doesn't works. Has anyone tried something similar before ? any help would be appreciated :)

C and C++ programs get compiled in multiple passes through various programs/steps. One of the first is the C Preprocessor, which handles the #define preprocessor directive.

It's basically a big find/replace function. After the preprocessor is done, anywhere you had D8 outside of a string literal, would have the value 13. It's not a variable or a string -- it's simply the number 13.

But the String p, which has content "D8" doesn't get replaced by the #define directive because it's part of a string, and the preprocessor doesn't modify strings in that way.

Also, p converted to a byte array of length 2 does not have anything like 13 as the value. It has 0x44 and 0x38 (or, in decimal, 68 (ASCII 'D') and 56 (ASCII '8')). Disregarding that digitalWrite() and pinMode() do not accept byte arrays, only bytes, you are passing in a byte that doesn't represent pin 13.

If you want to assign the pin via a string, then you would need to use programming to examine the string and pick the right byte value, and each possible value would have to be explicitly enumerated and checked for.


Measuring LPO (Low-Pulse Occupancy) I'm using an Arduino clone (Seeeduino Lotus) together with a Shinyei PPD42NS sensor to measure air quality. The sensor reports its measurement as Low-Pulse occupancy. What would be the best way how to collect the value with Arduino? Currently I'm simply looping for some predefined duration using pulseIn:

unsigned long starttime;
register unsigned long sample_time; // ms
register unsigned long lowpulseoccupancy = 0; // us

// Wait for the signal to return to HIGH
pulseIn(DUSTPIN, LOW);
// Now start measuring
starttime = millis();
while ((sample_time = (millis() - starttime)) < DUST_SAMPLE_TIME_MS) {
    lowpulseoccupancy += pulseIn(DUSTPIN, LOW);
}

ratio_pct = lowpulseoccupancy / (sample_time * 10.0);

Is there a better way? In particular, this tight loop prevents Arduino from doing anything else for 30s (or a similar period).

I was thinking about using interrupts, either triggering on CHANGE, or (if that's possible) having two functions, one triggering on RISING and another on FALLING. Are there any caveats when doing so?

You can trigger on CHANGE, and check in your handler which case it is:

   attachInterrupt(digitalPinToInterrupt(my_pin), my_handler, CHANGE);
    (...)
    void my_handler(void) {
      if(LOW==digitalRead(my_pin)) {
        //do_falling();
      }
      else {
        //do_rising();
      }
    }

Another option would be to use a timer to poll your input, and implement a logic on top of this.


I2C communication between 2 Arduinos with updated wire library I would like to enable communication between two Arduino 101. From what I have read, the best method is to use I2C using the wire library. However, it seems as though the newest Arduino IDE has an updated version of the Wire library that no longer includes the begin(int) and onRequest functions.

All of the tutorials for I2C communication use these methods, so I am unable to follow and use them. It looks like when I change the board to Arduino Uno these functions are found, but as soon as I change the board to Arduino 101 the following errors appear no matching function for call to TwoWire::begin(int).

When I try replacing my wire library with the older version, I get other errors for missing libraries and if I replace everything it is unable to compile on Arduino 101.

Can someone please help me or direct me to a I2C tutorial that uses the most updated version of the Wire library?

The problem I see is the Arduino 101 uses an Intel microprocessor (Curie) instead of an Atmel microprocessor.

The only information I could find is on the Arduino page for the 101, which mentions it has dedicated pins for I2C, but it also says that you can use the Wire library. Maybe you just need to update your IDE?

I'd help more, but I can't seem to find any useful information on the Curie...


Is 1MB flash enough for OTA upload in ESP-01? I'am asking this question, because in my ESP-01 OTA upload always fail. In fact update won't even start. When update was triggered esp wifi led(build in blue) indicates "working" , but after cca one second esp reset itself. And The original program remains and starts again...

Yes, 1MB is fine for OTA. There are, though, a few caveats when working with OTA that you must observe regardless of the flash size:

The maximum OTA program size is less than half the available flash size. Typically it is about 500kB. Two copies need to be stored in flash, plus the partition table and NVRAM. The rest of the flash on larger chips is most often dedicated to FS storage.
The device must first be programmed through USB with an OTA-compatible partition layout.
After programming through USB it must be manually reset or power cycled to set the boot mode correctly.
You can not change the partition layout over OTA programming. You need to make sure you have the same partition layout selected as when you originally programmed through USB.
ArduinoOTA.handle(); has to be called very regularly to handle the programming request. You can't have any blocking code in your sketch that might stop that from being called.

Observe all those and you should be able to program over WiFi with no problems.


Can I connect TFT LCD screen to Arduino Leonardo same way as it's recommanded for Arduino Uno? I want to connect the Arduino TFT LCD 1.77" screen to an Arduino Leonardo. Acording to this tutorial I should connect some pins on LCD screen to ICSP pins on Leonardo but I don't have equipment to do it. Can I just connect LCD screen to Leonardo in the way it't recommanded for an Arduino Uno (same tutorial above) using only digital and power pins. And then use sketches for Uno. Will it work?

Also, is it safe for LCD screen?

I think it could work, but not easily. I.e. you would need to tweak the code and anyway you will end up with really low performance.

This is the reason:

  SPI: on the ICSP header. These pins support SPI communication using the SPI library. Note that the SPI pins are not connected to any of the digital I/O pins as they are on the Uno, They are only available on the ICSP connector. This means that if you have a shield that uses SPI, but does NOT have a 6-pin ICSP connector that connects to the Leonardo's 6-pin ICSP header, the shield will not work.

Source: https://www.arduino.cc/en/Main/ArduinoBoardLeonardo

  The screen can be configured for use in two ways. One is to use an Arduino's hardware SPI interface. The other is to declare all the pins manually. There is no difference in the functionality of the screen between the two methods, but using hardware SPI is significantly faster when drawing.
  If you plan on using the SD card on the TFT module, you must use hardware SPI.
  All the examples are written for hardware SPI use.

Source: https://www.arduino.cc/en/Guide/TFT#toc4

In the end I think it would be better to get the equipment needed...

Edit: You can try with this constructor:

  When not using hardware SPI, you can use any available pins, but you must declare the MOSI and SCLK pins in addition to CD, DC, and RESET.

#define SCLK 4
#define MOSI 5
#define CS   6
#define DC   7
#define RESET 8

TFT myScreen = TFT(CS, DC, MOSI, SCLK, RESET);

Source: https://www.arduino.cc/en/Reference/TFTLibrary


My Arduino Uno buzzer isn't working /*

*/

void setup() // Built in initialization block
{
    Serial.begin(9600);
    Serial.println("Beep!");
}

void loop() // Main loop auto-repeats

{

//   Serial.println("Beep!");

   tone(4, 3000, 1000); // Play tone for 1 second

   delay(1000); // Delay to finish tone
}

First, take a look at the two links provided in the comments to your question and explain why your question is different from them.  Start by describing your "buzzer."  If your question is not significantly different then it will attract downvotes instead of answers, or it may be marked as duplicate or just simply closed.

Here is one solution, making the assumption you are writing about a piezo beeper:

void setup() {
  pinMode(4,OUTPUT);
}
void loop() {
  digitalWrite(4,HIGH);
  delay(1000);
  digitalWrite(4,LOW);
  delay(1000);
}

Alternatively, take the first example program from your IDE, called blink, and hook your beeper to pin 13 (positive) and GND (negative) while that runs.  It does basically the same thing.


Burning Arduino Bootloader I'm trying to use an atmega chip from an arduino on a breadboard, with minimal hardware (using the internal 8mhz clock).  I am using the article in the link provided.  When I reach the final step (burning the bootloader), I get an error telling me the device signature is wrong-

Arduino: 1.8.5 (Windows 10), Board: "ATmega328 on a breadboard (8 MHz internal clock)"

avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

Error while burning bootloader.

I am assuming the error is because the chip is from a uno clone, and uses an atmega328p-pu chip.  How am I able to override this check using -F, as described in the error message?  Or is there maybe some other way i can fix this?  Thanks in advance.

https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard

One of the parameters that you have to give avrdude is the microcontroller you are using, and then it checks the signature of the micro to ensuere that everthing is ok. this parameter is passed through -p flag

avrdude -p <microcontroller name>

For ATmega328 this parameter should be m328 and in your case, with ATmega328p this parameter should be m328p. All options avalible can be checked in man page.


How can you reduce the clock frequency of an Arduino Mega? I'm trying to debug a problem and need to reduce the speed of the clock on my Arduino Mega from 16MHz to 8MHz.

I can't find any simple way of doing so, so I wanted to know if there were any gurus here who knew if this was possible, as well as how to do it.

WITHOUT PRESCALER:

long int runTime;

void setup()
{
  Serial.begin(9600);     //Setting the data transfer rate
}

void loop()
{
  delay(1000);
  runTime = millis();
  Serial.print("Runetime: ");
  Serial.println(runTime);
  delay(100);
  exit(0);
}

OUTPUT: 999

WITH PRESCALER:

long int runTime;

void setup()
{
  Serial.begin(19200);   //Setting the data transfer rate for when CLK Freq. is Halfed

  CLKPR = _BV(CLKPCE);  // enable change of the clock prescaler
  CLKPR = _BV(CLKPS0);  // divide frequency by 2
}

void loop()
{
  delay(1000);
  runTime = millis();
  Serial.print("Runetime: ");
  Serial.println(runTime);
  delay(100);
  exit(0);
}

OUTPUT: 999

You can set the clock prescaler for that:

void setup() {
    noInterrupts();
    CLKPR = _BV(CLKPCE);  // enable change of the clock prescaler
    CLKPR = _BV(CLKPS0);  // divide frequency by 2
    interrupts();
}

This is explained in section 10.12 and 10.13 of the
ATmega2560
datasheet.

Of course, changing the clock frequency will mess with the time-related
function (millis(), delay() and co.) and the baud rate of the serial
port.

Edit: Here is a small program to demonstrate the slowing of the
clock:

//#define SLOW_CLOCK

void setup()
{
#ifdef SLOW_CLOCK
    noInterrupts();
    CLKPR = _BV(CLKPCE);  // enable change of the clock prescaler
    CLKPR = _BV(CLKPS0);  // divide frequency by 2
    interrupts();
#endif
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
}

This makes the LED flash at 1 Hz. If you uncomment the line
#define SLOW_CLOCK, it instead flashes at 0.5 Hz.


"No Socket available" for WiFiClient I have an LDR/Photocell which sends a value 1 or 0 (depending on the value) to a text file on my web address. The code works for a few seconds then prints out No Socket available.

Any help will be appreciated; code below.

#include <SPI.h>
#include <WiFi.h>

int LDR = A0;
int LED = 11;
char ssid[] = "SSID";
char password[] = "password";
int status = WL_IDLE_STATUS;

char server[] = "www.example.com";
int value;

void setup() {
  Serial.begin(9600);
  pinMode(LDR, INPUT);
  pinMode(LED, OUTPUT);
  connectWifi();
  printWifiStatus();
  // postData();
}

void loop() {
  value = analogRead(LDR);
  postData();

  delay(10000);
}

void connectWifi() {
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, password);
    delay(500);
  }
}

void printWifiStatus() {
  // Print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // Print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // Print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

void postData() {
  WiFiClient client;
  if (client.connect(server, 80)) {
    Serial.println("Connecting...");
    if (value > 350) {
      Serial.println("0");
      digitalWrite(LED, LOW);
      String data = "value=0";
      client.print("GET /example/client.php?");
      client.print(data);
      client.println(" HTTP/1.1");
      client.println("Host: www.example.com");
      client.println("Connection: close");
      client.println(); client.println();
      //client.stop();
    } else {
      Serial.println("1");
      digitalWrite(LED, HIGH);
      String data = "value=1";
      client.print("GET /example/client.php?");
      client.print(data);
      client.println(" HTTP/1.1");
      client.println("Host: www.example.com");
      client.println("Connection: close");
      client.println(); client.println();
      //client.stop();
    }
  } else {
    Serial.println("Connection failed");
    client.stop();
  }

}

Output:

Attempting to connect to SSID
SSID: SSID
IP Address: 255.255.255.255
signal strength (RSSI):-47 dBm
Connecting...
1
Connecting...
0
Connecting...
0
Connecting...
0
No Socket available
Connection failed
No Socket available
Connection failed
No Socket available
Connection failed
No Socket available

Actual web address omitted.

I guess you have commented the command:
 //client.stop();

If you allow it, I guess you will have your code running


How do I set a 25 kHz PWM signal on an ESP-WROOM-32? I want to control a single pin of an ESP-WROOM-32 to have a 25 kHz PWM signal. How do I do that in Arduino Studio? I compiled a "hello world" program for such a device successfully in Arduino Studio, now what steps do I need to take? (Other libraries? Source Code?)

FYI: I'd like to do quite the same as provided in Set PWM frequency to 25 kHz but not on an AVM micro-controller but an ESP32. There are tons of explanations for original Arduinos and ESP8266s using bit banging in various forms. But how do I do that on an ESP-WROOM-32 using no bit banging but built in PWM?

Background: I'd like to control a standard 12V PWM fan with this signal. As far as I learned I just can connect a pin with the PWM input of the fan. I just don't seem to be able to figure out how to produce such high frequent PWM signals on an ESP32 :-/ Please help!

It is very simple to set up a PWM signal at any frequency you desire, with any resolution you desire, provided you don't exceed the maximum 'bandwidth': the frequency multplied by the resolution must be less than half the clock speed of the device.

The full explanation with relation to the ESP-IDF is available here. The article explains the intricacies of all the channels and their configurations. I must confess I have not read it all, because my application was very basic.

In setup(), the code required to instantiate a PWM signal on channel chan at frequency freq, with a resolution of bit_num bits is:

double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)

The code to attach the channel chan to an output pin pin is:

void ledcAttachPin(uint8_t pin, uint8_t chan)

Within loop(), or otherwise, inflict a duty cycle duty to a given channel chan using:

void ledcWrite(uint8_t chan, uint32_t duty)

I recommend perusing esp32-hal-ledc.c in the core files you installed that enabled you to program the ESP32 in Arduino Studio. You don't need to include any files to get the above functionality, but it's always good to know a bit about what goes on behind the scenes.

A few things to note, if reading through the core code is too much:

chan can only be between 0 and 15, and the function will return 0 if you try an number outside these bounds;
you can't attach the PWM output to all of the GPIO pins, as some are input only and others might have secondary functions that you need;
duty is a 32-bit type but the maximum value is determined by the resolution you used for bit_num. For example, if bit_num is 8 then the range of duty is from 0 to 255. I don't know what happens if you put higher number: the duty may stay at 100%,  or the duty may be bitmasked such that writing 256 is the same as  0, 257 is 1, etc.

Once you have mastered this, the ESP32 includes 'fading' functionality, whereby the duty cycle changes from x% to y% in z milliseconds. There are a number of tutorials on the internet for such a thing.

FINAL NOTE:

If you haven't already, take a look at Intel's PWM fan specs. It states that you need an open-collector or open-drain source provided, in your case, by the ESP32. There's a chance that the PWM pin is pulled up to 5.25V within the fan; this will hurt the ESP32 if you just wire the two together. Likewise, the Tachometer output is pulled all the way up to 12V. This will kill the ESP32 if you wire it directly to the fan.


How to upload one program into several Arduinos at once? I am trying to upload a single program to a number of Arduinos one by one. But it is time consuming. So I would like to know if there is any way to upload the code at once to multiple Arduinos.

I have tried as follows:

3 Arduino with all the Rx, Reset, Vcc, Gnd line connected to each other. Only pin left is Tx line. So I just connect the Tx line of one arduino and program it and so on.

Is there any other way?

Are you programming them for the first time or doing a update?

If is the first programming, I cant see another way.

Otherwise, If is a update and your Arduino have a Wifi module you could try something like an update on the air, where you put your new firmware in a server for example and all devices updates yourself automatically or by a command.

Google for Arduino OTA (on the air) you will get a lot of source code and examples of doing that.


Can Arduino Uno R3 board remove chip on the board First off, got my Elegoo Uno board as Christmas gift, so this is all new to me.

Here is my problem, I built an motor project and the chip has been programmed. Can I remove the chip from the Uno board?

Or can I placing a new chip onto the Uno board?

Best regards.

It depends, if the chip has not been soldered, but placed in an IC (DIP) socket, than you can remove the programmed chip, and use it in another circuit and place another (same) IC in the IC socket of the Uno to be reprogrammed.

You also could desolder it, but I would not advice that; also most of the Uno's having a soldered IC use SMD instead of DIP.

Also, to replace the IC, you need to install a bootloader on the IC to be placed in the new Arduino (thanks for the addition Roberto Lo Giacco).

Below is a version with DIP that easily can be replaced, hence the big IC and the socket:

Below is a version with SMD that cannot easily be replaced, hence the small IC without a socket:


What are the connectors used in the arduino mega? I am trying to build a shield for an arduino mega.For that i need to know the type of the female connectors that are soldered in the pins of the arduino mega in order to choose the correct male connectors.

Look for male pin header strip, with 0.1 inch (2.54mm) pitch.

In single and dual row form.

Specifically they are:

8x1 ADCL
8x1 ADCH
8x1 PWML
8x1 PWMH
8x1 Communication
6x1 Power
18x2   digital IO (on the side)

Source: Schematics


Arduino UNO Chinese Clone LEDs not lighting up Hi all,

In the screenshot of a circuit I've included, I'm attempting to light up 4 LEDs off of pin 2. In circuits.io, everything works great. 3 blue LEDs and 1 red LED light up and blink as planned. When I create this same circuit on a Arduino Uno Chinese clone, IF the LEDs are all blue, they all light up and blink. If I change one of them to red, yellow, or green, ONLY the red, yellow, or green one lights up. The three blue LEDs no longer light up. It also doesn't seem to matter, where the off blue LED is put.

Not sure what's wrong.

Use one resistor per led, not one for all of them.

This is because different color leds have different forward voltages. Red requires a lower voltage to light up. So it will guzzle up all available current, while the blue leds are waiting for the voltage to go higher (which never happens).


Burn arduino bootloader using ubuntu 16 I get the following error when I try to burn the arduino bootloader on an atmega328 mcu:

avrdude: verification error, first mismatch at byte 0x0000
         0xfd != 0x05

I am using an Arduino as ISP programmer. My computer runs Ubuntu 16.

This did not happen when I was using Ubuntu 14. I also tested it on another machine with Ubuntu 14 and this error does not appear. Seems to be something with Ubuntu 16. I installed Arduino IDE using the out of the box repo.

The avrdude command launched by the IDE is:

/usr/share/arduino/hardware/tools/avrdude -C/usr/share/arduino/hardware/tools/avrdude.conf -v -v -v -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -b19200 -e -Ulock:w:0x3F:m -Uefuse:w:0x05:m -Uhfuse:w:0xde:m -Ulfuse:w:0xff:m

Am I safe replacing the -Uefuse:w:0x05:m with -Uefuse:w:0xfd:m ?? If answer is yes how can I get the IDE to do this correctly?

Uploading a sketch works pretty well.

I had same problem and I think I have solved it.

In boards.txt file, I had:

##############################################################

diecimila.name=Arduino Duemilanove or Diecimila

diecimila.upload.tool=avrdude diecimila.upload.protocol=arduino

diecimila.bootloader.tool=avrdude diecimila.bootloader.low_fuses=0xFF
diecimila.bootloader.unlock_bits=0x3F
diecimila.bootloader.lock_bits=0x0F

diecimila.build.f_cpu=16000000L diecimila.build.board=AVR_DUEMILANOVE
diecimila.build.core=arduino diecimila.build.variant=standard

## Arduino Duemilanove or Diecimila w/ ATmega328
## --------------------------------------------- diecimila.menu.cpu.atmega328=ATmega328

diecimila.menu.cpu.atmega328.upload.maximum_size=30720
diecimila.menu.cpu.atmega328.upload.maximum_data_size=2048
diecimila.menu.cpu.atmega328.upload.speed=57600

diecimila.menu.cpu.atmega328.bootloader.high_fuses=0xDA
diecimila.menu.cpu.atmega328.bootloader.extended_fuses=0x05
 diecimila.menu.cpu.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex

diecimila.menu.cpu.atmega328.build.mcu=atmega328p

## Arduino Duemilanove or Diecimila w/ ATmega168
## --------------------------------------------- diecimila.menu.cpu.atmega168=ATmega168

diecimila.menu.cpu.atmega168.upload.maximum_size=14336
diecimila.menu.cpu.atmega168.upload.maximum_data_size=1024
diecimila.menu.cpu.atmega168.upload.speed=19200

diecimila.menu.cpu.atmega168.bootloader.high_fuses=0xdd
diecimila.menu.cpu.atmega168.bootloader.extended_fuses=0x00
 diecimila.menu.cpu.atmega168.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex

diecimila.menu.cpu.atmega168.build.mcu=atmega168

##############################################################

I have replaced the line containing:

diecimila.menu.cpu.atmega328.bootloader.extended_fuses=0x05

with:

diecimila.menu.cpu.atmega328.bootloader.extended_fuses=0xFD

Everything is ok now.

I can install boot loader on an ATMEGA328P (with an usbasp programmer), and I can install sketchs after that (via usb serial).

I don't know if it's the best way to solve the problem, but it works.
Hope this will help you, if not already solved.


Combining Strings into a datestamp I'm creating a weather station / environmental datalogger and am saving my data to a SD card Breakout. The SD card works fine but I would like to name the files I am saving on it after the date when the readings were taken.I've tryed multiple things but I can't work out how to combine the date from my RTC and put them in a file name. I've tryed this:

dataFile = SD.open(String(now.day()) + "-" + String(now.month()) + "-" + String(now.year()) + ".csv",FILE_WRITE);

But this gives me an error -

char dateName[13] = {String(now.day()) + "-" + String(now.month()) + "-" + String(now.year()) + ".csv"};
dataFile = SD.open(dateName,FILE_WRITE);

But this gives me this error:

 cannot convert 'StringSumHelper' to 'char' in initialization

Help! How do I do this?

EDIT: As noted by Klaus Warzecha, the SD library may only support 8.3 format filenames (i.e. 8 characters for the name, 3 characters for the extension). The solution may in fact be to ensure that the years is only 2 digits, resulting in names like: 20-12-14.csv

From what I can see in the SD library code, the open() method isn't designed to accept a String object as a parameter. It only wants a plain old C-style string (which means a char array). That explains why your first example doesn't work -- it's trying to pass a String object.

The second example unfortunately is invalid C++. You simply can't initialise an array like that. What you want to do instead is to build the String object, then extract the characters out using String::toCharArray().

Something like this should work:

String filename = String(now.day()) + "-" + String(now.month()) + "-" + String(now.year()) + ".csv";
char str[16] = {0};
filename.toCharArray(str, 16);
dataFile = SD.open(str, FILE_WRITE);

I'm not sure what your now.year() returns; i.e. if that's a 2 digit or 4 digit year. I've assumed 4 digits, so I've made the char array big enough for 15 characters in total, plus an extra null terminator (which is essential for C-style strings).


Set slide potentiometer values I am using the Grove - Slide Potentiometer (http://wiki.seeedstudio.com/Grove-Slide_Potentiometer). How can I set the potValue so that at maximum it will 128?

int potPin= A0;
int readValue;
int potValue;

void setup() {
  pinMode(potPin, INPUT);
  Serial.begin(9600);
}

void loop() {
 readValue = analogRead(potPin);
 potValue = (255./500.) * readValue;
 Serial.print("You are writing a value of ");
 Serial.println(potValue);
}

analogRead() returns 0x0000 to 0x03ff

If the max data 0x03ff is shifted to the right by 3 bits (or divide by 8),
then 0x03ff becomes 0x007f, or 127.

I think this will do it:

desiredMax = analogRead(A0) >> 3; // divide 1023 max by 8, becomes 127 max


What's the function of this transistor on Arduino Mega? I am trying to get information about the transistor on the Arduino Mega board below:

It says "340P" on the transistor. I want be able to know which model transition is this so that I can check its documentation. It also want to know what it is driving or its function on the Arduino board.

It's a P-channel MOSFET.  It's job is to act as a "dropless" diode.

The principle is this:

MOSFETs have a built-in diode across them in reverse bias (an effect of the chemistry)
The P-channel MOSFET is connected backwards in series with the incoming USB power.
The internal diode conducts power when there is +5V in to the USB to give power to the board.
The diode imposes a voltage drop, but there is enough voltage still to run the circuitry.
An op-amp compares the incoming voltage from the barrel jack (divided by 2) against 3.3V.  If it's less than 3.3V (6.6V incoming) or not there at all, it turns on the P-channel MOSFET
The MOSFET then short circuits the internal diode removing the voltage drop, giving the full 5V from the USB to the rest of the board.

simulate this circuit – Schematic created using CircuitLab

Note: diode shown is internal to the MOSFET.

The MOSFET is designated T2 in the schematic, and is a FDN340P on the reference design, although the actual model is not that critical, as long as the threshold voltage is above about -3V and it can happily handle 500mA or more.


Two floating point values do not get added and printed on ESP-WROOM-32 I have a Olimex ESP32-PoE board which has a ESP-WROOM-32.

I just found out a strange behaviour for printing floating point numbers on the board.

Sketch

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  float a=34567891.234;
  float b=2.3456;
  a++;
  Serial.print(a+b, 4);
  Serial.println("");
  delay(1000);
}

the sketch is extremely simple where I want to add two floating point numbers, one a big and another small to print their addition result upto 4 places.

Output

on the serial console in the Arduino IDE

34567896.0000
34567896.0000
34567896.0000
34567896.0000
34567896.0000
34567896.0000
34567896.0000
34567896.0000
34567896.0000
34567896.0000
34567896.0000
34567896.0000
34567896.0000

Everytime I increment the float a using a++ i expect it to increment by one and print the result but the output above is completely off.

Without Increment

void loop() {
  // put your main code here, to run repeatedly:
  float a=34567891.234;
  float b=2.3456;
  Serial.print(a+b, 4);
  Serial.println("");
  delay(1000);

}

output

34567896.0000
34567896.0000
34567896.0000

Same output.

Is this Board specific or is the Serial.print not supporting float?

Try doubles instead of floats.

Your initial value, 34567891.234 needs 35 bits of precision to keep track of the decimals, but floats only have 24 bits pf precision. So to have enough precision to keep track of the difference between 34567891.234 and 34567891.234+1, you need higher precision storage.

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  double a=34567891.234;
  double b=2.3456;
  a++;
  Serial.print(a+b, 4);
  Serial.println("");
  delay(1000);
}


How to convert hex to ASCII I am receiving bytes, converting them into hex and now I need to convert the hex to ASCII. Can it be done on an Arduino? Or do I need something else?
I am new to programming with Arduino.

If you have a byte variable b, you can

write(b) it as it is. if it is ASCII code of a readable character, the Serial Monitor will display it as that character, for example for 65 it will printt 'A'
print it as decimal number with print(b). for 65 it will print "65"
print it as hexadecimal number with print(b, HEX). for 65 it will print "41"
print it as a number in other base with print(b, base), for example print(b, 2) will print 1000001 if b is 65 in decimal


nRF24L01+ packet loss caused by Arduino reading and communicating with sensors I have 2 Arduinos communicating with each other. My problem is that one sends packets every 1.5-2 seconds but the other Arduino does sensor reading and data uploading with a Wifi module, which may take up to 5 seconds until the next time the nRF24L01+ is available to receive data.

This results in about 4 packet losses and if I am lucky sometimes 2. Is there any way that when the nRF24L01+ sends data, the other Arduino stops everything to get the data? Like a communication between these two Arduinos that will be open 24/7, so that the other Arduino can multitask (reading sensors and upload the data through wifi).

I am using the code from this tutorial. Here is a my problem in an image (I hope this helps you understand it). Thanks in advance.

You need to re-factor your program somewhat (I would imagine).  The nRF needs to be read at the same time as doing other things. That means interleaving it with your other operations.

There is a concept called a finite state machine which is the best way of writing a complex program like this. The idea is that nothing ever blocks, it just changes states. And all the time other things can be happening, such as reading the nRF24L01+ module.

I have a little tutorial on the Finite State Machine here:

https://hackingmajenkoblog.wordpress.com/2016/02/01/the-finite-state-machine/

If you use the Finite State Machine concept to run the reading of your sensors and the writing of data to the WiFi the nRF can then be polled constantly outside of the FSM constantly - maybe with an FSM of its own to deal with reception etc.

Things to remember:

Avoid delay(), certainly for anything longer than a couple of ms.
Avoid while(), for(), etc except for very short loops that finish quickly.
Any operation that takes more than a few ms to complete should be broken down into a number of sub-operations and coded as separate states of the FSM.


Shift Register Not Working I am trying to learn how to use a shift register to control 8 LEDs but for some reason my shift register is misbehaving and none of the LEDs are lighting up. I imagine that it's a problem with my wiring? I have replicated the circuit on 123D Circuits.

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  // count from 0 to 255 and display the number
  // on the LEDs
  for (int numberToDisplay = 0; numberToDisplay < 256; numberToDisplay++) {
    // take the latchPin low so
    // the LEDs don't change while you're sending in bits:
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);

    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    // pause before next value:
    delay(500);
  }
}

From the Arduino website:

  shiftOut()

  Description

  Shifts out a byte of data one bit at a time. [...]

  Note: if you're interfacing with a device that's clocked by rising
  edges, you'll need to make sure that the clock pin is low before the
  call to shiftOut(), e.g. with a call to digitalWrite(clockPin, LOW).

You need to pull clockPin low before each shiftOut() call, as the documentation says.

Also, you have misunderstood the behaviour of the latchPin. This can be high or low at any time; it's the change from low to high that latches the data into the output cells.


IDE 1.6.10 on LinuxMint 17.3 Cinnamon When compiling I get the error
'as: unknown option »-mmcu=avr5« exit status 1'

I succeeded now using your piece of advise. Thank you so much.

Delete or rename the old "Arduino15" directory located at /home/(username)/.arduino15    (a.k.a. ~/.arduino15) and re-install 1.6.10.


Inheritance not working as expected Short version: This is a lighting control project.  Some of the clases are Pin and  Channel. Channel contains a Pin.  Pin is a base class for DigitalOutPin and will be the base class for AnalogOutPin, and I want Channel to be able to use any child of Pin.

Pin has an abstract method setPinValue(), but when I create a DigitalOutPin object and call setPinValue(), Pin.setPinValue() gets called, not DigitalOutPin.setPinValue() and my program doesn't work because Pin.setPinValue() is empty as it's supposed to be overwritten.

Long version:
If I leave out the definition of Pin.setPinValue(), I get that most idiotic of error gcc messages, "undefined reference to `vtable for Pin'".  If I make it pure virtual I get several errors in the form of

In file included from /devel/arduino/lightbright/LightBrightMain/LightBrightMain.ino:9:0:
/devel/arduino/libraries/LightBrightLib/Channel.h:21:20: error: cannot declare parameter 'pin' to be of abstract type 'Pin'
     void begin(Pin pin, int channelNumber);
                ^
In file included from /devel/arduino/libraries/LightBrightLib/DigitalOutPin.h:10:0,
             from /devel/arduino/lightbright/LightBrightMain/LightBrightMain.ino:8:
/devel/arduino/libraries/LightBrightLib/Pin.h:16:7: note:   because the following virtual functions are pure within 'Pin':
 class Pin
   ^
/devel/arduino/libraries/LightBrightLib/Pin.h:33:18: note:  virtual void Pin::setPinValue(int)
     virtual void setPinValue(int value)=0;
              ^
In file included from /devel/arduino/lightbright/LightBrightMain/LightBrightMain.ino:9:0:
/devel/arduino/libraries/LightBrightLib/Channel.h:23:9: error: invalid abstract return type for member function 'Pin Channel::getPin()'
 Pin getPin();
     ^
In file included from /devel/arduino/libraries/LightBrightLib/DigitalOutPin.h:10:0,
             from /devel/arduino/lightbright/LightBrightMain/LightBrightMain.ino:8:
/devel/arduino/libraries/LightBrightLib/Pin.h:16:7: note:   since type 'Pin' has pure virtual functions
 class Pin
   ^

Full code is at GitHub but here are the relevant parts:
Pin is declared like this right now as pure virtual, but I've tried with and without =0

class Pin
{
  public:
   ...
  protected:
   ...
  // This method is child-specific. It's empty in this base class
  virtual void setPinValue(int value)=0;
};

DigitalOutPin is declared as

class DigitalOutPin : public Pin
{
  public:
    void on();
    void off();
  protected:
    void setPinValue(int value);
};

and defined as

void DigitalOutPin::setPinValue(int value) {
....
}

Disclaimer: I'm primarily a Java developer so C++ OO is very different for me, but as far as I can tell this should work as designed.

Thanks for any advice you can offer.

I have taken your code from above and compiled it for a PC in Visual Studio.
When I create an object of type DigitalOutPin and call setPinValue() it calls the function I expect.  So this means either you have managed to find a bug in the gcc compiler, or there is something else in your code that is coming into play.  Can you try writing a VERY simple minimal test program that defines the Pin class and DigitalOutPin class (with just the setPinValue functions that print a string) and the setup and loop functions.  Just to see if you have found a gcc bug.

Even if this fixes the inheritance problem, you have other issues with you code because C++ is weird.  In Channel.h your Pin variables will need to be pointers, this will allow them to call the functions in the derived classes, not the base class functions.

I think you may get a performance improvement by using "const int& foo" for you parameters.  The const means the function can't change it, this allows the compiler to treat it differently and the "&" means use a reference to the variable rather than make a new copy of it.

Functions that don't change member variables within the code should also be declared constant.  "int FooBar(const int& value) const;"  It makes it clearer to the reader and the compiler probably does some funky stuff to improve performance.  (You might want to investigate "inline" if you are writing one line functions.)

Finally I'd recommend using constructors and destructors.  In release builds variables are not assigned a value.  If these variables are class members this means you don't know what they are to start with.  Also derived classes should initialise the base class, so:

// Class constructor for DigitalOutPin
DigitalOutPin::DigitalOutPin(const int& pinNumber)
  : Pin(pinNumber)  // Initialise the base class
  , m_State(false)  // Initialise all the class members (in order declared in .h file)
{
  // Lots of lovely code
}
// Class destructor for DigitalOutPin (Declared as virtual)
DigitalOutPin::~DigitalOutPin()
{}


Controlling multiple stepper motors non-simultaneously I want to control multiple stepper motors one after another and at different speeds/directions. I am using the ULN2003 driver and the stepper has 5 coils.

My current code for controlling one motor is:

#include <Stepper.h>

const int stepsPerRevolution = 500;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);

void setup() {
  // set the speed at 60 rpm:
  myStepper.setSpeed(50);
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);

  // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution);
}

How would I define each stepper motor differently?

Sorry if I have not asked the question properly. I will try to clarify as time goes on.

Like @chris! suggested, you could include two Stepper variables. So in the line where you were initializing the variable, you could instead have:

Stepper steppermotor1(stepsPerRevolution, 8, 10, 9, 11);

Stepper steppermotor2(stepsPerRevolution, 4, 5, 6, 7);

and then continue on with the code for speed, rotation and so on for each motor.


Using a state machine I'm trying to get a strip of Neopixels to circle through its length, one LED at a time, I want it to do it faster as the value received from the sensor increases

#include <FastLED.h>
#define NUM_LEDS    34
#define DATA_PIN    6
#define SENSOR_PIN  A0

int airPressure,
    barometricToRGB,
    frequency       = 0,
    high            = 0,
    low             = 600,
    interval        = 50;

long previousMillis = 0;

CRGB leds[NUM_LEDS];

void setup() {
  Serial.begin(115200);
  pinMode(SENSOR_PIN,INPUT);
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}

void loop() {
  airPressure = analogRead(SENSOR_PIN);
  autoTune();

  unsigned long currentMillis = millis();
  Serial.print("frequency ");
  Serial.println(frequency);
  Serial.print("Time to beat ");
  Serial.println(frequency*interval);
  Serial.print("Last Called ");
  Serial.println(currentMillis - previousMillis);

  if(currentMillis - previousMillis > (frequency/interval)) {
    previousMillis = currentMillis;

    for (int i=0; i<NUM_LEDS; i++) {
          leds[i].setRGB( barometricToRGB, 68, 255/barometricToRGB);
          FastLED.show();
        }
  }
}

void autoTune() {
  if (airPressure < low) {
    low = airPressure;
  }
  if (airPressure > high) {
    high = airPressure;
  }
  barometricToRGB = map(airPressure, low, high, 1, 255);
  barometricToRGB = constrain(barometricToRGB, 1, 255);
  frequency = map(airPressure, low, high, 1, 100);
  frequency = constrain(frequency, 1, 100);

}

While I had managed to cause the color to change based on the sensor, I can't seem to understand how to control how fast it will go, every how long.

Ok, if I understood what you meant, you want that a single led in the ring is on and the refresh rate is dependent on the pressure, right?

If so, you did not write any "select this led" code, so it can't work.

I fixed a couple of things in your code. Mainly:

added the circularity to the ring (with variable currentlyOnLed)
fixed some types (use the byte unless you need a bigger type)
removed some constrains, which were reduntant
frequency*interval instead of frequency/interval (I guess it was a typo)
I prefer summing the step instead of setting previousMillis to currentMillis, so you will not add error with time passing
moved FastLED.show() outside the loop: I'm not sure about this, but I think that you don't need to call it every loop. I can't test it, anyway.

So, here is the fixed code. Let us know if it works for you

#include <FastLED.h>
#define NUM_LEDS    34
#define DATA_PIN    6
#define SENSOR_PIN  A0

int airPressure;
int high  = 0;
int low   = 600;
byte barometricToRGB;
int frequency = 0;
byte interval = 50;
byte currentlyOnLed;

long previousMillis = 0;

CRGB leds[NUM_LEDS];

void setup() {
    Serial.begin(115200);
    pinMode(SENSOR_PIN,INPUT);
    FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
    currentlyOnLed = 0;
}

void loop() {
    airPressure = analogRead(SENSOR_PIN);
    autoTune();

    unsigned long currentMillis = millis();
    Serial.print("frequency ");
    Serial.println(frequency);
    Serial.print("Time to beat ");
    Serial.println(frequency*interval);
    Serial.print("Last Called ");
    Serial.println(currentMillis - previousMillis);

    if(currentMillis - previousMillis > (frequency*interval)) {
        previousMillis += (frequency*interval);

        //Set next on led
        if (currentlyOnLed >= NUM_LEDS - 1)
            currentlyOnLed = 0;
        else
            currentlyOnLed++;

        for (byte i=0; i<NUM_LEDS; i++) {
            if (i == currentlyOnLed)
                leds[i].setRGB( barometricToRGB, 68, 255/barometricToRGB);
            else
                leds[i] = CRGB::Black;
        }
        FastLED.show();
    }
}

void autoTune() {
    airPressure = constrain(airPressure, low, high);
    barometricToRGB = map(airPressure, low, high, 1, 255);
    frequency = map(airPressure, low, high, 1, 100);
}