body:
I recently got into programing and I'm making an alarm. I cant figure out how to make a buzzer loop. I have two blinking LED's and two fading ones. Now I plan to have sound and it won't work.  It only blinks once and stops. I would also like the two fading LED's to fade at different times. I can't figure that out. Here's the code. 8 is the buzzer and red and blue are the fading LED's.

    int blue = 6;
    int red = 9;
    int brightness = 0;
    int fadeAmount = 500;

    void setup() {
      pinMode(11,OUTPUT);
       pinMode(12,OUTPUT);
        pinMode(red, OUTPUT);
         pinMode(blue, OUTPUT);
          pinMode(8, OUTPUT);
    }

    void loop() {
      digitalWrite(11, HIGH);
      digitalWrite(12, LOW);
      delay(200);
      digitalWrite(11, LOW);
      digitalWrite(12, HIGH);
      delay(200);
      digitalWrite(8, LOW);
      digitalWrite(8, HIGH);
      delay(10);

     analogWrite(red, brightness);
      analogWrite(blue, brightness);
       brightness = brightness + fadeAmount;

    if (brightness <= 0 || brightness >= 255) {
      fadeAmount = -fadeAmount;
    }
     millis();
    }

title: help with a loop

Answers: 4

body:
Have a look [here][1], on how you can use different peripherals in a  non-blocking manner. The following code is from the link:

    // These variables store the flash pattern
    // and the current state of the LED

    int ledPin1 =  12;      // the number of the LED pin
    int ledState1 = LOW;             // ledState used to set the LED
    unsigned long previousMillis1 = 0;        // will store last time LED was updated
    long OnTime1 = 250;           // milliseconds of on-time
    long OffTime1 = 750;          // milliseconds of off-time

    int ledPin2 =  13;      // the number of the LED pin
    int ledState2 = LOW;             // ledState used to set the LED
    unsigned long previousMillis2 = 0;        // will store last time LED was updated
    long OnTime2 = 330;           // milliseconds of on-time
    byte brightness = 0;
    byte brigthnessInterval = 10;

    void setup()
    {
      // set the digital pin as output:
      pinMode(ledPin1, OUTPUT);
      pinMode(ledPin2, OUTPUT);
    }

    void loop()
    {
      // check to see if it's time to change the state of the LED
      unsigned long currentMillis = millis();

      if((ledState1 == HIGH) && (currentMillis - previousMillis1 >= OnTime1))
      {
        ledState1 = LOW;  // Turn it off
        previousMillis1 = currentMillis;  // Remember the time
        digitalWrite(ledPin1, ledState1);  // Update the actual LED
      }
      else if ((ledState1 == LOW) && (currentMillis - previousMillis1 >= OffTime1))
      {
        ledState1 = HIGH;  // turn it on
        previousMillis1 = currentMillis;   // Remember the time
        digitalWrite(ledPin1, ledState1);   // Update the actual LED
      }

      if(currentMillis - previousMillis2 >= OnTime2)
      {
        previousMillis2 = currentMillis;  // Remember the time
        if (brigthness <= 254) brigthness += brigthnessInterval;
        if (brigthness == 255) brigthness = 0;
        analogWrite(ledPin2, brigthness);
      }
    }
Here, two LEDs are controlled with different intervals, I changed LED number 2 to fade in with an interval specified with OnTime2; watch out your fade amount though, because analogWrite has 255 levels, and you immediately increased it to 500. You can add as many intervals as you want in the same manner, and perform tasks in pseudoparallel.

  [1]: https://learn.adafruit.com/multi-tasking-the-arduino-part-1/now-for-two-at-once

body:
try and analyze this alarm sound sketch

    const byte TONE_PIN = 4;
    const int ALARM_BEEP_1 = 4186;
    const int ALARM_BEEP_2 = 4699;

    const int ALARM_TONE_LENGTH = 200;
    const int ALARM_TONE_PAUSE = 800;
    const int ALARM_TONE_REPEAT = 6;

    void setup()
    {
    }

    void loop()
    {
      alarmSound();
    }

    void alarmSound() {
      static unsigned long next = millis();
      static byte count = 0;
      if (millis() > next) {
        next += ALARM_TONE_LENGTH;
        count++;
        if (count == ALARM_TONE_REPEAT) {
          next += ALARM_TONE_PAUSE;
          count = 0;
        }
        tone(TONE_PIN, (count % 2) ? ALARM_BEEP_1 : ALARM_BEEP_2, ALARM_TONE_LENGTH);
      }
    }

body:
 "I recently got into programing"
So start here :
https://en.wikipedia.org/wiki/Divide_and_conquer_algorithm

To apply such principle start by finding suitable "blink (SINGLE) LED" in Arduino IDE examples. There is no real need to reinvent  the wheel / code when you just starting to learn programming as long as you do not just "cut and paste".

You can blink LED attached to pin 13 without using any additional hardware.
Then find an example doing same without using "delay".

Most newcomers have issues with Arduino hidden main function and navigating "loop".

Once you have hang of the loop function you can add multiple "instances" of blinking LED's, and later consolidate these instances into suitable function.

Then use same approach to your buzzer or any other device.
Good luck.

body:
I suggested the basics in my answer to your previous question - "To fade them out of phase, you'll need a second brightness-variable (and possibly a second fade-amount), and an increment/decrement and limit test for each LED."

To put that more concretely, instead of `brightness`, you'll need a `redBrightness` and a `blueBrightness`, and initialize them to different values.

       brightness = brightness + fadeAmount;

    if (brightness <= 0 || brightness >= 255) {
      fadeAmount = -fadeAmount;
    }

For instance, initializing them to '0' and '128', respectively, would drive the LEDs 180 degrees out of phase, or one fading up while the other fades down, assuming you use the same `fadeAmount` variable for both. If you use a `redFadeAmount` and `blueFadeAmount`, you can make them fade at different rates, as well.


body:
Assume I want to write the following without using `DDRD` or `PORTD`:

    #include <avr/io.h>
    #include <util/delay.h>

    int main(void) {
        DDRD = 0xFF;
        PORTD = 0xFF;
    }

I found this link which includes a list of mapped registers to memory addresses:
https://github.com/DarkSector/AVR/blob/master/asm/include/m328Pdef.inc

So I replaced one of the keywords with a pointer:

    #include <avr/io.h>
    #include <util/delay.h>

    int main(void)
    {
        DDRD = 0xFF;
        unsigned char *portd = 0x0b;
        *portd = 0xFF;
    }

But it's not working (my LED isn't turning on with the second code). Why is that?

title: How do I directly access a memory mapped register of AVR with C

Answers: 1

body:
It's worth exploring how `PORTD` is defined in the actual AVR header file.  The relevant file is `iom328p.h`, and it's defined as:

    #define PORTD   _SFR_IO8(0x0B)

`_SFR_IO8` is defined as

    #define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
and

    #define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))

This shows that 0x0b is *not* the address of the `PORTD` register, but its offset from the address `__SFR_OFFSET`, which is 0x20.  Indeed, if you look at the ATMEGA328 datasheet, the register summary shows that `PORTD` is at offset 0x2b.  So that is the address that you would want to access via a pointer.

Note that this also shows the type of the pointer, if we fully expand the original definition of `PORTD` we get:

    #define PORTD   _SFR_IO8(0x0B)
    #define PORTD _MMIO_BYTE((0x0B) + __SFR_OFFSET)
    #define PORTD _MMIO_BYTE((0x0B) + 0x20)
    #define PORTD (*(volatile uint8_t *)(0x2B))

This syntax takes the integer 0x2B, casts it to type `pointer to volatile uint8_t`, and dereferences that pointer so you can assign to or read from the location the pointer references.  The `volatile` qualifier is important because it prevents the compiler from optimizing out accesses to memory.  Without it, the compiler may store the value to a register instead, or not store it at all, which would mean your IO port would remain unchanged or appear to report an incorrect value.

To go back to the title of your question, you have asked how to "directly access a memory mapped register in C", well the answer is you do that exactly the way the header file defines for you:

    (*(volatile uint8_t *)(0x2B) = 0xFF
aka

    PORTD = 0xff

There is no more direct way than this.  The compiler sees a literal address and writes to it.  What you've written is very different (adjusting to use the correct address and type:

    volatile uint8_t * portd = 0x2b;
     *portd = 0xFF;

This allocates a location in memory symbolized by `portd`, which holds the value 0x2B.  When you write `*portd = foo`, the MCU has to access the location where `portd` is stored, take the value found there as an address to find the location you actually want to write to.  This method requires that you allocate a place in memory to hold `portd` and requires an extra memory access to be able to read or write to the port register.  This method is therefore *indirect*.

In reality, if optimization is enabled, the compiler may optimize the pointer away and replace it with the same literal access as in the PORTD case, however this depends on the program structure, and in particular the qualification and scope of the pointer.  Limiting the scope of `portd` as much as possible and/or declaring it as `volatile uint8_t * const portd = 0x2b` (which indicates that the pointer's value is constant even if the value *pointed to* is volatile) will increase the likelihood of the pointer being optimized away.

----------

The reason the AVR headers define the IO port registers this way is because in addition to the standard load/store instructions that can access the entire data memory address space and take three clock cycles to complete, the IO registers are special, and can also be accessed using IN/OUT instructions, which complete in two cycles.  The load/store instructions use the memory address for the IO registers (starting at offset 0x20), whereas the IN/OUT instructions use the IO address, which starts at 0x00, but corresponds to 0x20 in the memory address space.  From the datasheet:
[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/UgOE8.png

So when you access an IO location, the optimizer should recognize that it can issue a more efficient instruction than the standard load/store, and it will replace the load/store to 0x2b with an in/out to 0x0b.


body:
Port is detected and selected but sketch is not uploading to it.
I am getting error:

             avrdude: Version 6.3, compiled on Jan 17 2017 at 12:00:53
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "C:\Users\ACER\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino9/etc/avrdude.conf"

             Using Port                    : COM5
             Using Programmer              : arduino
             Overriding Baud Rate          : 115200
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x2c
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x2c
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x2c
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x2c
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x2c
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x2c
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x2c
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x2c
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x2c
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x2c

    avrdude done.  Thank you.

    Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

title: Arduino sketch not uploading to Arduino Nano

Answers: 1

body:
In IDE in the Tools menu, select in submenu Processor the "Atmega 328P (Old Bootloader)" option.

The upload speed 115200 in your console output indicates the you try to upload for new bootloader. The fail to upload could indicate that your Nano has the old bootloader.


body:
[![enter image description here][1]][1]I recently bought this Arduino Fingerprint Sensor FPM10A from Aliexpress. So, when I connected it with my Arduino Nano and uploaded the 'enroll' example and opened the serial monitor. The fingerprint print sensor got detected but when I enter #1 to enroll the fingerprint no output is given on the serial monitor. I think my Arduino Nano just freezes.But other examples such as 'Empty database, it works with no problems. Is this caused by the less powerful Atmega168 microprocessor? If I get a Arduino Uno or an Arduino Nano with an Atmega328P microprocessor will this problem be solved? And I do not think the fingerprint module is defective as other examples worked like a charm.
Please see the attached photo above.

  [1]: https://i.stack.imgur.com/q4VRt.png

title: My Arduino Fingerprint Sensor FPM10A is not working with an Arduino Nano with Atmega168 processor

Answers: 1

body:
Did you buy the arduino board Nano Atmega168 on Aliexpress? Sometimes the cheapest arduino compatible boards are okay, but sometimes they are stripped of decoupling capacitors or the polyfuse is missing (on a uno board). Sometimes they put a Atmega168 on the board, it is a few cents cheaper.

If you buy the cheapest nano compatible board, look at the photo if the quality is reasonable. The newer arduino boards have a ARM Cortex processors. The Atmega328p is still okay for small projects. I suggest to use the Atmega328p as the minimum.
A Arduino nano Atmega328p clone at Aliexpress costs about 2 dollars, so there is no reason to buy an Atmega168.

When the compiler tells you that "Low memory available, stability problems may occur" for the ram, then you can almost be sure that it will not work.

I try to keep about 300 bytes ram available for local variables, stack and the heap. It depends how much memory the libraries require. I also don't use the String objects for the Arduino uno or nano.
For a beginner, you can try to keep at least 500 bytes ram available.


body:
I am creating a test program with Arduino Nano where I can save network and password. Here is my code to start with:

    void SaveNetwork(String ssid, String pass){
      String com = ssid + "~" + pass;
      const char *array = com.c_str();
      for(int i = 0; i<sizeof(com); i++){
        EEPROM.write(i, array[i]);
      }
      Serial.println("Saved");
      char ar[255] = "";  //test read string.
      for(int i = 0; i<sizeof(com); i++){
        ar[i] = EEPROM.read(i);
      }
      Serial.println(ar);
    }

    SaveNetwork("Testing", "Network123......");

Now I print ar string which is suppose to return ssid, "~" and password.

BUT what I get is "Testin" instead of "Testing~Network123......".

Is there is a limitation for EEPROM size? If so, how can I expand the capacity, should I use a memory chip, or what is the code I should use to resolve this?

title: EEPROM size limitation issue

Answers: 1

body:
The problem is with `sizeof(com)` in your loops. `sizeof()` is for C arrays, not string objects. If you print it, it will report 6, which is not the length of the array. For string objects you should use `com.length()` instead. Then the output becomes

> Saved
>
> Testing~Network123......

P.S. The EEPROM can store 1024 bytes on ATmega328P-based boards (I believe that's what most Arduino Nanos use (clones included).


body:
I am using an Arduino Nano (Clone) which I was programming with the Arduino IDE (Version 1.8.5 on Mac OS X 10.10.5).

Using the Arduino IDE I need to re-plug the Nano before uploading, but after doing this everything works as expected and the sketch is being uploaded successfully.

I then tried to use Platformio core (CLI) and get the well-known `not in sync` error:

    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0xe0
    avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0xe0
    avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xe0
    avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00

As said, this error is well-known, esp. in relation to Arduino clones, and reported several times around the Internet with different solutions.

I just wonder how Arduino IDE is able to upload the code successfully, but Platformio is not since both Arduino IDE and Platformio CLI are just calling `avrdude` to upload the code.

Remark: Uploading the same code to an Arduino Uno works like a charm with both using Arduino IDE and Platformio.

---
_Updates due to further investigation:_

I enabled verbose output for both Arduino IDE and Platformio showing the exact `avrdude` command executed to upload the built hex-file. I adopted the call to `avrdude` from Arduino IDE with the path of the compiled Platformio code. This works as expected:

    avrdude -v -p atmega328p -c arduino -b 57600 -D -P /dev/cu.usbserial-00000000 -U flash:w:.pioenvs/nano/firmware.hex:i

I then had a look at the command used by Platformio which is quite similar but provides an additional `-C` for a config-file:

    avrdude -v -p atmega328p -C /Users/Albert/.platformio/packages/tool-avrdude/avrdude.conf -c arduino -b 57600 -D -P "/dev/cu.usbserial-00000000" -U flash:w:.pioenvs/nano/firmware.hex:i

Unfortunately, I am not able to run this command from the Terminal due to an error:

    avrdude: Version 6.0.1, compiled on Dec 16 2013 at 17:26:24
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2009 Joerg Wunsch

             System wide configuration file is "/Users/Albert/.platformio/packages/tool-avrdude/avrdude.conf"
    avrdude: syntax error at /Users/Albert/.platformio/packages/tool-avrdude/avrdude.conf:1080

title: Unable to upload sketch using Platformio (but Arduino IDE works)

Answers: 1

body: Please use board = nanoatmega328new in your platformio.ini


body:
I have recently bought a few of these chips on boards along with some "adapter boards" which supposedly regulates the 5v to propper 3.3v with the required capacitors.
So power supply shouldn't be a problem although I haven't tried with a separate power supply.
Ok, so I like to build my stuff from scratch to really know everything that's going on so I'm not using a library for this chip but I've read the datasheet in it's entirety and have understood all the features.
At first after going through every option one of the modules was successfully sending out packets as indicated by the TX_DS interrupt but nothing was showing up on the one in receiver mode, and after lots of checking I chose to disable every feature and managed to finally get some action as the receiver interrupted each time the transmitter sent out a packet with no CRC and no ACK.

But now there's an issue, the datasheet clearly states:

> The RX_DR IRQ is asserted by a new packet arrival event.
>     The procedure for handling this interrupt should be:

>    1) read payload through SPI,

>    2) clear RX_DR IRQ,

>    3) read FIFO_STATUS to check if there are more payloads available in RX FIFO,

>    4) if there are more data in RX FIFO, repeat from step 1).

However upon getting the interrupt and reading out 33 bytes with the command, the status register reads 4E (0100 1110) saying that the interrupt was indeed RX_DR but also the pipe number bits are all on meaning an empty RX FIFO. The following 32 bytes read 0.

How can this be? Has anyone experienced something similar?

UPDATE: Tested with separate power supply on RX side, issue still stands.

Pictures: https://1drv.ms/f/s!Ag6xBMoahJ8xkOkWMG89RIAa1m71Kw

Arduino code: (feel free to correct me I'm no expert in this language :p)

Main

    void setup() {
      attachInterrupt(digitalPinToInterrupt(radio.irq), interrupt, FALLING);
      Serial.begin(9600) ;
      Serial.write("\n    ----Boot----\n\nInitializing radio...\n");

      //Starts radio as PRX
      //Sets channel
      //Sets bitrate to 1Mbps
      if (radio.init()) {
        Serial.println("Radio ready.\n\n ----Boot complete----\n\n");
      } else {
        Serial.write("Couldn't initialize radio!\n\n  ----Boot failed----\n");
        return;
      }
      delay(10);
      digitalWrite(9, HIGH);
    }

    void loop() {
    }

    void interrupt() {
      Serial.write("\nINTERRUPT\n");
      digitalWrite(9, LOW);

      radio.readRegister(0x17, 2, true, BIN);
      radio.readRXpayload(true);
      radio.clearIRQ();

      digitalWrite(9, HIGH);
    }

Radio class

    #include "BitUtils.h"

    BitUtils utils;

    uint8_t* tmp = (uint8_t*)malloc(sizeof(uint8_t) * 33);
    uint8_t initialPipe0[5] = {0x28, 0x18, 0xdb, 0xc2, 0x86};
    uint8_t beaconAddress[5] = {0x29, 0x26, 0x13, 0x12, 0x00};

    class Radio {
      public:
        uint8_t nullmsg[1] = {0x00};

        uint8_t rx_config[1] = {0b00100011}; //0x00
        uint8_t tx_config[1] = {0b00100010}; //0x00
        uint8_t aa_config[1] = {0b00000000}; //0x01
        uint8_t ch_config[1] = {0b00110100}; //0x05
        uint8_t rf_config[1] = {0b00000110}; //0x06
        uint8_t features_config[1] = {0b00000000}; //0x1D

        uint8_t clear_irq[1] = {0b01110000}; //0x07

        uint8_t clk = 13;
        uint8_t miso = 12;
        uint8_t mosi = 11;
        uint8_t slaveselect = 10;
        uint8_t chipenable = 9;
        uint8_t irq = 2;

        SPISettings spiConfig = SPISettings(2000000, MSBFIRST, SPI_MODE0);

        boolean init() {
          noInterrupts();

          pinMode(clk, OUTPUT);
          pinMode(miso, INPUT);
          pinMode(mosi, OUTPUT);
          pinMode(slaveselect, OUTPUT);
          pinMode(chipenable, OUTPUT);
          pinMode(irq, INPUT);
          digitalWrite(clk, LOW);
          digitalWrite(slaveselect, HIGH);
          digitalWrite(chipenable, LOW);
          delay(11);

          transfer(nullmsg, 1, tmp);
          if (tmp[0] != 0b00001110) {
            return false;
          }

          writeRegister(0x00, rx_config, 2); Serial.print("0x00: ");
          readRegister(0x00, 2, true, BIN);
          writeRegister(0x01, aa_config, 2); Serial.print("0x01: ");
          readRegister(0x01, 2, true, BIN);
          writeRegister(0x05, ch_config, 2); Serial.print("0x05: ");
          readRegister(0x05, 2, true, BIN);
          writeRegister(0x06, rf_config, 2); Serial.print("0x06: ");
          readRegister(0x06, 2, true, BIN);
          writeRegister(0x1D, features_config, 2); Serial.print("0x1D: ");
          readRegister(0x1D, 2, true, BIN);

          pipeAddress(initialPipe0, 0);
          pipeAddress(beaconAddress, 1);

          Serial.print("Pipe 0 address: ");
          readRegister(0x0A, 6, true, HEX);
          Serial.print("Pipe 1 address: ");
          readRegister(0x0B, 6, true, HEX);

          delay(2);
          interrupts();
          return true;
    }

        //    -- Operations --

        void clearIRQ() {
          writeRegister(0x07, clear_irq, 2);
          Serial.println("Cleared IRQ");
        }

        void sendTXpayload(uint8_t data[], boolean ack) {
          uint8_t message[33] = {0b10100000};
          if (!ack) {
            message[0] = 0b10110000;
          }
          for (int i = 31; i > -1; i--) {
            message[32 - i] = data[i];
          }

          transfer(message, 33, tmp);
          pulseCE(12);
          delay(2);
        }
        void readRXpayload(boolean report) {
          uint8_t message[33] = {0b01100001};

          transfer(message, 33, tmp);
          if (report) {
            utils.prtArr(tmp, 33, HEX);
          }
        }

        void mode(char m) {
          digitalWrite(chipenable, LOW);

          if (m == 't') {
            writeRegister(0x00, tx_config, 2);
            Serial.println("Set tx mode.");
          }
          if (m == 'r') {
            writeRegister(0x00, rx_config, 2);
            Serial.println("Set rx mode.");
          }
        }

        void pipeAddress(uint8_t* address, uint8_t number) {
          uint8_t pipeNumber = 0x0A + number;
          for (int i = 4; i > -1; i--) {tmp[4 - i] = address[i];}

          if (number < 2) {
            writeRegister(pipeNumber, tmp, 6);
          }else{
            writeRegister(pipeNumber, address, 2);
          }
        }

        void sendTo(uint8_t* address) {
          for (int i = 4; i > -1; i--) {
            tmp[4 - i] = address[i];
          }
          writeRegister(0x10, tmp, 6);
          Serial.print("TX Address: ");
          readRegister(0x10, 6, true, HEX);
        }

        void setChannel(uint8_t ch) {
          writeRegister(0b00000101, new uint8_t[1] {ch}, 2);
          Serial.write("Frequency set to: ");
          Serial.print(2400 + tmp[1], DEC);
          Serial.println("MHz");
        }

        //    -- Low operations --

        void readStatus(boolean prt) {
          transfer(nullmsg, 1, tmp);
          if (prt) {
            utils.prtArr(tmp, 2, BIN);
          }
        }
        void readRegister(uint8_t address, uint8_t amount, boolean prt, uint8_t format) {
          uint8_t message[amount] = {address};
          transfer(message, amount, tmp);

          if (prt) {
            utils.prtArr(tmp, amount, format);
          }
        }
        void writeRegister(uint8_t address, uint8_t* data, uint8_t amount) {
          uint8_t message[amount] = {(uint8_t)(0b00100000 | address)};
          for (uint8_t i = 1; i < amount; i++) {
            message[i] = data[i - 1];
          }

          transfer(message, amount, tmp);
        }
        void pulseCE(int duration) {
          digitalWrite(chipenable, HIGH);
          delayMicroseconds(duration);
          digitalWrite(chipenable, LOW);
        }

        //    -- Bidirectional SPI bus --

        void transfer(uint8_t* data, uint8_t amount, uint8_t* output) {
          SPI.beginTransaction(spiConfig);
          digitalWrite(slaveselect, LOW);
          delayMicroseconds(1);

          for (uint8_t i = 0; i < amount; i++) {
            output[i] = SPI.transfer(data[i]);
          }

          delayMicroseconds(1);
          digitalWrite(slaveselect, HIGH);
          SPI.endTransaction();
        }
    };

title: nrf24l01+ contradicting itself?

Answers: 1

body:
My advice would be to strip out all of the unnecessary code to make a minimal complete example (MCVE).  The nRF24L01 is not so complicated when you get to know the data registers, and unfortunately that's where a lot of people get stuck, by trying to use the libraries without reading the datasheet.  However, the posted code suggests that you have done your homework.  This is how I set up nRF24L01 to use IRQ (chronological order from top to bottom):

    // Begin SPI
    // Register 0x0A: set receiver addresses
    // Register 0x11: set payload number of bytes

    // flush RX (spi transfer B11100010) and TX (spi transfer B11100001)

    // attach ISR on IRQ digital input pin.

    // start the main program loop

This is the ISR called:

    void isr(){
    // Read payload data
    digitalWrite(CSN_pin, LOW);
     data_in[0] = SPI.transfer(B01100001); //read payload register
     data_in[1] = SPI.transfer(B00000000);
     data_in[2] = SPI.transfer(B00000000);
     data_in[3] = SPI.transfer(B00000000);
     // etc
    digitalWrite(CSN_pin, HIGH);

    // flush RX
    digitalWrite(CSN_pin, LOW);
     SPI.transfer(B11100010);//flush RX
    digitalWrite(CSN_pin, HIGH);

    // Read status register 0x07
    digitalWrite(CSN_pin, LOW);
     SPI.transfer(0x07);
     reg7 = SPI.transfer(0x00);
    digitalWrite(CSN_pin, HIGH);

    reg7 |= B01000000; // RX_DR set bit 6
    // write back to status register
    digitalWrite(CSN_pin, LOW);
     SPI.transfer(0x20+0x07);
     SPI.transfer(reg7);
    digitalWrite(CSN_pin, HIGH);
    }

*Edit*: bit 6 of the status register is the `RX_DR` flag.  If this is 1 (which is the case in the OP's example), then the data have not been received.  Set bit 6 to clear the interrupt.


body:
So this is pretty much explanatory.  I am new to arduino, and i am learning the best i can.  I need to sketch a code in which will cycle through 5 different brightness settings of an led.  One push will cycle through the five, another push of the button will turn the led off, and another push will restart the cycle.

    const int led =11;
    const int BUTTON = 7;
    boolean lastButton = LOW;
    boolean currentButton = LOW;
    int ledLevel = 0;

    void setup()
    {
      pinMode(led,OUTPUT);
      pinMode(BUTTON,INPUT);
    }
    boolean debounce(boolean last)
    {
      boolean current = digitalRead(BUTTON);
      if (last != current)
    {
      delay(5);
      current = digitalRead(BUTTON);
    }
    return current;
    }

    void loop()
    {
      currentButton = debounce(lastButton);
      if (lastButton == LOW && currentButton == HIGH)
      {
        ledLevel = ledLevel + 51;
      }
      lastButton = currentButton;
      if (ledLevel > 255) ledLevel = 0;
      analogWrite(led, ledLevel);
      analogWrite(led, ledLevel + 51);
      delay(200);
      analogWrite(led, ledLevel + 102);
      delay(200);
      analogWrite(led, ledLevel + 153);
      delay(200);
      analogWrite(led, ledLevel + 204);
      delay(200);
      analogWrite(led, ledLevel + 255);
    }

The code above turns the led on and cycles brightness, like it should it however for some reason it does disable the button.  Take the analogWrites out except for the first one, and the button will cycle the led. any suggestions on what i could do?  Im very new at this.

title: Need to cycle through LED brightness

Answers: 2

body:
All the delay(200) lines keep the sketch from reading button presses.

You need to learn about Blink Without Delay so your sketch can do things other than sit there blindly letting time pass.

body:
Something like this, with variable declarations & setup() left to you.  All time elements are of type unsigned long.

    pwmValue {} = [51, 102, 153, 204, 255];

    void loop(){
      if (digitalRead(startButton) == LOW && pwmCycling == 0){
        // start button pressed, and not already running
        startTime = millis(); // capture the time of the button press
        pwmCycling = 1; // keep track of the running state. 0 for off, 1 for on.
        }
      if (pwmCycling == 1){ // cycling is running
        // this is where the blink without delay is:
        currentTime = millis(); // capture the time now
        elapsedTime = currentTime - startTime; // see how much time went by
        if (elapsedTime >= eventDuration){  // enough?  start next brightness
          currentTime = startTime; // set up for next event time
          brightNumber = brightNumber +1; // keep track of brightness level
          if (brightNumber >= 5){ brightNumber = 0; } // reset after the last level
          analogWrite (ledPin, pwmValue[brightNumber]); // write the LED pin
          }
        }
      if (digitalRead(startButton) == LOW && pwmCycling == 1){
        // start button pressed while LEDs are cycling, stop them
        pwmCycling = 0;
        analogWrite (ledPin, 0);
        brightNumner = 4; //reset the brightness level to the end
        delay (100); // little bit of dumb debounce delay
        }
    }


body:
I have a very basic circuit setup:

- A button connected to pin 2
- An LED connected to pin 9

Desired Functionality:

When the button is pressed, the user can toggle through 4 LED patterns.

The Problem:

Once the first fade pattern begins, the user has to wait until it has finished running before the button can toggle to the next pattern. What  I want is that the button push will move to pattern 2, even if pattern 1 has already started.

Attempted Solutions:

I've tried to insert a while function in a couple of places i.e while buttonstate =lastbuttonstate, but that doesn't seem to work.

Here's the code: (I realize all the fadeloops are the same right now, they will different in the working model)

    //PROBLEM: The fade function has to complete a full loop before allowing toggle to next one

    const int  buttonPin = 2;    // the pin that the pushbutton is attached to
    const int ledPin = 9;       // the pin that the LED is attached to

    // Variables will change:
    int buttonPushCounter = 0;   // counter for the number of button presses
    int buttonState = 0;         // current state of the button
    int lastButtonState = 0;     // previous state of the button

    int brightness = 0;    // how bright the LED is
    int firstFadeAmount = 5;    // how many points to fade the LED by
    int secondFadeAmount = 5;    // how many points to fade the LED by

    void setup() {
      // initialize the button pin as a input:
      pinMode(buttonPin, INPUT);
      // initialize the LED as an output:
      pinMode(ledPin, OUTPUT);
      // initialize serial communication:
      Serial.begin(9600);
    }

    void loop() {
      // read the pushbutton input pin:
      buttonState = digitalRead(buttonPin);

      if (buttonState != lastButtonState) {
        if (buttonState == HIGH) {
          buttonPushCounter++;
        }
        // Delay a little bit to avoid bouncing
        delay(50);
      }
      lastButtonState = buttonState;

      while (buttonPushCounter = lastButtonState) {
        if (buttonPushCounter == 1 && buttonState == HIGH) {
          fadeLoop1();
          delay(50);//JP Edit
        }

        else if (buttonPushCounter == 2 && buttonState == HIGH) {
          fadeLoop2();
          delay(50);
        }

        else if (buttonPushCounter == 3 && buttonState == HIGH) {
          fadeLoop3();
          delay(50);
        }

        else if (buttonPushCounter == 4 && buttonState == HIGH) {
          fadeLoop4();
          delay(50);
        }

      }
      if (buttonPushCounter == 4) {  //Resets back to zero after 4 presses
         buttonPushCounter = 0;
      }

    }

    void fadeLoop1()
    {
      for (int i = 0; i < 100; i++) {  //Set the length of the first fading cycle
        analogWrite(ledPin, brightness);
        brightness = brightness + firstFadeAmount;
        if (brightness <= 0 || brightness >= 255) {
          delay(1000);                  //Sets the hold at the top and bottom of the cycle
          firstFadeAmount = -firstFadeAmount;
        }
        delay(100);
      }
      for (int i = 0; i < 100; i++) {  //Set the length of second fading cycle
        analogWrite(ledPin, brightness);
        brightness = brightness + secondFadeAmount;
        if (brightness <= 0 || brightness >= 255) {
          secondFadeAmount = -secondFadeAmount;
        }
        delay(30);
      }

      digitalWrite(ledPin, LOW);
    }

    void fadeLoop2()
    {
      for (int i = 0; i < 100; i++) {  //Set the length of the first fading cycle
        analogWrite(ledPin, brightness);
        brightness = brightness + firstFadeAmount;
        if (brightness <= 0 || brightness >= 255) {
          delay(1000);                  //Sets the hold at the top and bottom of the cycle
          firstFadeAmount = -firstFadeAmount;
        }
        delay(100);
      }
      for (int i = 0; i < 100; i++) {  //Set the length of second fading cycle
        analogWrite(ledPin, brightness);
        brightness = brightness + secondFadeAmount;
        if (brightness <= 0 || brightness >= 255) {
          secondFadeAmount = -secondFadeAmount;
        }
        delay(30);
      }

      digitalWrite(ledPin, LOW);
    }

    void fadeLoop3()
    {
      for (int i = 0; i < 100; i++) {  //Set the length of the first fading cycle
        analogWrite(ledPin, brightness);
        brightness = brightness + firstFadeAmount;
        if (brightness <= 0 || brightness >= 255) {
          delay(1000);                  //Sets the hold at the top and bottom of the cycle
          firstFadeAmount = -firstFadeAmount;
        }
        delay(100);
      }
      for (int i = 0; i < 100; i++) {  //Set the length of second fading cycle
        analogWrite(ledPin, brightness);
        brightness = brightness + secondFadeAmount;
        if (brightness <= 0 || brightness >= 255) {
          secondFadeAmount = -secondFadeAmount;
        }
        delay(30);
      }

      digitalWrite(ledPin, LOW);
    }

    void fadeLoop4()
    {
      for (int i = 0; i < 100; i++) {  //Set the length of the first fading cycle
        analogWrite(ledPin, brightness);
        brightness = brightness + firstFadeAmount;
        if (brightness <= 0 || brightness >= 255) {
          delay(1000);                  //Sets the hold at the top and bottom of the cycle
          firstFadeAmount = -firstFadeAmount;
        }
        delay(100);
      }
      for (int i = 0; i < 100; i++) {  //Set the length of second fading cycle
        analogWrite(ledPin, brightness);
        brightness = brightness + secondFadeAmount;
        if (brightness <= 0 || brightness >= 255) {
          secondFadeAmount = -secondFadeAmount;
        }
        delay(30);
      }

      digitalWrite(ledPin, LOW);
    }

title: Button to exit a running loop

Answers: 2

body:
Rewrite the fade loops so they return immediately and instead use global state to adjust the LEDs and `millis()-timestamp` to set the timing.

You can use blinkwithoutdelay as inspiration.

body:
Short Answer:
-------------

Switch from using a loop for the entire animation and convert to only tracking what needs to happen at a single point in time.

Long Answer:
------------

The 'while' approach is a good way to test out an individual pattern but for the behavior you describe, you need to limit the use of loops inside of the 'loop()' function.

Essentially, if you use a while to control the entire pattern, as you encountered, you have to wait for the while to exit before the rest of the code can check for a button press.

Here is how I've done the same thing.  I don't have the code handy so I'll have to edit the answer later.  The basic form is something like this:

    int pattern = 0;
    int brightness = 0;
    int maxBrightness = 100;

    setup()
    {
    // your setup code here
    }

    loop()
    {
       if (pattern = 0)
       {
          //increment brightness
          //call code to set the LED to the current brightness
          if (brightness => maxBrightness)
          {
              brightness = 0;
          }
       }
       checkforbuttonpress();
    }

What you notice is I didn't use a for / while loop to do my animation, because the already existing loop() function already does that for me.  All I have to do is track what needs to happen right now, with variables for which pattern and the current brightness for the code to interact with the hardware.  Remember to handle the repetition manually (maxBrightness in this example) and now when the button is pressed, you can change the pattern anywhere because there is no secondary loop to wait for.


body: I'm going to be in the third year of university in a month. I'm satisfied with the software part of my bachelor but I feel like I lack in practice in practical implementation. Would getting an Arduino board and playing around with it worth it and useful for me?

title: Should I buy Arduino as a Computer Engineering Student?

Answers: 3

body:
It depends. If you don't have any knowledge about microcontrollers it might be useful.

However, Arduino hides a lot of concepts in their libraries. If you want to go more indepth check other systems like STM32 or PIC.

You also can do both, start with Arduino to get a rough feeling, continue with another.

More important is WHAT you try, don't stop with LEDs/switches, but check communication protocols like SPI, I2c, UART etc. And learn what timers, interrupts etc. are and how to use them.

body: I don't think there is a should or should not about it, do you want a low cost experimental setup using the C language to toy with ideas and concepts without a massive outlay or proprietary software or NDA's to get chip data that ties you to a single company then why not? You can get Arduino clones very cheaply from the likes of aliexpress etc as well as prototyping kits. While the Arduino IDE is a relatively primitive editor you can use any programmers editor you like to compose your C files and use the Arduino IDE just to do the final compile and linking and upload/burn them to the target device. It can be done so cheaply that even if you decide it does not inspire your imagination you won't have wasted hundreds of $! Just spent a couple of tens of $ to accumulate a significant micro-controller playground! Assuming you already have some kind of personal computer or easy access to one.

body:
As already stated in previous answers, there is no clear-cut answer to
this kind of question. It all depends on what you want to learn.

If that can help, I will share my personal experience. I studied
computer science for only one year at university. Then I stopped to
continue on my physics major. But as I never lost interest in computers,
I continued learning on my own. I started playing with Arduinos just
because it looked like a fun way to learn some microcontroller stuff and
low-level programming. The barrier to entry is extremely low: in no time
you get your LED blinking, and from there you can start exploring plenty
of possibilities. The Arduino IDE and core library make it extremely
easy to make _simple_ programs, but they are quite limited when you want
to get more serious. For many people, this environment, plus extra
downloadable libraries, is all they need to achieve their goals. For me,
it was a stepping stone to learn lower level stuff, like direct hardware
access, use of the avr-libc, and even assembly programming.

Today, what I love most about Arduinos (or, rather, the AVR
microcontrollers at their core), is their _simplicity_ and
_understandability_. Today, when I disassemble a program I have written,
I can understand basically everything: the C runtime initialization
code, the memory allocation, the way the compiler translates my own
code... I find it extremely rewarding to reach such an understanding of
a (kind of) computer system.

The same level of understanding would be (for me) impossible to achieve
on a typical PC. Even though I use Linux, which is Open Source, and I
have access to the full source code, the whole software stack involved
in running even the simplest program is overwhelming. The kernel itself
is like millions of lines of code. Even the assembly language of an x86
(or x86\_64) is something I find way too complex for my taste.

In conclusion, the Arduino has been for me a very rewarding learning
experience. If you want to get your hands dirty with bare metal
programming, I definitely recommend you get an Uno, or something
similar, and start playing with it. Once you get your first program
running (and that takes no time!) start looking under the hood: read the
source of the [Arduino core][] (it's short and very readable), read [the
datasheet of the microcontroller][datasheet], start [poking the
hardware][port access], take a look at how the compiler allocates
memory, how it translates your source code...

[Arduino core]: https://github.com/arduino/ArduinoCore-avr/tree/master/cores/arduino

[datasheet]: http://ww1.microchip.com/downloads/en/devicedoc/atmel-42735-8-bit-avr-microcontroller-atmega328-328p_datasheet.pdf
[port access]: https://www.arduino.cc/en/Reference/PortManipulation


body:
I am new here and I know that this basic question has been answered in the past but what I want to know is this. And I cant figure out how to add this to one of those threads. Sorry in advance if I am posting this wrong.

Arduino Uno

I have a motor driven PWM off output 10 and output 9 is used for the display, can I change the resolution of output 10 only to 16 bit? or will both outputs need to be used as PWM when changing timer 2 to 16 bit? All of the coding samples I see are for changing both outputs.

title: Increase PWM bit resolution on only one timer 2 output

Answers: 1

body:
As long as you don't use PWM (i.e. analogWrite) on pin 9, any changes made to timer1 won't affect pin 9.

<strike>It will change both outputs, as both use the same (single) timer.

But you can use code to convert a 8-bit PWM value to a 16-bit value by simply multiplying the 8-bit value by 256.</strike>


body:
I have the following problem:
Since the BH1750 Sensor only supports two different I2C adresses, but i need to use 6 of those sensors, i wanna use 3 arduinos, 2 nanos, 1 uno and send the data from the nanos to the uno. Problem is that the I2C bus is already in use and while trying to send data, it does not work properly.
Is this even possible? When trying it out, i can't get anything correct[![enter image description here][1]][1]

----

Update:

That's what i tried now:

Results i get are still not correct

[![enter image description here][2]][2]

    #include <Wire.h>
    #include <BH1750.h>

    // This code will feature the use of 6 gy 30 light sensors

    BH1750 active_sensor(0x23); // We will use this adress for stating the active sensor
    BH1750 inactive_sensor(0x5C);

    void setup(){

      Serial.begin(9600);

      // Setting the input pins for controling the addr pins of the modules
        pinMode(8, OUTPUT);
        pinMode(9, OUTPUT);
        pinMode(10, OUTPUT);
        pinMode(11, OUTPUT);
        pinMode(12, OUTPUT);
        pinMode(13, OUTPUT);

        digitalWrite(8, LOW);
        digitalWrite(9, LOW);
        digitalWrite(10, LOW);
        digitalWrite(11, LOW);
        digitalWrite(12, LOW);
        digitalWrite(13, LOW);

      // Initialize the i2c bus
      Wire.begin();

     // Here we will set the mode of the module
      if (active_sensor.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
        Serial.println(F("BH1750 Advanced begin"));
      }
      else {
        Serial.println(F("Error initialising BH1750"));
        Serial.println("Problem on 1");
      }
    }

    void loop() {
      get_values();

    }

    void get_values(){
      int i;
      Serial.println("----");
      for(i = 8; i<=13;i++){
        digitalWrite(i,HIGH);
        delay(50);
        int lux = 0;
        lux = active_sensor.readLightLevel();
        Serial.println(lux);
        delay(50);
        digitalWrite(i,LOW);
        delay(150);
      }
    }

  [2]: https://i.stack.imgur.com/B00VM.png

  [1]: https://i.stack.imgur.com/4GgfN.png

title: Connecting two Arduinos via I2C while I2C Pins A4/A5 are already in use

Answers: 2

body: Use the ADDR pin as a chip select. Pull both pins high normally. When you want to talk to one, pull the ADDR pin low and use the ADDR = 0 address to talk to the selected device. Then you can have all 6 connected to one Arduino.

body:
You can make the nanos use software I2C to isolate those I2C buses from the UNO's I2C bus. Then have the UNO be the master on it's own bus, requesting the data when needed.

Though if you go for software I2C you can make the UNO do all the I2C work, assuming you have enough free pins for that.

Another option is to get a proper I2C multiplexer like the [TCA9548A][1].

  [1]: https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout/overview


body:
I have written a simple Arduino sketch, that shall produce a clock signal.

Here is the code:

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

    }

    void loop() {
      // put your main code here, to run repeatedly:
      digitalWrite(8,HIGH);
      delayMicroseconds(500);
      digitalWrite(8,LOW);
      delayMicroseconds(500);
    }

Namely the pin 8 of Arduino Uno is periodicaly set to HIGH and LOW.

The output that I receive, for three different frequencies, is:

[![enter image description here][1]][1]

[![enter image description here][2]][2]

[![enter image description here][3]][3]

My question is: Why is falling edge not as sharp as rising edge? As can be noted, for high frequencies the signal wouldn't go to LOW after all.

  [1]: https://i.stack.imgur.com/9OII3.png
  [2]: https://i.stack.imgur.com/xN1q9.png
  [3]: https://i.stack.imgur.com/m287Y.png

title: The reason for signal not going back to LOW

Answers: 1

body:
The pin is not configured as OUTPUT.

By default, all of the GPIO pins on pretty much any microcontroller are configured as inputs following reset. This prevents the chip from "fighting" an external device that might be driving any of those pins before the firmware has had a chance to configure the GPIO correctly.

On the MCU used on the Arduino, the output latch controls the state of an internal pullup resistor when the pin is configured as an input. Your code was simply enabling and disabling this resistor. When you set the pin low, it makes the pin open-circuit, and you see a slow decay of voltage through your oscilloscope probe.


body:
I want to display the DHT22 temperature and humidity sensor in a 3 digit 7 segments display. It's always showing the  sensor value and after 2 or 3 sec the display turns off, and then the display turns on, and so on.
I need help to understand where is the mistake on the code to make the display always turned ON.

    #include <SevSeg.h>
    #include <EEPROM.h>
    #include "DHT.h"
    #define COMMON_ANODE 0
    #define DHTPIN A0     // what pin we're connected to

    #define DHTTYPE DHT22   // DHT 22  (AM2302)
    DHT dht(DHTPIN, DHTTYPE);
    int chk;
    float hum;  //Stores humidity value
    float temp; //Stores temperature value
    SevSeg sevseg;

    void setup(){

    byte numDigits = 3;
    byte digitPins[] = {1,2,3};
    byte segmentPins[] = {4,5,6,7,8,9,10,11};
    sevseg.begin(COMMON_ANODE, numDigits, digitPins, segmentPins);
     dht.begin();
    }

    void loop(){
       temp= dht.readTemperature();

       sevseg.setNumber(temp,1);
       sevseg.refreshDisplay();
    }

title: 7 segment display blinking

Answers: 2

body:
You have a multiplexed display. Multiplexed displays have to be constantly updated, or they display the last displayed digit (if there was one) for an extended period.

The reading from the DHT will take time. That time will interrupt the display updates causing it to stop for a while as it reads.

Why does it do it every few seconds? All I can suggest is that the DHT library you are using limits the actual readings to every few seconds - and between those times it just returns the previously stored value.

To get around it you should consider doing your display updates from within a timer interrupt (assuming your DHT library doesn't disable interrupts).

body:
A good way to avoid display flicker is to only update the display when needed.  The display update is what causes it to flicker.  If you change your main loop as below, the display will only update when needed (when the current reading is different than the last reading).  It's probably also a good idea to only read the temperature every 2 seconds or so which can be controlled with a simple delay().

    float temp, last_temp = 0;

    void loop() {
        temp = dht.readTemperature();
        if (temp != last_temp)
        {
            sevseg.setNumber(temp,1);
            sevseg.refreshDisplay();
        }
        last_temp = temp;
        delay(2000);
    }


body:
I am sure this is a very simple answer, but I don't know to look it up on google

In the example "SerialEvent" in the arduino IDE (v1.8.7), there is the following function

        void serialEvent() {
            while (Serial.available()) {
               // get the new byte:
               char inChar = (char)Serial.read();
               // add it to the inputString:
               inputString += inChar;
               // if the incoming character is a newline, set a flag so the main loop can
               // do something about it:
               if (inChar == '\n') {
                   stringComplete = true;
               }
            }
         }

On the third line "**char inChar = (char)Serial.read();**" the (char) is given in brackets before the serial read.
Why is this? and more specifically how is called ?

title: "char inChar = (char)Serial.read();" why is the "char" in brackets? and what is it called

Answers: 1

body:
It is called type casting and will convert one type to another. The return type of `Serial.read()` is `int`, because it will return `-1`, when you try to read without any bytes being available. The casting with `(char)` will drop the high byte of the (2-byte long) integer, leaving only the lower byte. This byte will contain the actual read data, in which you are interested here.

Casting is a complex thing, because there can be different ways to convert different types (for example maintaining the bit-content vs. maintaining the decimal value). The casting, that you are seeing here, should only be done, if you really know, what you are doing. The bits will not be changed to maintain the correct value, but the bit-content will be preserved, unless the new type is smaller than the former. In this case the rest is lost. Also, if you try to cast a `float` value to an `int` value with this, you will get a totally different decimal value out of it, because the numbers are encoded in the bits in a totally different way. Here it is known to be OK, especially, if you are checking for available bytes before reading with `Serial.available()`, because the library puts the ASCII data in the lower byte.

For further explanations you should consult C/C++ guides.


body:
im building my second arduino project. Im very new to this all so I could certainly use some help fixing everything.

Im trying to make a controller for a pc port of an arcade game. It uses two rotary encoders, something I never heard about before going into this project

 I had found some code on [github][1] that works perfectly in my case, but the code has the rotary encoders move the mouse. something that dosent work for the games controls unfortunately (i tried)

so i attempted to change them and now they do spit out text like i need them but when i rotate them instead of getting the needed out put of

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
i get something more along the lines of

    babababababababababababababababbabb
like if im turning the knob both ways at the same time when im just turning it one direction.

heres the code im working on

    /*
    * By Daniel Tam (daniel@danieltam.net)
    ============ NOTES ============
    This will create a SDVX Controller using an Arduino Leonardo.
    You will hook up one wire of the button to the Arduino pin and the other to Arduino's ground. When pushed, the button should go to ground.
    You will need to download the encoder library and use it in your project for this to work (ww.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino)
    ===============================
    */

    // buttons
    #include <Mouse.h>
    #include <Keyboard.h>
    #define BT_A 2
    #define BT_B 3
    #define BT_C 4
    #define BT_D 5
    #define FX_L 6
    #define FX_R 7
    #define BT_ST 8

    // encoders
    #include <Encoder.h>
    Encoder enc1(15, 14);
    Encoder enc2(16, 10);
    float knob1 = 0;
    float knob2 = 0;
    float old_knob1 = 0;
    float old_knob2 = 0;

    void setup()
    {
      // set pins to read, and output high
      // when the pins read low, we know that the buttons have went to ground (aka, pushed down)
      pinMode(BT_A, INPUT);
      pinMode(BT_B, INPUT);
      pinMode(BT_C, INPUT);
      pinMode(BT_D, INPUT);
      pinMode(FX_L, INPUT);
      pinMode(FX_R, INPUT);
      pinMode(BT_ST, INPUT);

      digitalWrite(BT_A, HIGH);
      digitalWrite(BT_B, HIGH);
      digitalWrite(BT_C, HIGH);
      digitalWrite(BT_D, HIGH);
      digitalWrite(FX_L, HIGH);
      digitalWrite(FX_R, HIGH);
      digitalWrite(BT_ST, HIGH);

      Mouse.begin();
      Keyboard.begin();
    }

    void loop()
    {
      // read encoders
      knob1 =  (float)(enc1.read());
      knob2 = (float)enc2.read();

      if(knob1 != old_knob1)
      {
        // if there's a difference in encoder movement from last pass, move the mouse
        if(knob1 < old_knob1)
        {
         // Mouse.move(0, -5);
          Keyboard.press('a');
          delay(100);
          Keyboard.release('a');
        }
        else
        {
        //  Mouse.move(0, 5);
          Keyboard.press('b');
          delay(100);
          Keyboard.release('b');
        }

      // we count the difference in the encoders, but we must not go over arduino's int limit
        if(knob1 < -255)
        {
          enc1.write(0);
          old_knob1 = 0;
        }
        else if (knob1 > 255)
        {
          enc1.write(0);
          old_knob1 = 0;
        }
        else
        {
          old_knob1 = knob1;
        }
      }

      if(knob2 != old_knob2)
      {
        if(knob2 > old_knob2)
        {
         // Mouse.move(-5, 0);
          Keyboard.press('c');
        }
        else
        {
         // Mouse.move(5, 0);
          Keyboard.press('d');
        }

        if(knob2 < -255)
        {
          enc2.write(0);
          old_knob2 = 0;
        }
        else if(knob2 > 255)
        {
          enc2.write(0);
          old_knob2 = 0;
        }
        else
        {
          old_knob2 = knob2;
        }
      }

      // read the buttons for low, if it's low, output a keyboard press
      if(digitalRead(BT_A) == LOW)
      {
        Keyboard.press('f');
      }
      else
      {
        Keyboard.release('f');
      }

      if(digitalRead(BT_B) == LOW)
      {
        Keyboard.press('b');
      }
      else
      {
        Keyboard.release('b');
      }

      if(digitalRead(BT_C) == LOW)
      {
        Keyboard.press('c');
      }
      else
      {
        Keyboard.release('c');
      }

      if(digitalRead(BT_D) == LOW)
      {
        Keyboard.press('d');
      }
      else
      {
        Keyboard.release('d');
      }

      if(digitalRead(FX_L) == LOW)
      {
        Keyboard.press('z');
      }
      else
      {
        Keyboard.release('z');
      }

      if(digitalRead(FX_R) == LOW)
      {
        Keyboard.press('x');
      }
      else
      {
        Keyboard.release('x');
      }

      if(digitalRead(BT_ST) == LOW)
      {
        Keyboard.press('n');
      }
      else
      {
        Keyboard.release('n');
      }
    }

  [1]: https://github.com/omgdanieltam/sdvx_leonardo

title: rotary encoder spamming output

Answers: 1

body:
Your aren't using the recommended pins to attach the encoders. Because of this the library isn't using interrupts, but depends on you calling `encX.read()` often enough, to not miss any changes. This, combined with the 100ms delay in your code, will almost guarantee that you will miss some changes, making the library think you are rotating the other way around.

Change the pins to 0, 1, 2, 3 (or at least one of those for each encoder).

Otherwise lower the delay to for example 1ms. I couldn't find whether this delay is even necessary, or how long it needs to be, so you'd have to experiment a bit, and see what works.

Lastly; why are you using `float` to store the position? Try using `long` instead, as that's the type enc.read() returns.


body:
I'm working on BLE project with espressif library. And It returns me founded BLE device.

    std::string getManufacturerData();
 std::string getName();
 int         getRSSI();
 BLEScan*    getScan();

When I want to print device name to serial port

    BLEAdvertisedDevice founded_dev;
    founded_dev=foundDevices.getDevice(0);
    Serial.println("Name -> " + founded_dev.getName());

It gives me error like this

    no matching function for call to 'HardwareSerial::println(std::__cxx11::basic_string<char>)'

So how can i convert to std:string to String in Arduino?

title: Arduino Convert std:string to String

Answers: 1

body:
Don't. Instead just access the underlying C string:

    Serial.print(F("Name -> "));
    Serial.println(founded_dev.getName().c_str());


body:
I'm trying to connect with a 4 channel temperature controller using [Arduino Modbus Library][1].

This is a part of my temperature controller datasheet. It has register for read PV of each channel.

[![Registers][2]][2]

I have studied example code of the library and now i'm trying to read PV of each channel.

So, I have modified the example code as below,

    #include <ModbusMaster.h>

        // instantiate ModbusMaster object
        ModbusMaster node;

        void setup()
        {
          // use Serial (port 0); initialize Modbus communication baud rate
          Serial.begin(19200);

          // communicate with Modbus slave ID 2 over Serial (port 0)
          node.begin(2, Serial);
        }

        void loop()
        {
          static uint32_t i;
          uint8_t j, result;
          uint16_t data[6];

          i++;

          // set word 0 of TX buffer to least-significant word of counter (bits 15..0)
          node.setTransmitBuffer(0, lowWord(i));

          // set word 1 of TX buffer to most-significant word of counter (bits 31..16)
          node.setTransmitBuffer(1, highWord(i));

          // slave: read (4) 16-bit registers starting at register 2 to RX buffer
          result = node.readHoldingRegisters(1, 4);

          // do something with data if read is successful
          if (result == node.ku8MBSuccess)
          {
            for (j = 0; j < 4; j++)
            {
              data[j] = node.getResponseBuffer(j);
            }
          }

        }

My questions are,
Explain below lines in the code

              // set word 0 of TX buffer to least-significant word of counter (bits 15..0)
          node.setTransmitBuffer(0, lowWord(i));

          // set word 1 of TX buffer to most-significant word of counter (bits 31..16)
          node.setTransmitBuffer(1, highWord(i));

I didn't  pass any request to slave, So, can I get the 4 PV value like this?
If not, please explain how can I do it.

  [1]: https://github.com/4-20ma/ModbusMaster
  [2]: https://i.stack.imgur.com/bKai8.png

title: Using Modbus-RTU with Arduino and temperature controller

Answers: 1

body:
The setTransmitBuffer calls are for writeMultipleRegisters, which you removed from the example.

The first parameter of the readHoldingRegisters is the address of the register. The second parameter is the count of registers to read.

Your sketch doesn't show the retrieved data. You have no indication of success or fail.


body:
I am attempting to use 3 x TLC5917 chips to drive a row of LEDs in PWM. The LEDs share a common anode being powered through a transistor, with each LEDs cathode going to pins on the TLC5917 Chips.

There are obviously other chips specifically designed for PWM but my questions relate to the Arduino SPI Implementation.

The chips I am using are rated for 30MHz Max Speed.
The Arduino (Uno) I am using runs at 16MHz. SPI can only run at half speed which means the SPI Transfer Max Speed for this hardware is 8MHz.

With this in mind, before overhead it should take `1/8Million` seconds per clock cycle, equivalent to `1/8th` of a Microsecond.
This means that SPI should take 24 clock cycles to send out 24 bits. Clocking out all 3 bytes (24 bits) should take about 3 Microseconds before overhead.
Then a few more microseconds to flip the latch pin.

Instead I see it taking about 12 Microseconds to send the 24 bits and another 12 Microseconds to latch the pin low and high, 4 times what I expected. Obviously there is some overhead but 400% seems excessive.

I have looked at the Arduino SPI Library to see if there is any obvious overhead but I cant see anything that would quadruple the theoretical transfer time.

This is the sketch I used to time the data transfers

    #include <SPI.h>

    void SSHigh(){
      PORTB = PORTB | 10000000;
    }

    void SSLow(){
      PORTB = PORTB ^ 10000000;
    }

    void setup() {
       SPI.begin();
       Serial.begin(9600);
       pinMode(2, OUTPUT);
       digitalWrite(2, LOW);
    }

    void writeChips(byte red, byte green, byte blue){
        SPI.transfer(blue);
        SPI.transfer(green);
        SPI.transfer(red);

    }

    long start;
    long end;
    long delta;

    void loop() {

      start = micros();
      writeChips(B11000110,B01110010,B00011110);
      end = micros();
      delta = end - start;
      Serial.println(delta);

    }

title: TLC5917 SPI Speeds

Answers: 0


body: I have some code that works fine on Windows but is giving me errors on Ubuntu. I noticed that while Windows is running the code using avr-gcc, Ubuntu is trying to make it run using avr-g++. Any functions not defined within void setup() comes up as "was not declared in this scope". Is there a way to force it to use avr-gcc ?

title: Arduino on Windows vs Ubuntu

Answers: 1

body:
In my case, i would tell you compile/upload your sketch Arduino on Ubuntu 17.10 like my owned.

I have

 - Wemos D1 MINI Board based ESP8266 chip.
 - Define ttyUSB0 port like my Owned.

Before upload your sketch, you need Arduino Package for Ubuntu in [Arduino Official Pages][1] or if you have Arduino Package on your Aptitude Source list / PPA Repository of Arduino with following `sudo apt-get install -y arduino`. that's same to me.

After your Arduino Package installed, try to following commnand :

    cd /path/installation/package/ //for change directory to Arduino Package

    ARDUINO-DIR(pwd) //for make environment of Arduino directory

    cd $HOME/Arduino/sketch/ //for change directory to your Arduino sketch

    ls -l //for list all items in your folder

    $ARDUINO-DIR/arduino --verify sketch.ino --board (board) --port (port) --verbose //for compile your sketch

    $ARDUINO-DIR/arduino --upload sketch.ino --board (board) --port (port) --verbose //for upload your sketch

**NOTE:**

e.g --board esp8266:esp8266:d1_mini //for WemosD1Mini board or
e.g --board arduino:avr:uno //for ArduinoUNO board.
e.g --port /dev/ttyUSB0 or /dev/ttyACM0 //if your define ttyUSB0 or ttyACM0 port you have.

**See Below** to my verbose log appears a avr-gcc and a avr-g++ automatically called in arduino-builder binary to compile all my library defined.

[![enter image description here][2]][2]

Hope you can get it.

  [1]: https://playground.arduino.cc/linux/ubuntu
  [2]: https://i.stack.imgur.com/nhBPA.gif


body:
Using a 4x3 membrane keypad and I want to make the '*' key a backspace if the wrong number is entered.

I am a newbie and having a hard time trying to figure out how to code that, any help would be great.
<!-- language-all: lang-cpp -->

    int getNumber()
    {
      int num = 0;
      char key = myKeypad.getKey();
      while (digitCount <=  1)
      {
        switch (key)

        {
        case NO_KEY:
          break;
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
          num = num * 10 + (key -  48);
          digitCount++;
          break;
        case '*':
          break;
        case '#':
          break;
        }
      key = myKeypad.getKey();
      }

      digitCount = 0;
      return num;
    }

title: Making '*' key on keypad a backspace key

Answers: 0


body:
None of my channels initialize. I suspect a driver issue, but I have tried 2 different libraries.

I have this device:

[Krida 4 channel][1]

connected exactly like:

    GND - > GND
    VCC -> 5V
    SYNC -> DIGITAL.3
    CH1 -> DIGITAL.7

Libraries attempted:

[https://code.google.com/archive/p/arduino-timerone/downloads][2]

and the stock Arduino <TimerOne.h> from libraries manager

I tried all the different code samples but here is the most recent.
Code sample:

    #include <TimerOne.h>

    unsigned char channel_1 = 7;    // Output to Opto Triac pin, channel 1
    unsigned char channel_2 = 6;    // Output to Opto Triac pin, channel 2
    unsigned char channel_3 = 5;    // Output to Opto Triac pin, channel 3
    unsigned char channel_4 = 4;    // Output to Opto Triac pin, channel 4
    unsigned char CH1, CH2, CH3, CH4;
    unsigned char i=0;
    unsigned char delay_time=25;     // delay ms or flashing SPEED
    unsigned char clock_tick;        // variable for Timer1
    unsigned char CHANNEL_SELECT;    // variable for channel select

    unsigned char CH[]={CH1,CH2,CH3,CH4};

    unsigned char dim_level[]={5,8,10,12,15,18,20,25,30,35,45,50,55,60,65,70,75,80,82,85,88,92,95};   // don't use this massive for 60Hz
                                                                                // create new massive for 60Hz
    void setup() {

      pinMode(channel_1, OUTPUT);// Set AC Load pin as output
      pinMode(channel_2, OUTPUT);// Set AC Load pin as output
      pinMode(channel_3, OUTPUT);// Set AC Load pin as output
      pinMode(channel_4, OUTPUT);// Set AC Load pin as output
      attachInterrupt(1, zero_crosss_int, RISING);
      Timer1.initialize(100); // set a timer of length 100 microseconds for 50Hz or 83 microseconds for 60Hz;
      Timer1.attachInterrupt( timerIsr ); // attach the service routine here

    }

    void timerIsr()
    {
        clock_tick++;

          if (CH[0]==clock_tick)
        {
          digitalWrite(channel_1, HIGH);   // triac firing
          delayMicroseconds(10);           // triac On propogation delay (for 60Hz use 8.33)
          digitalWrite(channel_1, LOW);    // triac Off
        }

          if (CH[1]==clock_tick)
        {
          digitalWrite(channel_2, HIGH);   // triac firing
          delayMicroseconds(10);           // triac On propogation delay (for 60Hz use 8.33)
          digitalWrite(channel_2, LOW);    // triac Off
        }

          if (CH[2]==clock_tick)
        {
          digitalWrite(channel_3, HIGH);   // triac firing
          delayMicroseconds(10);           // triac On propogation delay (for 60Hz use 8.33)
          digitalWrite(channel_3, LOW);    // triac Off
        }

          if (CH[3]==clock_tick)
        {
          digitalWrite(channel_4, HIGH);   // triac firing
          delayMicroseconds(10);           // triac On propogation delay (for 60Hz use 8.33)
          digitalWrite(channel_4, LOW);    // triac Off
        }
    }

    void zero_crosss_int()  // function to be fired at the zero crossing to dim the light
    {
      // Every zerocrossing interrupt: For 50Hz (1/2 Cycle) => 10ms  ; For 60Hz (1/2 Cycle) => 8.33ms
      // 10ms=10000us , 8.33ms=8330us

        clock_tick=0;
    }

    void loop() {

    for (CHANNEL_SELECT=0;CHANNEL_SELECT<4;CHANNEL_SELECT++)  // fade up
     {
      for (i=22;i>1;i--)
      {
        CH[CHANNEL_SELECT]=dim_level[i];
        delay(delay_time);
      }
     }

    delay(2000);

    for (CHANNEL_SELECT=0;CHANNEL_SELECT<4;CHANNEL_SELECT++)  // fade down
     {
      for (i=0;i<22;i++)
      {
        CH[CHANNEL_SELECT]=dim_level[i];
        delay(delay_time);
      }
     }
    delay(1000);

    }

The code uploads error free to one of the many Arduino Nanos (I tried fresh hardware) that I have.

I cannot establish continuity with my load input channel to any of the load output channels. It is though D7 never never does its job and flip the channel open. Nor can I get any continuity on any of the other channels.

The code is supposed to cycling through all of them but no current ever hits any of the 'load' on any of my channels (Chan 1-4).

Deeper inspection of the Arduino with a voltage meter shows that I am getting reverse polarity on my d7 pin. actually, d7 - d4 all have what appear to be incorrect cycles (reverse polarity) on them. These are all the pins that are supposed to be turning on channels. This does not look correct to me at all.

I suspect driver but I cannot find any other libraries to try that look sane.

How do I initialize my d7 Arduino pin correctly to bring my Krida 4 chan triac Load channel live?

or, did I miss something exceptionally ignorant? I am not experienced with this particular module.

photos:

[![image 1][3]][3]

[![image 2][4]][4]

[![image 3][5]][5]

[![Same as image 2, but with channel 1 to d7 connected][6]][6]

  [1]: http://www.inmojo.com/store/krida-electronics/item/4-channel-ac-light-dimmer-arduino--v2/
  [2]: https://code.google.com/archive/p/arduino-timerone/downloads
  [3]: https://i.stack.imgur.com/awZPf.jpg
  [4]: https://i.stack.imgur.com/EJaY8.jpg
  [5]: https://i.stack.imgur.com/eYtPE.jpg
  [6]: https://i.stack.imgur.com/IKNKZ.jpg

title: Krida 4 ch ac dimmer triac fails to initialize from an Arduino

Answers: 1

body:
First of all you should test if the SYNC interrupt is working, like turning on one LED or something you can debug. You switch on the mains AC and then you should detect this zero cross interrupt. If not, then maybe you configured an interrupt event on wrong pin.

Further, making do-while loops in interrupt routine is a no go. Your timeISR turns on one triac, then loops for 10us and turns the triac off. Well not so good implementation. You could skip delay, and turn off after another timeISR by making this ISR at 10us instead.

    void timerIsr()  //10us
    {
        clock_tick++;
        digitalWrite(channel_1, LOW);    // triac Off
        digitalWrite(channel_2, LOW);    // triac Off
        .....
        if (CH[0]==clock_tick)
          {
            digitalWrite(channel_1, HIGH);   // triac firing
          }


body:
I am working on a project on Arduino OLED MAX6675 thermocouple and SSR for my oven.
My problem is when my SSR goes in LOW or HIGH state it  turn ON and OFF several times before going to permanent HIGH or LOW state.
This make my load(Heater) on and off many times. Since the temperature crosses the set-point to change the output state, the process temperature will be cycling rapidly, going from below set-point to above, and back below.
This frequent ON OFF will damage my SSR and heater.
My Question.
Is there any hardware or software solution. To reduce the frequency of ON OFF .
I can’t increase  the delay() time because it make my button input slow.
My codes are below.

<!-- language: lang-c++ -->

    #include <Wire.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_GFX.h>
    #include "max6675.h"

    //oled
    //oled i2c addresss
    #define OLED_ADDR 0x3C
    Adafruit_SSD1306 display(-1);
    // 128 x 64 pixel display
    #define SSD1306_LCDHEIGHT 64

    //MAX6675
    //Pin initialization
    int so = 2;
    int cs = 3;
    int sck = 4;
    MAX6675 thermocouple(sck, cs, so);
    float current_temp;
    int set_temp;
    int const h_temp = 2;

    //Button
    int button_up = 7;
    int button_down = 8;
    int button_upv;
    int button_downv;

    //SSR
    int ssr_u = 10;
    int ssr_d = 12;

    void setup() {
        Wire.begin();
        delay(1000);

        // initialize and clear display
        display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
        display.clearDisplay();
        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(8, 20);
        display.println("Welcome..");
        display.display();
        display.clearDisplay();
        delay(1000);

        //Button
        pinMode(button_up, INPUT);
        pinMode(button_down, INPUT);
        set_temp = 20;
        pinMode(ssr_u, OUTPUT);
        pinMode(ssr_d, OUTPUT);
    }

    void loop() {
        current_temp = thermocouple.readCelsius();
        delay(100);
        button_upv = digitalRead(button_up);
        button_downv = digitalRead(button_down);

        //button
        if (button_upv == HIGH && set_temp < 180) {
            set_temp = set_temp + 5;
        }
        if (button_downv == HIGH && set_temp > 20) {
            set_temp = set_temp - 5;
        }

        display.clearDisplay();
        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(5, 10);
        display.println(current_temp);
        display.setCursor(5, 30);
        display.println(set_temp);

        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(30, 40);
        if (button_upv == HIGH) {
            display.println("Up");
        }
        if (button_downv == HIGH) {
            display.println("Down");
        }
        display.display();

        //SSR
        if (current_temp < set_temp - h_temp) {
            digitalWrite(ssr_u, HIGH);
            digitalWrite(ssr_d, HIGH);
            delay(500);
        }
        if else(current_temp > set_temp + h_temp) {
            digitalWrite(ssr_u, LOW);
            digitalWrite(ssr_d, LOW);
            delay(500);
        }
    }

Thanks in advance for help

title: Frequent ON OFF in SSR

Answers: 1

body:
You need to implement hysteresis. Set two temperature points around set_temp. One a little higher to be a limit for turning the heater off and a one a little lower then set_temp to turn the heater on.

You only need to change your if else condition a little

    if (current_temp < set_temp - HYST_VALUE) {
      digitalWrite(ssr_u, HIGH);
    } else if (current_temp > set_temp + HYST_VALUE) {
      digitalWrite(ssr_u, LOW);
    }

you could start with

    int const HYST_VALUE = 1;


body:
The ESP 12 board has 22 pins [![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/Gytj6.png

Are all of them usable?

I understand that there is an external flash memory that is accessed through SPI, but I'm not sure what the impact on the pins is.

And if it is so, then why are the pins available?

Is there a sort of a decoder board that receive as an input, let's say 3 SPIOs and outputs 8 GPIOs?

Is there a way to obtain more GPIO pins?

title: ESP 12 unusable pins

Answers: 1

body:
The flash memory is connected to io 6 to io 11 if it is connected in QIO mode. DIO mode lets two of the pins free. According to [Arduino core reference][1] the two pins are 9 and 11. The flash pins are labeled SD and most of them are the first SPI interface of the esp8266. You can't use this SPI pins as digital pins, but supposedly you can [connect another SPI device][2].

Some of the esp8266 'free' pins have some restrictions. Boot configuration pins io 0, io 2 and io 15 need to have some state at boot. io2 not LOW, io 15 LOW and with io 0 flashing mode is activated. The A0 is ADC only pin. And you can't count power, EN, Reset and ground as 'pins'.

You can use a multiplexer or an I2C expansion board to get more pins.

  [1]: https://arduino-esp8266.readthedocs.io/en/latest/reference.html#
  [2]: https://arduino-esp8266.readthedocs.io/en/latest/libraries.html#spi


body:
Hello i've try to decode JPG image from FS so, i create and upload spiffs image (using /data directory and Arduino Ide Plugin )

On every jpg i've same error: "pjpeg_decode_init() failed with status 19"

here is my same code:

    #include <TFT_eSPI.h> // Hardware-specific library
    #include <SPI.h>
    #include "GfxUi.h"

    TFT_eSPI tft = TFT_eSPI(); // Invoke custom library

    #define DEBUG
    #define LOAD_SPIFFS

    GfxUi ui = GfxUi(&tft);

    void writeFile(fs::FS &fs, const char * path, const char * message);
    void readFile(fs::FS &fs, const char * path);
    void listDir(fs::FS &fs, const char * dirname, uint8_t levels);

    void setup(void)
    {
      Serial.begin(115200);
      Serial.print("Start");
      SPIFFS.begin(true);
      tft.begin();
      tft.setRotation(3);
      tft.fillScreen(TFT_BLACK);

      listDir(SPIFFS, "/", 0);
      fs::File jpeg = SPIFFS.open("/star.jpg", "r");
      //readFile(SPIFFS, "/star.jpg");
      boolean decoded = JpegDec.decodeFsFile(jpeg);
      Serial.println("===============");
      Serial.println("JPEG image info");
      Serial.println("===============");
      Serial.print  ("Width      :"); Serial.println(JpegDec.width);
      Serial.print  ("Height     :"); Serial.println(JpegDec.height);
      Serial.print  ("Components :"); Serial.println(JpegDec.comps);
      Serial.print  ("MCU / row  :"); Serial.println(JpegDec.MCUSPerRow);
      Serial.print  ("MCU / col  :"); Serial.println(JpegDec.MCUSPerCol);
      Serial.print  ("Scan type  :"); Serial.println(JpegDec.scanType);
      Serial.print  ("MCU width  :"); Serial.println(JpegDec.MCUWidth);
      Serial.print  ("MCU height :"); Serial.println(JpegDec.MCUHeight);
      Serial.println("===============");
      Serial.println("");
    }

    void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
        Serial.printf("Listing directory: %s\r\n", dirname);

        File root = fs.open(dirname);
        if(!root){
            Serial.println("- failed to open directory");
            return;
        }
        if(!root.isDirectory()){
            Serial.println(" - not a directory");
            return;
        }

        File file = root.openNextFile();
        while(file){
            if(file.isDirectory()){
                Serial.print("  DIR : ");
                Serial.println(file.name());
                if(levels){
                    listDir(fs, file.name(), levels -1);
                }
            } else {
                Serial.print("  FILE: ");
                Serial.print(file.name());
                Serial.print("\tSIZE: ");
                Serial.println(file.size());
            }
            file = root.openNextFile();
        }
    }

    void readFile(fs::FS &fs, const char * path){
        Serial.printf("Reading file: %s\r\n", path);

        File file = fs.open(path);
        if(!file || file.isDirectory()){
            Serial.println("- failed to open file for reading");
            return;
        }

        Serial.println("- read from file:");
        while(file.available()){
            Serial.write(file.read());
        }
    }

    void writeFile(fs::FS &fs, const char * path, const char * message){
        Serial.printf("Writing file: %s\r\n", path);

        File file = fs.open(path, FILE_WRITE);
        if(!file){
            Serial.println("- failed to open file for writing");
            return;
        }
        if(file.print(message)){
            Serial.println("- file written");
        } else {
            Serial.println("- frite failed");
        }
    }

    void loop() {

    }

Output from serial:

    Listing directory: /
      FILE: /logo.jpg       SIZE: 16346
      FILE: /arduino.jpg    SIZE: 8426
      FILE: /star.jpg       SIZE: 3853
    pjpeg_decode_init() failed with status 19 <--- here is
    ===============
    JPEG image info
    ===============
    Width      :0
    Height     :0
    Components :0
    MCU / row  :0
    MCU / col  :0
    Scan type  :0
    MCU width  :0
    MCU height :0
    ===============

title: ESP32 - JPEGDecoder from SPIFFS

Answers: 1

body:
as far as I can determine uploading to SPIFFS via the Arduino IDE is broken as of the beginning of 2018. The files are uploaded but are corrupted on a read. There are a few [fixes reported][1].  I am using a core from Dec 2017 and that works fine.

  [1]: https://github.com/me-no-dev/ESPAsyncWebServer/issues/316


body:
Here's my code

    void loop() {
      if (analogRead(A0) > 500)
      {
        statuss = true ;
      }
      if (statuss)
      {
        digitalWrite(D7, HIGH);
        if (millis() - lasttime > 500)
        {
          digitalWrite(D8, etat);
          digitalWrite(D6, etat);
          etat = !etat;
          lasttime = millis();
        }
      }
      server.handleClient();
    }

When I use only `server.handleClient` everything works fine but when I add any type of code to the `loop()` function the server goes down and I can't see the ESP8266 access point.

title: Can't add more code to loop() when use server.handleClient

Answers: 1

body:
The problem is analogRead. The esp8266 uses the ADC to evaluate the strength of the WiFi signal. Hard use of analogRead disturbs it and the signal goes down. Use millis() to time analogRead.

    unsigned int tempSensRead() {

      const unsigned long MEASURE_INTERVAL = 2L * 1000 * 60; // 2 minutes
      static unsigned long lastMeasureMillis;
      static unsigned int lastValue;

      if (millis() - lastMeasureMillis > MEASURE_INTERVAL) {
        lastMeasureMillis = millis();
        lastValue = analogRead(A0);
      }
      return lastValue;
    }


body:
I'm working with an arduino UNO. I would like to be able to send it `set` and `get` commands over serial and have it update class data class members accordingly by key value pair. I spoke to users in the cpp room, and they suggested I try using map to map every key to value.

command structure
`command:key:value`

ex. `set:key1:20`
ex. `get:key2`

I created a class called Uno, assigned all my keys to private data members, and defined set and get functions. However, I am experiencing unintended behavior.

**Unintended behavior**
The set function ends up setting `key1` and `key2` to the same value, and the `get` function returns a random integer value that wasn't assigned.

      #include <ArduinoSTL.h>
      #include <string.h>
      #include <map>

    class Uno{
      //private
        int key1;
        int key2;
        std::map<String, int Uno::*> keys;
      public:
      //Constructor
        Uno(){
          key1 = 0;
          key2 = 0;
          keys["key1"] = &Uno::key1;
          keys["key2"] = &Uno::key2;
        }
        bool setKey(String key, int value){
          if (keys.count(key)) {
              this->*keys[key] = value;
              return true;
          }
          return false;
        }
        int getKey(String key){
          if (keys.count(key)) {
              return this->*keys[key];
          }
        }
    };

    String inputString = "";      // a String to hold incoming data
    bool stringComplete = false;  // whether the string is complete
    bool scan = false;            // whether a scan is in progress
    Uno myMS;                      // global declaration of Mass Spec Class

    void setup() {
      // initialize serial:
      Serial.begin(9600);
      // reserve 250 bytes for the inputString:
      inputString.reserve(250);
    }

    void loop() {
      if (stringComplete) {
        t(inputString); // tokenize and process string

        //RESET STRING
        inputString = "";
        stringComplete = false;
      }
    }

    void serialEvent() {
      while (Serial.available()) {
        // get the new byte:
        char inChar = (char)Serial.read();
        // add it to the inputString:
        inputString += inChar;
        // if the incoming character is a newline, set a flag so the main loop can
        // do something about it:
        if (inChar == '\n') {
          stringComplete = true;
        }
      }
    }

    void t(String inputString) {
        //get command
        String command = getValue(inputString, ':', 0);

        if(command == "set"){
          // get key, get value
           String key = getValue(inputString, ':', 1);
           int value = (getValue(inputString, ':', 2)).toInt();
           Serial.println(myMS.setKey(key,value));
        }
        else if(command == "get"){
           String key = getValue(inputString, ':', 1);
           int value = myMS.getKey(key);
           Serial.println(value);
        }
        else if(command == "stop"){
           scan = false;
        }
        else if(command == "scan"){
           scan = true;
           while(scan){
    //        Serial.println(myMS.scan());
           }
        }
        else{
           Serial.println("not recognized");
        }
    }

    String getValue(String data, char separator, int index)
    {
      int found = 0;
      int strIndex[] = {0, -1};
      int maxIndex = data.length()-1;

      for(int i=0; i<=maxIndex && found<=index; i++){
        if(data.charAt(i)==separator || i==maxIndex){
            found++;
            strIndex[0] = strIndex[1]+1;
            strIndex[1] = (i == maxIndex) ? i+1 : i;
        }
      }
      return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
    }

**EDIT:** Here is a REPL IT working demo of concept provided by nwp.
[https://repl.it/repls/AntiqueProductiveMineral][1]

Sample output

    set:key1:10 ===> 1 (GOOD)
    get:key1 ===> 32512

  [1]: https://repl.it/repls/AntiqueProductiveMineral

title: Arduino std::map returning random values

Answers: 1

body:
You get random values because if the key is not found in getKey, then there is no return statement.

You attach the \n to the key in serialEvent(), then the key for getKey is "key1\n" and it is not found.

    void serialEvent() {
      while (Serial.available()) {
        // get the new byte:
        char inChar = (char)Serial.read();
        if (inChar == '\n') {
          stringComplete = true;
        } else {
          inputString += inChar;
        }
      }
    }

If you have CR/LF set in Serial Monitor, then the \r character is send too and the parsed key is "key1\r\n".

There are obsolete things in your code, like the this->* or Uno::. Make the map `std::map<String, int> keys;`, because now you mix pointers and ints.


body:
i have a little project going on, where i want to connect vibration motors to an arduino. I found [this](https://learn.adafruit.com/adafruit-arduino-lesson-13-dc-motors/overview), with example code but also found other tutorials wish use a capacitor for the motor. What is the advantage of using one ?

I am currently planning to power the arduino by a 9V battery, with 3 ultrasound sensors being connected to the 5v output of the arduino. Hence, i believe that i need an external battery for the 2 vibration motors. I think 2x AA's should do the job for some hours, right ?

I also have a question about the rating of the resistor to use at the base of the transistor. How do i calculate the rating that i need ?

title: Using external battery for motor

Answers: 2

body:
Resistor is there to limit Arduino current out. 220, 270, 330, any should be okay.

Be sure to connect battery - to Arduino Gnd.
Transistor will be used to connect motor '-' to Gnd? Be sure to put a diode across it - anode to motor '+', cathode to motor '-' to dissipate current surge generated by the motor when the transistor turns off.

2AAs will last a little while. Better than using 9V for them, that will drain a battery quick.

body:
a transistor is a current controlled current source. it means that you can control how much current is "Allowed" to flow from emitter to collector, by controlling the minor current flowing through the base of transistor. there is a specific ratio for this two currents for various transistors. (I recommend reading some transistor tutorials). let's say, your motor is drawing 250mA in full speed. you want to "allow" up to 300mA to be available to it.

 1. base is connected to 5V through a 2.2 kOhm resistor. The base current is : (5/220) ~=  2.2mA
 2. the hfe of your transistor is 150 (it depends on transistor model. It’s written in the datasheet available for every transistor on the market. it's the ratio of base current and emitter collector current mentioned above. You “must” read it first as it’s highly various between transistor models).
 3. The current allowed to flow from emitter to collector is 2.2mA * 150 = 330mA which is sufficient for you motor.

note : many simplifications are made to make it easier to understand.


body:
I want to read sensor data using *analogRead()* after every 5ms. I have read other answers to similar questions but what I'm confused about is:

 - let's say, I made a loop to read sensor data using *analogRead()* at the end of which I write *delay(50)*

 - it means it'll take some time to read data(adc) , then it'll wait for 50ms

 - time to execute loop isn't same for every iteration so we get the pattern as: *some time for loop execution*, *delay of 50ms*, *some time for next iteration*........and so on
**I want to ask if I want arduino to read sensor data exactly every 5ms, what should I do?**
Thanks

title: Read sensor data repeatedly after specified time?

Answers: 2

body:
You store the time (`millis()`) of the last measurement. Then wait till 5ms have past since the last measurement. Do your measurement, and update the time.

Something like:

    unsigned long lastMeasurement = millis();

    void loop()
    {
      while( (millis()-lastMeasurement)<5 ){/* do nothing */}
      lastMeasurement = lastMeasurement + 5; //or use `lastMeasurement=millis();` depending on whether you want accuracy between measurement, or accuracy over time
      auto measurement = analogRead(A0);
    }

body:
You do something like this

    unsigned long timerMesurement = 0;

    void loop()
    {
      if (millis() - timerMesurement > 5UL) {
        timerMesurement = millis();
        int measurement = analogRead(A0);
      }
    }