body:
I am trying to make some data logging conserining physiological data coming from a bitalino.
My problem is that I would like to collect samples at something like 1 kHz, that is the rate that the bitalino can read the sensors, but I think that the time needed
to write this data to the SD card can't keep up with the speed, and here is why i think that:

I put in the script some timers to check what was consuming the time causing to low sample rate, resulting:

    Bitalino: 0, SD: 27
    Bitalino: 0, SD: 28
    Bitalino: 2, SD: 26
    Bitalino: 0, SD: 29

Being that the time in miliseconds.

    void loop() {
        time = millis();
        readBIT();
        time2 = millis();
        printDataSD();
        time3 = millis();
        printData();
    }

    void printData() //Send the data acquired to the pc through the serial port
    {
      Serial.print("Bitalino: ");
      Serial.print(time2-time);
      Serial.print(", SD: ");
      Serial.println(time3-time2);
    }

    void printDataSD() //Send the data acquired to the SD Card
    {
        if (myFile) {
        //Bitalino
        myFile.print(_ECG);
        myFile.print(",");
        myFile.print(_EMG);
        myFile.print(",");
        myFile.print(_EEG);
        myFile.print(",");
        myFile.print(_EDA);
        myFile.print(",");
        //Time
        myFile.println(time);
        myFile.flush();

        } else {
        Serial.print("error opening file, ");
        SD.begin(10);
        delay(1000);
      }
    }
I would like to know if there is a way to improve my sample rate.

Thank you!

Here is the readBit() like asked:

    void readBIT() //Read IMU data
     {
      _ECG = analogRead(ECG);
      _ECG = ((_ECG/1024) - 0.5)*Vcc*1000/gECG; //mV

     _EMG = analogRead(EMG);
     _EMG = ((_EMG/1024) - 0.5)*Vcc*1000/gEMG; //mV

     _EEG = analogRead(EEG);
     _EEG = ((_EEG/1024) - 0.5)*Vcc*1000000/gEEG; //uV

     _EDA = analogRead(EDA);
     _EDA = (_EDA/1024*Vcc-0.259388)/gEDA; // revolution
     }

title: Data logging speed with arduino

Answers: 2

body:
Why not write a simple program and try to write values like 1, 2, 3 ... 100 to the SD card with a 1 second delay between writes. Then read the values back and send them via serial link to your PC screen.
This way you can make sure that you are writing and reading values in the correct way.

Once this works, you can reduce the delay and see what is the minimum delay between writes that the SD card will support.

It might be advisable to also write a program to fill the SD card with 100 values = 0 to clear it before the next test.

body:
The OP has likely solved this problem by now, but I know that others will be in the same position, so I am answering for them.

I routinely record ten channels of biological sensors including one of 16-bit sound at 8 kHz (plus the associated FFT data) to an SD card using arduino-compatible systems, so I doubt very much that the SD card writing per se is the problem.

Throughput to an SD card is a function of several variables.

 - To maximize write throughput you need to write full blocks of data at
   the correct block size, since partial blocks take the same amount of
   time as full blocks.
 - You also need to be ready with more data as soon as the SD card is
   ready to take more, otherwise precious cycles slip away from you.
 - You need to ensure that your writes are non-blocking (don't try to
   write more than the buffer can receive) so your loop can process and
   queue up new data while the SD card is doing its thing.
 - You need to read any timing-sensitive sensors using interrupt service
   routines that write their data either to a circular buffer or to one
   of a group of two or three buffers that are cycled between being
   filled and being emptied.

Printing debug statements to the serial port can take many tens of milliseconds in a loop that otherwise may take only a few microseconds. If you write more than the serial port buffer can hold, the call will be blocking and you will be at the mercy of the PC that's reading the serial port. This will always be bad enough to mess up the program you're trying to debug... I've encountered situations where this introduced delays of up to 10 seconds (the PC was misbehaving, but still...).

A quick improvement to printing debug statements is to maintain a loop counter and only print a debug statement every N loops.

The program in the original question uses a naive strategy in the sense that it acquires some amount of data and then immediately tries to write it to the SD card, waiting until the write is complete before trying to acquire new data. This will never work at high data rates for the reasons given above. If you use this approach, you are likely wasting 90% of your program cycles in waiting for the SD write and the Serial port write. If either one takes too long, you will miss the next data acquisition window.

My advice: your first step is to research and find or write a circular buffer library.

Then set a timer to call an interrupt service routine that acquires data and puts it into the circular buffer.

Write a loop routine that checks to see whether the SD card is available for writing, and then takes just enough data out of the circular buffer to fit in a single block write for your SD card (look at the documentation for the card adaptor and the card).

At that point you will know whether your system can keep up with your needs.

It's possible that your SD card writing itself is OK but your Arduino is having trouble keeping up either because it's too slow or because you don't have enough room for a sufficiently large circular buffer. I doubt this because I've recorded and played back audio at 8 KHz on the Uno, but then I don't know what else you need to accomplish in your program.

If you do determine that the Arduino itself is too slow or has insufficient memory, take a look at the Teensy series of boards[ \[https://www.pjrc.com/teensy/index.html\]][1]. They are entirely compatible with Arduino libraries and IDE but they run hundreds of times faster than the Uno at a larger data width, plus they have oodles of RAM and a gazillion pins. They're also much smaller than the Arduino form factor and the community that uses them is very knowledgeable.

If it turns out that SD card write throughput is OK but that it requires more buffering than you have on-board, you can add an SPI ram breakout board for more fast buffering space.

Finally, if the amount of data you need to collect is so large and so continuous that you simply can't buffer it long enough to get it written out to SD, or if the SD card truly can't keep up, or if the data is larger than any available SD card, you may consider sending your data off the board in near-real-time. I send 10 hours of nightly data from a Teensy over a USB virtual serial port to the PC at about 3Mbps, and others have done better. Ethernet output is also available and can be at least an order of magnitude greater.

glhf!

  [1]: https://www.pjrc.com/teensy/index.html


body:
Could I have some help getting the following code work?

My purpose is to turn on 4(or N) LEDs in a binary sequence with 4 (or N) bits, A,B,C,D. When bit=1, LED on, otherwise LED off,...

I will have 16 combinations, 2^4=16, so:

 - 0000 => All leds off
 - 0001 => All leds off except the one on the right
 - ...

Here's the code I came up with:

    int LEDblu=4;
    int LEDgiallo=2;
    int LEDrosso=5;
    int LEDverde=7;
    int num_led;
    String numeri="";
    String output;
    int i=0;
    int p;

    void setup() {
        // put your setup code here, to run once:
        pinMode(LEDblu,OUTPUT);
        pinMode(LEDgiallo,OUTPUT);
        pinMode(LEDrosso,OUTPUT);
        pinMode(LEDverde,OUTPUT);

        Serial.begin(9600);

        if(Serial.available())                //Dimmi numero LED
        {
            num_led=Serial.readString().toInt();
            Serial.print(num_led);
        }
    }

    void loop() {
        // put your main code here, to run repeatedly:
        int vect[num_led];
        for(int i=num_led-1, c=0; i>=0; i--, c++)
        {
            int num=2^i;
            vect[c]=num;
        }

        output="";

        if(i<2^num_led)
        {
            p=i;

            for(int c=0; c<num_led; c++)     //Convert binary to decimal
            {
                if(p>=vect[c])
                {
                    output+="1";
                    int d=vect[c];
                    p-=d;
                }
                else
                    output+="0";
            }

            Serial.println(output);

            if(output[0]=="1")
                digitalWrite(LEDrosso,HIGH);
            else
                digitalWrite(LEDrosso,LOW);

            if(output[1]=="1")
                digitalWrite(LEDverde,HIGH);
            else
                digitalWrite(LEDverde,LOW);

            if(output[2]=="1")
                digitalWrite(LEDgiallo,HIGH);
            else
                digitalWrite(LEDgiallo,LOW);

            if(output[3]=="1")
                digitalWrite(LEDblu,HIGH);
            else
                digitalWrite(LEDblu,LOW);
        }

        delay(1000);
        i++;
    }

title: Turn LEDs on in binary sequence

Answers: 2

body:
I don't see any specific initialization of `num_led`; it should be set to some appropriate value, like 4.

As noted in some comments, the `^` operator is bitwise exclusive-Or.  For example, 2^2 is 0, 2^4 is 6, 2^7 is 5, etc.

To compute the nth power of 2, say `1<<n`.

Your convert-binary-to-decimal code is clunky and unnecessary.  Instead, do something like the following, which repeatedly strips off the least significant bit of `t`:

    t = p;
    digitalWrite(LEDrosso,t&1);   t>>=1;
    digitalWrite(LEDverde,t&1);   t>>=1;
    digitalWrite(LEDgiallo,t&1);  t>>=1;
    digitalWrite(LEDblu,t&1);

If you want the blue LED instead of the red one to represent the least significant bit, reverse the order of color names in the `digitalWrite` statements from rosso, verde, giallo, blu to blu, giallo, verde, rosso.

To print data out in binary, use the [`Streaming.h`](http://arduiniana.org/libraries/streaming/) library, and say, for example,

    Serial << _BIN(p) << endl;

body:
Note that this is one of those situations where [direct port access][]
just makes things easier. You did not specify what board you are using,
and I will assume you have some AVR-based board. On those boards, I/O
pins come in groups called _ports_, with up to eight pins per port. You
can update all the pins of a port at once by writing a number to the
port output register. And guess what? The number you write comes out the
pins in binary, jut like everything works in binary inside the
microcontroller.

For example, on an Arduino Uno, you could wire your LEDs to the first
four pins of port B: i.e. pins 8 (lest significant bit) through 11 (most
significant bit). Then you can output a number to the LEDs just by
writing `PORTB = number`, and your loop would become:

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

    void loop()
    {
        static uint8_t number;
        PORTB = number;              // output to pins 8..11
        Serial.println(number, 2);   // print the value in binary
        number = (number + 1) % 16;  // increment modulo 16
        delay(1000);
    }

[direct port access]: https://www.arduino.cc/en/Reference/PortManipulation


body:
I have a Raspberry Pi and an Arduino Micro. The two are connected by a SPI bus, the RPi is the master; the Arduino the slave.

I need to send 5 bytes to the Arduino and get 5 bytes as an answer.
The answer is pre-calculated so when the Arduino receives the first byte, it already knows what to answer.

I don't understand why the response I get is mis-ordered. I get the right bytes (value), but they seem shifted in time.

Arduino code:

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

    // Data received
    volatile unsigned char rx_buffer[5];

    // Data to be sent
    volatile unsigned char tx_buffer[5];

    // Triggered to true by the interruption when message is complete
    volatile bool message_ready(false);

    // Useful to keep trace of where we are in the message
    unsigned char bytes_received = 0;

    // SPI interrupt routine
    // Message consists of 5 bytes: never less, never more
    ISR (SPI_STC_vect)
    {
      SPDR = tx_buffer[bytes_received];
      rx_buffer[bytes_received] = SPDR;

      if (++bytes_received == 5) // Reached the end of the buffer
      {
        bytes_received = 0;
        message_ready = true;
      }
    }

    void setup (void)
    {
      pinMode(MISO, OUTPUT); // Set Slave Output as output
      SPCR |= _BV(SPE); // Slave mode
      SPCR |= _BV(SPIE); // Turn on interrupts

      // Reponse to be sent
      tx_buffer[0] = 'a';
      tx_buffer[1] = 'b';
      tx_buffer[2] = 'c';
      tx_buffer[3] = 'd';
      tx_buffer[4] = 'e';
    }

    void loop (void)
    {
      // When message is ready, print it on serial port
      if (message_ready)
      {
        message_ready = false;
        Serial.print((char) rx_buffer[0]);
        Serial.print((char) rx_buffer[1]);
        Serial.print((char) rx_buffer[2]);
        Serial.print((char) rx_buffer[3]);
        Serial.println((char) rx_buffer[4]);
      }
    }

The RPi uses a C++ program and WiringPi 2.39 to communicate (I also made a similar program with Unix spidev/ioctl calls, same results)

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

    #include <iostream>
    #include <thread>
    #include <chrono>

    #include <wiringPi.h>
    #include <wiringPiSPI.h>

    using std::cout;
    using std::cerr;
    using std::endl;

    int main(void)
    {
      // Initialize wiringPi
      if (!wiringPiSPISetup(0, 150000))
      {
        cerr << "Could not initialize SPI!" << endl;
        return 1;
      }

      // Create message and response arrays
      uint8_t message[5], response[5];
      message[0] = 'z';
      message[1] = 'u';
      message[2] = 't';
      message[3] = ' ';
      message[4] = '!';

      std::chrono::steady_clock::time_point begin, end;
      unsigned count(0);
      while (1)
      {
        // Change the number at the end of the message: "zut 0", "zut 1" etc..
        message[4] = *std::to_string(count++).c_str();
        if (count == 10)
          count = 0;

        // Copy the message into response because reponse is going to be overwritten
        for (unsigned i(0); i < 5; ++i)
          response[i] = message[i];

        // Count time and transfer the message (and get the reponse at the same time)
        begin = std::chrono::steady_clock::now();
        if (!wiringPiSPIDataRW (0, response, 5))
          cerr << "Could not send message!" << endl;
        end = std::chrono::steady_clock::now();

        // Inform user
        cout << "Sent: " << message << endl;
        cout << "Received: " << response << endl;
        cout << "Duration: " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << " microseconds" << endl;

        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
      }

      return 0;
    }

The outputs are the following,

Arduino (read over serial):

    zut 0
    zut 1
    zut 2
    zut 3
    zut 4
    zut 5
    zut 6
    zut 7
    zut 8
    zut 9
    zut 0
    zut 1
    zut 2
    zut 3

Everything looks good on the Arduino receive side!

RPi output (std::cout/cerr):

    Sent: zut 0
    Received: eabcd
    Duration: 374 microseconds

    Sent: zut 1
    Received: eabcd
    Duration: 359 microseconds

    Sent: zut 2
    Received: eabcd
    Duration: 357 microseconds

    Sent: zut 3
    Received: eabcd
    Duration: 384 microseconds

    Sent: zut 4
    Received: eabcd
    Duration: 389 microseconds

    Sent: zut 5
    Received: eabcd
    Duration: 384 microseconds

    Sent: zut 6
    Received: eabcd
    Duration: 386 microseconds

    Sent: zut 7
    Received: eabcd
    Duration: 391 microseconds

    Sent: zut 8
    Received: eabcd
    Duration: 385 microseconds

    Sent: zut 9
    Received: eabcd
    Duration: 387 microseconds

    Sent: zut 0
    Received: eabcd
    Duration: 387 microseconds

    Sent: zut 1
    Received: eabcd
    Duration: 387 microseconds

    Sent: zut 2
    Received: eabcd
    Duration: 390 microseconds

    Sent: zut 3
    Received: eabcd
    Duration: 386 microseconds

I get the bytes `eabcd` but I expected `abcde`.

Why isn't the RPi receiving the bytes in the correct order? Don't hesitate to ask for additional information.

title: Why is the SPI response mis-ordered?

Answers: 1

body:
@KIIV gave me the answer:

> Anyway to not be shifted, you'll have to fill the data register in slave device BEFORE master even starts the transfer.

What happens is that when an SPI transfer is complete, we enter the `ISR (SPI_STC_vect)`, this means that 1 byte (8 bits) has been received. This also means that the response has been sent, because SPI is full duplex!

So the `SPDR` must be filled with the next byte to be sent before entering the ISR. If you modify the `SPDR` inside the ISR, this will set the next byte to be sent; it will not be sent until a byte is received.

----------

# Fixed Arduino code

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

    // Data received
    volatile unsigned char rx_buffer[5];

    // Data to be sent
    volatile unsigned char tx_buffer[5];

    // Triggered to true by the interruption when message is complete
    volatile bool message_ready(false);

    // Useful to keep trace of where we are in the message
    unsigned char bytes_received = 0;

    // SPI interrupt routine
    // Message consists of 5 bytes: never less, never more
    ISR (SPI_STC_vect)
    {
      // Store incoming byte
      rx_buffer[bytes_received] = SPDR;

      if (++bytes_received == 5) // Reached the end of the message/buffer
      {
        bytes_received = 0;
        message_ready = true;

        // Let's send another message next time!
        changeTxMessage();
      }

      // When next byte is received, this will be the response
      SPDR = tx_buffer[bytes_received];
    }

    // This changes the response message sent by the Arduino to the RPi
    unsigned count(0);
    void changeTxMessage()
    {
      // Update message
      switch (count++)
      {
        case 0:
          tx_buffer[0] = 'c';
          tx_buffer[1] = 'r';
          tx_buffer[2] = 'a';
          tx_buffer[3] = 'z';
          tx_buffer[4] = 'y';
          break;
        case 1:
          tx_buffer[0] = 'k';
          tx_buffer[1] = 'a';
          tx_buffer[2] = 'n';
          tx_buffer[3] = 'j';
          tx_buffer[4] = 'i';
          break;
        case 2:
          tx_buffer[0] = 'b';
          tx_buffer[1] = 'u';
          tx_buffer[2] = 'x';
          tx_buffer[3] = 'o';
          tx_buffer[4] = 'm';
          break;
      }

      if (count > 2)
        count = 0;
    }

    void setup (void)
    {
      pinMode(MISO, OUTPUT); // Set Slave Output as output
      SPCR |= _BV(SPE); // Slave mode
      SPCR |= _BV(SPIE); // Turn on interrupts

      // Reponse to be sent
      tx_buffer[0] = 'a';
      tx_buffer[1] = 'b';
      tx_buffer[2] = 'c';
      tx_buffer[3] = 'd';
      tx_buffer[4] = 'e';

      // Prepare first byte to be sent as a response
      SPDR = tx_buffer[0];
    }

    void loop (void)
    {
      // When message is ready, print it on serial port
      if (message_ready)
      {
        message_ready = false;
        Serial.print((char) rx_buffer[0]);
        Serial.print((char) rx_buffer[1]);
        Serial.print((char) rx_buffer[2]);
        Serial.print((char) rx_buffer[3]);
        Serial.println((char) rx_buffer[4]);
      }
    }

Changes done:

 - On setup(), `SPDR` is filled with the first response byte
 - Added a new function `void changeTxMessage()` that changes the response message sent by the Arduino for demo purposes.

Arduino output:

    zut 0
    zut 1
    zut 2
    zut 3
    zut 4
    zut 5

RPi output:

    Sent: zut 0
    Received: abcde
    Duration: 241 microseconds
    Sent: zut 1
    Received: crazy
    Duration: 231 microseconds
    Sent: zut 2
    Received: kanji
    Duration: 232 microseconds
    Sent: zut 3
    Received: buxom
    Duration: 249 microseconds
    Sent: zut 4
    Received: crazy
    Duration: 254 microseconds
    Sent: zut 5
    Received: kanji
    Duration: 254 microseconds

Everything looks good!

----------
# Further thoughts

One thing I don't understand with the old code: why did I receive `eabcd` the first time I get an answer, the first byte should be random because I did not set the SPDR?! Maybe it's kept in memory during Arduino upload.

----------
# Performance

I cannot achieve high bit rates with this code. 250 000 Hz is the maximum I can reach (`wiringPiSPISetup(0, 250000)`) before getting problems in the communication. Example at 0.5 Mhz:

Arduino log:

    zut 0
    zut 1
    zut 2
    zut 3
    zut 4
    zut 5
    zut 6
    zut 7

RPi log:

    Sent: zut 0
    Received: bzut
    Duration: 143 microseconds
    Sent: zut 1
    Received: czut
    Duration: 136 microseconds
    Sent: zut 2
    Received: kzut
    Duration: 135 microseconds

I expected to reach at least 2 Mhz, I think I'll open a new question for that.


body:
I am thinking over an autonomous rover.

One of the features/components of the rover will be ability to know how fast is the rover moving and what distance did it travel. I would like to use dedicated attiny85 chip for that. The chip will use rotary encoder and interrupts to detect motion. It will be connected throught I2C/SPI (do not know yet) with the main controller. Main controller will ask the attiny85 on speed and distance if needed.

The problem is, I guess, that rotary encoder will use interrupts and so the I2C or SPI may not work properly. I could disable interrupts while communicating but:

 1. Motion sensing won't be precise, as I will loose some motion data.
 2. When attiny85 will be on receiving side, it wont know soon enough that it should disable the interrupts.
 3. There is a chance that SPI/I2C uses the interrupts as well, not sure, have to check.

Am I right? What would you advise?

title: Are (how much are) interupts interfering I2C or SPI communication?

Answers: 0


body:
I'm trying to use an Arduino Mega 2560 to use 7-segment displays, 6 displays... I use 3 CD4543B to pilot the 6 displays.

It works very well for 4 displays as you can see in this [video][1].

But when I want to use the same circuit for 5 or 6 displays, there is some bug as you can see on this [video][2] for 5 displays.

Here is the code that works fine for 4 displays:

    //définition des broches du premier décodeur
    const int bit_A=8;
    const int bit_B=9;
    const int bit_C=10;
    const int bit_D=11;
    //définition du brochage du deuxieme decodeur
    const int bit_E=22;
    const int bit_F=24;
    const int bit_G=26;
    const int bit_H=28;
    //définition du brochage du 3ième décodeur
    const int bit_I=40;
    const int bit_J=42;
    const int bit_K=44;
    const int bit_L=46;
    //définition des broches des transistors

    const int alim_millier=3;
    const int alim_centaine=4;
    const int alim_dizaine=5;
    const int alim_unite=6;

    void setup() {
      //les broches sont toutes des sorties
      pinMode(bit_A,OUTPUT);
      pinMode(bit_B,OUTPUT);
      pinMode(bit_C,OUTPUT);
      pinMode(bit_D,OUTPUT);
      pinMode(bit_E,OUTPUT);
      pinMode(bit_F,OUTPUT);
      pinMode(bit_G,OUTPUT);
      pinMode(bit_H,OUTPUT);
      pinMode(bit_I,OUTPUT);
      pinMode(bit_J,OUTPUT);
      pinMode(bit_K,OUTPUT);
      pinMode(bit_L,OUTPUT);
      pinMode(alim_millier,OUTPUT);
      pinMode(alim_centaine,OUTPUT);
      pinMode(alim_dizaine,OUTPUT);
      pinMode(alim_unite,OUTPUT);
      //les broches sont toutes mises à l'état bas
      digitalWrite(bit_A,LOW);
      digitalWrite(bit_B,LOW);
      digitalWrite(bit_C,LOW);
      digitalWrite(bit_D,LOW);
      digitalWrite(bit_E,LOW);
      digitalWrite(bit_F,LOW);
      digitalWrite(bit_G,LOW);
      digitalWrite(bit_H,LOW);
      digitalWrite(bit_I,LOW);
      digitalWrite(bit_J,LOW);
      digitalWrite(bit_K,LOW);
      digitalWrite(bit_L,LOW);
      digitalWrite(alim_millier,LOW);
      digitalWrite(alim_centaine,LOW);
      digitalWrite(alim_dizaine,LOW);
      digitalWrite(alim_unite,LOW);
    }

    void loop() {
      //fonction principale
      for(int i=0; i<10000; i++) {
        //boucle qui permet de compter de0 à9999(=10000 valeurs)
        afficher_nombre(i);//appelde la fonction affichage avec envoi du nombre à afficher
      }
    }

    //fonction permettant d'afficherun nombre sur quatre afficheurs
    void afficher_nombre(int nombre) {
      long temps;//variable utilisée poursavoir le temps écoulé
      int unite=0,dizaine=0,centaine=0, millier=0;//variable pour chaque afficheur
      millier=nombre/1000;//on récupère les milliers
      centaine=(nombre-1000*millier)/100;//on récupère les centaines
      dizaine=(nombre-(centaine*100)-(millier*1000))/10;//on récupère les dizaines
      unite=nombre-(millier*1000)-(centaine*100)-(dizaine*10);//on récupère les unités
      temps=millis();//on récupère le temps courant
      //tant qu'on a pas affiché ce chiffre pendant au moins 500 milliseconde
      //permet donc de pouvoir lire le nombre affiché
      while((millis()-temps)<500) {
        //on affiche le nombre
        //d'abord les milliers pendant 5ms
        digitalWrite(alim_millier,HIGH);
        afficher_CD(millier);//on appelle la fonction qui permet d'afficher le chiffre millier
        digitalWrite(alim_centaine,LOW);
        digitalWrite(alim_dizaine,LOW);//le transistor est bloqué
        digitalWrite(alim_unite,LOW);//le transistor est bloqué
        delay(5);
        //d'abord les centaines pendant 5ms
        digitalWrite(alim_millier,LOW);
        digitalWrite(alim_centaine,HIGH);//le transistor de l'afficheur des centaines est saturé, donc l'afficheur est allumé
        afficher_CM(centaine);//on appelle la fonction qui permet d'afficher le chiffre centaine
        digitalWrite(alim_dizaine,LOW);//le transistor est bloqué
        digitalWrite(alim_unite,LOW);//le transistor est bloqué
        delay(5);
        //ensuite les dizaines pendant 5 ms
        digitalWrite(alim_millier,LOW);
        digitalWrite(alim_centaine,LOW);// transistor est bloqué
        digitalWrite(alim_dizaine,HIGH);//transistor saturé
        afficher_CM(dizaine);
        digitalWrite(alim_unite,LOW);//transistor bloqué
        delay(5);
        //on affiche les unités 5 ms
        digitalWrite(alim_millier,LOW);
        digitalWrite(alim_centaine,LOW);//transistor bloqué
        digitalWrite(alim_dizaine,LOW);//transistor bloqué
        digitalWrite(alim_unite,HIGH);//transistor saturé
        afficher_UD(unite);
        delay(5);
      }
    }

    //fonction écrivant sur les premiers afficheurs
    void afficher_UD(int chiffre) {
      digitalWrite(bit_A,LOW);
      digitalWrite(bit_B,LOW);
      digitalWrite(bit_C,LOW);
      digitalWrite(bit_D,LOW);
      if(chiffre>=8) {
        digitalWrite(bit_D,HIGH);
        chiffre=chiffre-8;
      }
      if(chiffre>=4) {
        digitalWrite(bit_C,HIGH);
        chiffre=chiffre-4;
      }
      if(chiffre>=2) {
        digitalWrite(bit_B,HIGH);
        chiffre=chiffre-2;
      }
      if(chiffre>=1) {
        digitalWrite(bit_A,HIGH);
        chiffre=chiffre-1;
      }
    }

    //fonction écrivant sur le second afficheur
    void afficher_CM(int chiffre) {
      digitalWrite(bit_E,LOW);
      digitalWrite(bit_F,LOW);
      digitalWrite(bit_G,LOW);
      digitalWrite(bit_H,LOW);
      if(chiffre>=8) {
        digitalWrite(bit_H,HIGH);
        chiffre=chiffre-8;
      }
      if(chiffre>=4) {
        digitalWrite(bit_G,HIGH);
        chiffre=chiffre-4;
      }
      if(chiffre>=2) {
        digitalWrite(bit_F,HIGH);
        chiffre=chiffre-2;
      }
      if(chiffre>=1) {
        digitalWrite(bit_E,HIGH);
        chiffre=chiffre-1;
      }
    }

    void afficher_CD(int chiffre) {
      digitalWrite(bit_I,LOW);
      digitalWrite(bit_J,LOW);
      digitalWrite(bit_K,LOW);
      digitalWrite(bit_L,LOW);
      if(chiffre>=8) {
        digitalWrite(bit_L,HIGH);
        chiffre=chiffre-8;
      }
      if(chiffre>=4) {
        digitalWrite(bit_K,HIGH);
        chiffre=chiffre-4;
      }
      if(chiffre>=2) {
        digitalWrite(bit_J,HIGH);
        chiffre=chiffre-2;
      }
      if(chiffre>=1) {
        digitalWrite(bit_I,HIGH);
        chiffre=chiffre-1;
      }
    }

And here the code for 5 displays with "bugs" :

    //définition des broches du premier décodeur
    const int bit_A=8;
    const int bit_B=9;
    const int bit_C=10;
    const int bit_D=11;
    //définition du brochage du deuxieme decodeur
    const int bit_E=22;
    const int bit_F=24;
    const int bit_G=26;
    const int bit_H=28;
    //définition du brochage du 3ième décodeur
    const int bit_I=40;
    const int bit_J=42;
    const int bit_K=44;
    const int bit_L=46;
    //définition des broches des transistors
    const int alim_dm= 3;
    const int alim_millier=4;
    const int alim_centaine=5;
    const int alim_dizaine=6;
    const int alim_unite=7;
    void setup() {
      //les broches sont toutes des sorties
      pinMode(bit_A,OUTPUT);
      pinMode(bit_B,OUTPUT);
      pinMode(bit_C,OUTPUT);
      pinMode(bit_D,OUTPUT);
      pinMode(bit_E,OUTPUT);
      pinMode(bit_F,OUTPUT);
      pinMode(bit_G,OUTPUT);
      pinMode(bit_H,OUTPUT);
      pinMode(bit_I,OUTPUT);
      pinMode(bit_J,OUTPUT);
      pinMode(bit_K,OUTPUT);
      pinMode(bit_L,OUTPUT);
      pinMode(alim_dm,OUTPUT);
      pinMode(alim_millier,OUTPUT);
      pinMode(alim_centaine,OUTPUT);
      pinMode(alim_dizaine,OUTPUT);
      pinMode(alim_unite,OUTPUT);
      //les broches sont toutes mises à l'état bas
      digitalWrite(bit_A,LOW);
      digitalWrite(bit_B,LOW);
      digitalWrite(bit_C,LOW);
      digitalWrite(bit_D,LOW);
      digitalWrite(bit_E,LOW);
      digitalWrite(bit_F,LOW);
      digitalWrite(bit_G,LOW);
      digitalWrite(bit_H,LOW);
      digitalWrite(bit_I,LOW);
      digitalWrite(bit_J,LOW);
      digitalWrite(bit_K,LOW);
      digitalWrite(bit_L,LOW);
      digitalWrite(alim_dm,LOW);
      digitalWrite(alim_millier,LOW);
      digitalWrite(alim_centaine,LOW);
      digitalWrite(alim_dizaine,LOW);
      digitalWrite(alim_unite,LOW);
    }

    void loop() {
      //fonction principale
      for(int i=0;i<100000;i++)//boucle qui permet de compter de0 à 99999(=100000 valeurs) {
        afficher_nombre(i);//appelde la fonction affichage avec envoi du nombre à afficher
      }
    }

    //fonction permettant d'afficherun nombre sur quatre afficheurs
    void afficher_nombre(int nombre) {
      long temps;//variable utilisée poursavoir le temps écoulé
      int unite=0,dizaine=0,centaine=0, millier=0, dm=0;//variable pour chaque afficheur
      dm=nombre/10000;//on récupère les dm
      millier=(nombre-(10000*dm))/1000;//on récupère les milliers
      centaine=(nombre-1000*millier)-(10000+dm)/100;//on récupère les centaines
      dizaine=(nombre-(centaine*100)-(millier*1000)-(dm*10000))/10;//on récupère les dizaines
      unite=nombre-(dm*10000)-(millier*1000)-(centaine*100)-(dizaine*10);//on récupère les unités

      temps=millis();//on récupère le temps courant
      //tant qu'on a pas affiché ce chiffre pendant au moins 500 milliseconde
      //permet donc de pouvoir lire le nombre affiché
      while((millis()-temps)<500) {
        //on affiche le nombre
        //d'abord les dms pendant 5ms
        digitalWrite(alim_dm,HIGH);
        afficher_CD(dm);//on appelle la fonction qui permet d'afficher le chiffre dm
        digitalWrite(alim_millier,LOW);//le transistor bloqué
        digitalWrite(alim_centaine,LOW);//le transistor est bloqué
        digitalWrite(alim_dizaine,LOW);//le transistor est bloqué
        digitalWrite(alim_unite,LOW);//le transistor bloqué
        delay(10);
        //d'abord les millier pendant 5ms
        digitalWrite(alim_dm,LOW);
        digitalWrite(alim_millier,HIGH);//le transistor de l'afficheur des centaines est saturé, donc l'afficheur est allumé
        afficher_CM(millier);//on appelle la fonction qui permet d'afficher le chiffre centaine
        digitalWrite(alim_centaine,LOW);//le transistor est bloqué
        digitalWrite(alim_dizaine,LOW);//le transistor est bloqué
        digitalWrite(alim_unite,LOW);//le transistor bloqué
        delay(10);
        //ensuite les centaine pendant 5 ms
        digitalWrite(alim_dm,LOW);
        digitalWrite(alim_millier,LOW);
        digitalWrite(alim_centaine,HIGH);// transistor est bloqué
        afficher_CM(centaine);
        digitalWrite(alim_dizaine,LOW);//transistor saturé
        digitalWrite(alim_unite,LOW);//transistor bloqué
        delay(10);
        //on affiche les dizaines 5 ms
        digitalWrite(alim_dm,LOW);
        digitalWrite(alim_millier,LOW);
        digitalWrite(alim_centaine,LOW);//transistor bloqué
        digitalWrite(alim_dizaine,HIGH);//transistor bloqué
        afficher_UD(dizaine);
        digitalWrite(alim_unite,LOW);//transistor saturé
        delay(10);
        //on affiche les unités
        digitalWrite(alim_dm,LOW);
        digitalWrite(alim_millier,LOW);
        digitalWrite(alim_centaine,LOW);//transistor bloqué
        digitalWrite(alim_dizaine,LOW);//transistor bloqué
        digitalWrite(alim_unite,HIGH);//transistor saturé
        afficher_UD(unite);
        delay(10);
      }
    }

    //fonction écrivant sur les premiers afficheurs
    void afficher_UD(int chiffre) {
      digitalWrite(bit_A,LOW);
      digitalWrite(bit_B,LOW);
      digitalWrite(bit_C,LOW);
      digitalWrite(bit_D,LOW);
      if(chiffre>=8) {
        digitalWrite(bit_D,HIGH);
        chiffre=chiffre-8;
      }
      if(chiffre>=4) {
        digitalWrite(bit_C,HIGH);
        chiffre=chiffre-4;
      }
      if(chiffre>=2) {
        digitalWrite(bit_B,HIGH);
        chiffre=chiffre-2;
      }
      if(chiffre>=1) {
        digitalWrite(bit_A,HIGH);
        chiffre=chiffre-1;
      }
    }

    //fonction écrivant sur le second afficheur
    void afficher_CM(int chiffre) {
      digitalWrite(bit_E,LOW);
      digitalWrite(bit_F,LOW);
      digitalWrite(bit_G,LOW);
      digitalWrite(bit_H,LOW);
      if(chiffre>=8) {
        digitalWrite(bit_H,HIGH);
        chiffre=chiffre-8;
      }
      if(chiffre>=4) {
        digitalWrite(bit_G,HIGH);
        chiffre=chiffre-4;
      }
      if(chiffre>=2) {
        digitalWrite(bit_F,HIGH);
        chiffre=chiffre-2;
      }
      if(chiffre>=1) {
        digitalWrite(bit_E,HIGH);
        chiffre=chiffre-1;
      }
    }

    void afficher_CD(int chiffre) {
      digitalWrite(bit_I,LOW);
      digitalWrite(bit_J,LOW);
      digitalWrite(bit_K,LOW);
      digitalWrite(bit_L,LOW);
      if(chiffre>=8) {
        digitalWrite(bit_L,HIGH);
        chiffre=chiffre-8;
      }
      if(chiffre>=4) {
        digitalWrite(bit_K,HIGH);
        chiffre=chiffre-4;
      }
      if(chiffre>=2) {
        digitalWrite(bit_J,HIGH);
        chiffre=chiffre-2;
      }
      if(chiffre>=1) {
        digitalWrite(bit_I,HIGH);
        chiffre=chiffre-1;
      }
    }
    //Fin du programme

I've been trying for weeks to understand the problem. All displays work fine, and if I adapt the code for 4 displays and try to use any 4 of the 6 displays it works fine (I have tried a combination such as displays: 1, 2, 3, 4 or 2, 3, 4, 5 or 3, 4, 5, 6 or 1, 2, 5, 6, everything works).

Thanks to a conversation on [the Arduino forum][3], I also tried this code for 5 displays but I still have the same problem:

    //Da
    const int bit_A=8;
    const int bit_B=9;
    const int bit_C=10;
    const int bit_D=11;
    //Db
    const int bit_E=22;
    const int bit_F=24;
    const int bit_G=26;
    const int bit_H=28;
    //Dc
    const int bit_I=40;
    const int bit_J=42;
    const int bit_K=44;
    const int bit_L=46;
    // transistors
    const int alim_dizainemillier= 3;
    const int alim_millier=4;
    const int alim_centaine=5;
    const int alim_dizaine=6;
    const int alim_unite=7;
    void setup() {
      pinMode(bit_A,OUTPUT);
      pinMode(bit_B,OUTPUT);
      pinMode(bit_C,OUTPUT);
      pinMode(bit_D,OUTPUT);
      pinMode(bit_E,OUTPUT);
      pinMode(bit_F,OUTPUT);
      pinMode(bit_G,OUTPUT);
      pinMode(bit_H,OUTPUT);
      pinMode(bit_I,OUTPUT);
      pinMode(bit_J,OUTPUT);
      pinMode(bit_K,OUTPUT);
      pinMode(bit_L,OUTPUT);
      pinMode(alim_dizainemillier,OUTPUT);
      pinMode(alim_millier,OUTPUT);
      pinMode(alim_centaine,OUTPUT);
      pinMode(alim_dizaine,OUTPUT);
      pinMode(alim_unite,OUTPUT);
      digitalWrite(bit_A,LOW);
      digitalWrite(bit_B,LOW);
      digitalWrite(bit_C,LOW);
      digitalWrite(bit_D,LOW);
      digitalWrite(bit_E,LOW);
      digitalWrite(bit_F,LOW);
      digitalWrite(bit_G,LOW);
      digitalWrite(bit_H,LOW);
      digitalWrite(bit_I,LOW);
      digitalWrite(bit_J,LOW);
      digitalWrite(bit_K,LOW);
      digitalWrite(bit_L,LOW);
      digitalWrite(alim_dizainemillier,LOW);
      digitalWrite(alim_millier,LOW);
      digitalWrite(alim_centaine,LOW);
      digitalWrite(alim_dizaine,LOW);
      digitalWrite(alim_unite,LOW);
    }

    void loop() {
      for(int i=0;i<100000;i++) {
        afficher_nombre(i);
        delay(5);
      }
    }

    void afficher_nombre(int nombre) {
      long temps;
      int unite=0,dizaine=0,centaine=0, millier=0, dizainemillier=0;
      dizainemillier=nombre/10000;
      millier=(nombre-(10000*dizainemillier))/1000;
      centaine=(nombre-(1000*millier)-(10000*dizainemillier))/100;
      dizaine=(nombre-(centaine*100)-(millier*1000)-(dizainemillier*10000))/10;
      unite=nombre-(dizainemillier*10000)-(millier*1000)-(centaine*100)-(dizaine*10);
      temps=millis();
      while((millis()-temps)<500){
        afficher_CD(dizainemillier);
        digitalWrite(alim_dizainemillier, HIGH);
        delay(5);
        digitalWrite(alim_dizainemillier, LOW);
        afficher_CM(millier);
        digitalWrite(alim_millier, HIGH);
        delay(5);
        digitalWrite(alim_millier, LOW);
        afficher_CM(centaine);
        digitalWrite(alim_centaine, HIGH);
        delay(5);
        digitalWrite(alim_centaine, LOW);
        afficher_UD(dizaine);
        digitalWrite(alim_dizaine, HIGH);
        delay(5);
        digitalWrite(alim_dizaine, LOW);
        afficher_UD(unite);
        digitalWrite(alim_unite, HIGH);
        delay(5);
        digitalWrite(alim_unite, LOW);
      }
    }

    void afficher_UD(int chiffre) {
      digitalWrite(bit_A,chiffre & 1);
      digitalWrite(bit_B,chiffre & 2);
      digitalWrite(bit_C,chiffre & 4);
      digitalWrite(bit_D,chiffre & 8);
    }

    void afficher_CM(int chiffre) {
      digitalWrite(bit_E,chiffre & 1);
      digitalWrite(bit_F,chiffre & 2);
      digitalWrite(bit_G,chiffre & 4);
      digitalWrite(bit_H,chiffre & 8);
    }

    void afficher_CD(int chiffre) {
      digitalWrite(bit_I,chiffre & 1);
      digitalWrite(bit_J,chiffre & 2);
      digitalWrite(bit_K,chiffre & 4);
      digitalWrite(bit_L,chiffre & 8);
    }

Any clue is very welcome! Thanks!

  [1]: https://youtu.be/cTKuFk76ZP0
  [2]: https://youtu.be/boCAtVDET5w
  [3]: https://forum.arduino.cc/index.php?topic=475902.msg3261509#msg3261509

title: 7 segment displays arduino mega 2560

Answers: 2

body:
I think it's because I use `int` and I should use `long` to avoid overflow... for the number I want to display:

    void loop()
    {
     for(int i=0;i<100000;i++)
     {
       afficher_nombre(i);
       delay(5);
     }
    }

should be :

    void loop()
    {
     for(long i=0;i<100000;i++)
     {
       afficher_nombre(i);
       delay(5);
     }
    }

 And also a parentheses problem solved thanks to cattledog on [this forum][1]

  [1]: https://forum.arduino.cc/index.php?topic=475902.15

body:
> Here is the code that works fine for 4 displays:

both code pieces suffer from the use of "delay()".

here is what I used - https://dannyelectronics.wordpress.com/2017/06/30/a-more-flexible-driver-for-7-segment-leds/

it is written so the leds can be driven by individual pins so porting to  arduino requires no change to the source code - just a few macros to remap the IO operations.

also running it from a timer isr is the (only) way to go.

edit: here is to show how the code above gets to work here. I expanded it to cover 8 digits but only the first 6 digits effective. three macros are all it takes to repurpose it for arduino.

displaying a fixed "123456".

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

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

all the user code does is to dump the content to be displayed into the display buffer and the display routine, led_display() takes care of the rest.


body:
What I'm doing wrong or why is it not working:

    #define Uin A0;

    void setup() {
    }

    void loop() {
      analogRead(Uin);
    }

Results in a `Error (expected ')' before ; token.`

I thought `#define` just exists as a place holder.

title: Why can't I define the constant A0 (some pin) to something?

Answers: 1

body:
Because you have a `;` at the end of your #define.

    #define Uin A0;
    analogRead(Uin);

becomes:

    analogRead(A0;);

The Arduino website mentions this in [their reference](https://www.arduino.cc/en/Reference/Define). For more in-depth detail about the C pre-processor you can read the (rather large) manual [here](https://gcc.gnu.org/onlinedocs/cpp/).


body:
I have a system that checks the value of a moisture sensor and will also check the time

    if (t.hour == 7 && t.min == 00 && moistureOneSensorValue >= 700) {
      RelayOne();
      RelayTwo();
    }

When `moistureOneSensorValue` is greater than or equal to 700 it means the soil is `DRY`, so when all conditions inside the if statement are true the `relayOne` and `relayTwo` functions will be called.

My problem is that when `moistureOneSensorValue` is still `moist` the above if statement will result in `false` and the `relayOne` and `relayTwo` functions will not be called. I want Arduino to execute and call the `relayOne` and `relayTwo` functions and disregard the `time`. I use time so that the system will only call the `relayOne` and `relayTwo` functions in the morning at exactly 7 AM every day, but it needs to check/make sure that the soil is `DRY`...

**Example**

First thing in the morning the system will check the time and sensor value; if the `if statement` results in `false` the system will keep monitoring and try the if statement until the soil is `DRY`. But I think when that happens it will be over 7 AM.

Sorry for the messy explanation.

title: How to code multiple conditions inside if statement?

Answers: 2

body:
If the event is to be time independent then it follows you can not check the time.  If the event is to be both time independent and dependent then you need to add the code to handle the logic.

Consider checking if it is between 7am and, say, 7pm.  If true then test if the moisture detector is dry.  If true then close (watering) relays.

*(This is only a code example and has not been tested.)*

    if(t.hour >= 7 && t.hour <= 19)
    {
      while(moistureOneSensorValue >= 700)
      {
       RelayOne();
       RelayTwo();
      }
    }

Consider adding a state machine to mitigate possible problems by monitoring minimum times between events and maximum times of events.  For example, do not water more than once per 5 minutes.  Do not water more than 30 seconds at a time.  Do not water more then a total of 1 minute per hour.  Do not water more than 5 minutes per 24 hours.

body:
I'm not sure how quickly you soil could get dry, but I suspect what you want to do is to periodically check the dryness throughout the day. Say like every two hours:

    // Check every 2 hrs (when hr is even)
    if ( t.hour % 2 == 0 && moistureOneSensorValue >= 700 ) {...}

You could also bound it to only during the day time:

    if ( t.hour >= 7 // after 7a
      && t.hour <= 19 // before 7p
      && t.hour % 2 == 1 // every 2 hrs (when hr is odd)
      && moistureOneSensorValue >= 700 // soil is dry
    ) {...}


body:
I have 2x NRF24L01+ communicating but they are unreliable. It doesn't matter if they are right night to each other or 100ft away. For some odd reason when I place my hand on the antenna it work perfectly. Why would this be?
I have one set up to send and one to receive. All I am sending from one to the other is a 3 digit number to turn on a relay.

title: NRF24L01+ Issues antenna

Answers: 1

body:
I found a solution. As the signals where too close I found where I could tone down the signal strength using:

       radio.setPALevel(RF24_PA_MIN);

Because I didn't want to loose long range capabilities too I send my packet out 4 times at this lower signal and then increase the strength back to max to send out another 4 packets. This way my close range and far range relay will receive the signal.


body:
I'm new to Arduino and I have this problem: The common cathode 4 digits 7-segments keep on blinking even the code and my connection is correct (in my opition). I have used an LM35 IC to read the temperature
 I've just followed this pattern:[![enter image description here][1]][1]
and I used this code:

    const int digitPins[4] = {5,4,3,2}; //4 common CATHODE pins of the display (inverted the pins order)
    const int clockPin = 7;    //74HC595 Pin 11
    const int latchPin = 8;    //74HC595 Pin 12
    const int dataPin = 12;     //74HC595 Pin 14
    const int tempPin = A0;     //temperature sensor pin
    const byte digit[10] =      //seven segment digits in bits
    {
      B00111111, //0
      B00000110, //1
      B01011011, //2
      B01001111, //3
      B01100110, //4
      B01101101, //5
      B01111101, //6
      B00000111, //7
      B01111111, //8
      B01101111  //9
    };
    int digitBuffer[4] = {0};
    int digitScan = 0;
    float tempC; //Deleted kelvin and farenheit

    void setup(){
      for(int i=0;i<4;i++)
      {
        pinMode(digitPins[i],OUTPUT);
      }
      pinMode(tempPin, INPUT);
      pinMode(latchPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
      pinMode(tempPin, INPUT);
      //Serial.begin(9600);
    }

    //writes the temperature on display
    void updateDisp(){

      for(byte j=0; j<4; j++) {digitalWrite(digitPins[j], HIGH);} // Turns the display off. Changed to HIGH
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
      digitalWrite(latchPin, HIGH);

      delayMicroseconds(2);

      digitalWrite(digitPins[digitScan], LOW); //Changed to LOW for turning the leds on.

      digitalWrite(latchPin, LOW);
      if(digitScan==2)
        shiftOut(dataPin, clockPin, MSBFIRST, (digit[digitBuffer[digitScan]] | B10000000)); //print the decimal point on the 3rd digit
      else
        shiftOut(dataPin, clockPin, MSBFIRST, digit[digitBuffer[digitScan]]);

      digitalWrite(latchPin, HIGH);

      digitScan++;
      if(digitScan>3) digitScan=0;
    }

    void loop(){
      tempC = analogRead(tempPin)*0.00488;  //multiplied for this conversion constant
      tempC = tempC*10000;
      digitBuffer[3] = int(tempC)/1000;
      digitBuffer[2] = (int(tempC)00)/100;
      digitBuffer[1] = (int(tempC)0)/10;
      digitBuffer[0] = (int(tempC)0);

      if (digitBuffer[0]>=5) {
        digitBuffer[0] = 5;
      }
      else {
        digitBuffer[0] = 0;
      }

      delay(5);
      updateDisp();
    }

  [1]: https://i.stack.imgur.com/Zr5jA.jpg

title: How to make 4 digits 7 segments common cathode thermometer

Answers: 1

body:
First thing to check is that you have the IC and the 7-segment display module connected the correct way around. As a reference, the green wire is attached to Pin 14 of the 74HC595 IC, so pin 1 would be the top right pin. The 7-segment display should have the the dot points towards the bottom.

Check that you have a common cathode display. You can do this by applying a voltage, through a 220 ohm resistor, verifying that it lights up when positive is on pins A-G and Gnd connected to the common cathode pin.

Check the code by removing the temperature section of the code and just writing '0's to all 4 digits. In fact it would be worth testing the digits one by one. The below code should do just that (unverified):

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

    const int clockPin = 7;    //74HC595 Pin 11
    const int latchPin = 8;    //74HC595 Pin 12
    const int dataPin = 12;    //74HC595 Pin 14
    const int digitPins[4] = {5,4,3,2};

    void setup(){
      for(int i=0;i<4;i++)
      {
        pinMode(digitPins[i],OUTPUT);
        digitalWrite(digitPins[i], HIGH);
      }
      pinMode(latchPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
    }

    void loop() {
      for(int i=0;i<4;i++)
      {
        //select the digit by enabling the common cathode (sink)
        digitalWrite(digitPins[i], LOW);

        // write '0'
        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, 63);
        digitalWrite(latchPin, HIGH);
        delay(1000);
      }
    }

This code will display a '0' one digit at a time, each for 1 second.  If this code works then I suspect the problem lies in the `updateDisp()` function.

NB: In your code, tempPin is setup twice as an input.


body:
I would like to know what device and model to use for an application where I will have `1 arduino as a master` micro controller waiting to receive data from `5 slave arduino` microcontrollers.

The `Master` arduino will be connected to local network via Ethernet cable so once it receive data from a `Slave` controller it needs to post to server the information, get a response back and in case the response is a "true" value then the `Master` need to talk back to the `Slave` in order to turn a LED on.

There will be cases when maybe 3 of the `Slaves` will send data at the same time, this doesn't mean at exactly the same millisecond. So I don't know if there will be data lost.

I was reading that `Xbee` maybe is the best device because it has a feature that will hold the data until there is a success communication with slave.

> Is this a doable and "easy" task using `Xbee`? Anyone that already try to do something like this that can guide me?
>
>> I was reading that there is a device `nRF24l01` that is very cheap and can do exactly what I need. Just that I don't really know how to start.

Appreciate any advice or help.

title: Multiple arduino Wireless communication

Answers: 1

body:
It really depends on the communication range and context required.

If your _slaves_ are within 10-20 meters from the _master_ device and the environment is not polluted (in terms of magnetic field) you can achieve good results with very inexpensive nRF24L01+ modules which operate in the 2.4GHz.

If you need to cover greater distances (in the order of 100 meters) or a polluted environment then you have to resort to shorter wavelengths or more powerful devices, but that brings in the question on how are you powering your _slaves_: on battery power those ranges get pretty power hungry.

Generally speaking I would say this question should be rejected as it's going to start a debate rather than provide a solution.

You can get some introductions on how to use nRF24L01+ modules simply searching online:

 - [some posts on my blog][1]
 - [the Arduino library I always advice][2]
 - [a pretty valid guide][3]

  [1]: https://rlogiacco.wordpress.com/?s=nrf24
  [2]: https://github.com/nRF24/RF24
  [3]: https://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo


body:
The Code Below now works:

    void SendCTRL (String &input)
    {
      const char *hin = input.c_str();    // Get character array
      int clen = input.length()/2;
      unsigned char cmd[clen+1]; // Leave a byte for null terminator
      for (int i=0; i < 2*clen; i+=2)
      {
        cmd[i/2] = dehex(hin[i])<<4 | dehex(hin[i+1]);
      }
      cmd[clen] = 0;                     // Null-byte terminator
      digitalWrite(SSerialTxControl, RS485Transmit);  // Enable RS485 Transmit
      for (int i=0; i< clen; i++)
      {
      RS485Serial.write(cmd[i]);   // Send string someplace
      //Serial.write(cmd[i]);
      }
      delay(clen/4);
      digitalWrite(SSerialTxControl, RS485Receive);  // Disable RS485 Transmit
      Serial.println();

    }

    byte dehex(char c)
    {
      // Get nibble value 0...15 from character c
      // Treat digit if c<'A', else letter
      return c<'A'? c & 0xF : 9 + (c & 0xF);
    }

    byte dehex(char c)
    {
      // Get nibble value 0...15 from character c
      // Treat digit if c<'A', else letter
      return c<'A'? c & 0xF : 9 + (c & 0xF);
    }

Input is a series of ASCII-encoded hex digits and getting the output to print the byte values of the hex.

title: Write array to serial port

Answers: 1

body:
There's some logic slightly askew with your length calculations:

    int clen = input.length()/2;

Ok, so for a (say) 20 character string you have `clen=10`.

    for (int i=0; i < clen; i+=2)

Ok, so for the first 10 characters of your 20 character string you take alternate ones (0, 2, 4, 6, 8)

What about the last 10 characters?  `clen` is 10, not 20, since you divided it by 2 at the start.

Decide if you want clen to be half the string length, then count *double*, or is the whole string length, and you divide it by 2 where you want the final string length. Or have two variables - one before and one after dividing by 2.

Oh, and you should pass your String parameter *by reference* so you don't duplicate the object and end up fragmenting your heap.

    void SendCTRL (String &input)

I haven't gone into depth about the working of your `dehex` function, but this is the function I always use and works well:

    unsigned char h2d(char hex)
    {
        if(hex > 0x39) hex -= 7; // adjust for hex letters upper or lower case
        return(hex & 0xf);
    }

Also you should *or* your values together, not *add* them:

    cmd[i/2] = (dehex(hin[i])<<4) | dehex(hin[i+1]);

This would go some way to fixing your current issue, since `|` has a different precedence to `+`. At the moment you have effectively:

    cmd[i/2] = dehex(hin[i]) << (4 + dehex(hin[i+1]));

since the `+` happens before the `<<`, whereas what you want is:

    cmd[i/2] = (dehex(hin[i]) << 4) + dehex(hin[i+1]);

However with `|` instead you get

    cmd[i/2] = (dehex(hin[i]) << 4) | dehex(hin[i+1]);

because the `<<` happens before the `|`

Here is your code written in pure C to run on a PC (faster to debug and test than an Arduino when you're on Linux):

    #include <stdio.h>
    #include <string.h>

    unsigned char dehex(char c)
    {
      // Get nibble value 0...15 from character c
      // Treat digit if c<'A', else letter
      return c<'A'? c & 0xF : 9 + (c & 0xF);
    }

    void SendCTRL (const char *hin)
    {
      int ilen = strlen(hin);
      int clen = ilen / 2;
      unsigned char cmd[clen+1]; // Leave a byte for null terminator
      for (int i=0; i < ilen; i+=2)
      {
        cmd[i/2] = dehex(hin[i])<<4 | dehex(hin[i+1]);
        printf("x\n", cmd[i/2]);
      }
      cmd[clen] = 0;                     // Null-byte terminator
      for (int i = 0; i < clen; i++) {
        printf("%c", cmd[i]);
      }
    }

    void main() {
        SendCTRL("010307E40001C549");
    }


body:
This is an adapted layout for two tlc5940 hooked up to an Arduino nano. The [original project can be found here][1]. I am a little unsure about the capacitors and resistors as that project had it hooked up to a 5v wall plug.

My Design will be running a pattern of PWM, blinking and chasing lights. The two red lights are off of the TLC5940s circuits because reds need a different resistance. If i am wrong, please let me know as that would simplify things.
[![enter image description here][2]][2]

Also as is the way of the stack community, any other red flags you can point out would be greatly appreciated as i am new to this game.

  [1]: http://howtomechatronics.com/projects/diy-led-heart-photo-frame-arduino-project/
  [2]: https://i.stack.imgur.com/lrlK5.jpg

title: Arduino Nano + (2* tlc5940) + 34 LEDs = Power Questions

Answers: 1

body:
As Ignacio has mentioned the TLC5940 is a *constant current* driver. The 2kΩ resistor sets the current for the LEDs regardless of the forward voltage (or colour) or the supply voltage.

Also as Gerben says, move the 0.1µF (100nF) capacitor close to the TLC5940 as you can. There should be one for each TLC5940 since they are *decoupling capacitors*.

You might like to increase the capacitance of the electrolytic too. The purpose of that capacitor is to provide a low impedance energy source to supply the circuit (batteries are actually quite high impedance by comparison). Since you have lots of LEDs being controlled by PWM the current draw will be fluctuating wildly all the time, and lots of energy over brief periods will be wanted.

Another thing to watch, mentioned again by Ignacio, is the supply voltage for the TLC5940 is 5.5V *absolute maximum*. I wouldn't go much above 5V. Depending on what your batteries actually are you may be better running from 3 of them (4.5V alkaline AA - Ni-MH would be ~3.6V, so 4 of them, giving 4.8V, would be better in that situation).

I would also question your use of the TLC5940. They are not the easiest chips to drive requiring quite a strange protocol. Personally I prefer the TLC59116 which is the I2C variant of the same chip. Much easier to control from an Arduino, and requiring just 2 pins. Not so easy for bread-boarding though as they're SMD only.


body: I set a project-goal for me: to make a very small compiler in Attiny.This compiler should read the code from user and translate it into code;then save it in some portion of the flash and jump there. I know this sounds impossible on Attiny85 but I want test self-programming. I read from various websites that the '85 does not have a "bootloader protection" like Atmga or Uno does. If it's true what are the functions used to write to the flash? (The only function I can thing of that access the flash is pgm_read_byte() but that is only for read).

title: Writing to flash Attiny 85

Answers: 0


body:
I am currently developing a project that needs 9 led stripes, each led stripe has 5 meters, 300 leds, it consumes 60W per stripe in a total of 540W...

This are the led stripes - 5M 12W/M 24V SMD 2835

This led stripes use a 24V power supply.

The thing is I want to drive them with an arduino and PWM. What would I need to do it. I was looking for something like CAT4101 but I never dealt with so much power before and I would like your advice.

Thanks

title: how to drive 500W of leds

Answers: 1

body:
The led strips will have their own current limiting / drivers. A couple of quick calculations:

* 24V at 12W is (I=P/V) 12/24 = 0.5A per meter
* 5 meters = 0.5*5 = 2.5A

So each strip takes 2.5A. The CAT4101 is a 1A max driver, but since it is a *constant current* driver it's not suitable for a strip that has its own current control built in.

I suspect each meter consists of 10 chains of 6 LEDs with a current limiting resistor or two. Out of interest, calculations:

* 6 LEDs at (say) 3V forward voltage would be 18V.
* 24 - 18 = 6 volts to drop
* 500mA divided by 10 chains = 50mA
* R=V/I = 6 / 0.05 = 120Ω current limiting resistors.
* P=I²R = 0.05²×6 = 300mW dissipated from the resistors.

Instead all you need is an N-channel MOSFET as a low-side switch that can operate with that much current and not dissipate too much heat while switching. The more you derate the MOSFET the less heatsinking it would need.

A quick look on Digikey gave a possible match of [PSMN022-30PL](https://www.digikey.com/product-detail/en/nexperia-usa-inc/PSMN022-30PL,127/1727-5893-ND/2606361) - 30V, 30A, 27mΩ (typ) at 4.5V gate voltage.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/KQHep.png)

<!-- End schematic -->


body:
I am trying to read a SDM220 meter on my solar setup. I've been reading it using Modbus SCADA, so know it all works ok.
But I want to read it with my Arduino Mega 256. My problem is that when I run the code below the final value MtrKWh , is not float value. it's actual value is printed.
Here is a copy of the output.

17241 MtrKWh1 1129906176 MtrKWh1<<16 57737 MtrKWh2 1129963913 MtrKWh3 11299639.00 MtrKWh 2

the value '1129963913'       MtrKWh3,

if I turn it into Binary is
01000011010110011110000110001001,

if I convert this to binary using https://www.h-schmidt.net/FloatConverter/
it gives me the value

217.881,

the very value I expect. Am I missing some brackets somewhere?
So how do I get MtrKWh to print its float value?
I have left a lot of commented out bits to show the several things I have tried. Sorry if it appears messy, I will tidy it up once I solve this problem.
I'm sure it is something simple, but, I haven't been able to see it so far.
Any sugestions would be appreciated.

        // MtrV, MtrC, MtrW, MtrKWh
        //void AddressRegistry_0()
        result = sdm220_modbus.readInputRegisters(0x48, 2);
        //while (!result == 0) {
        // delay(10);
        // result = sdm220_modbus.readInputRegisters(0x156,4);
        //}
       if (result == sdm220_modbus.ku8MBSuccess)
       {
        // 1 Serial.println((node.getResponseBuffer(0x0D) + node.getResponseBuffer(0x0E) << 16)/100.0f);
        // 2 pvpower = ((long)node.getResponseBuffer(0x03) << 16 | node.getResponseBuffer(0x02)) / 100.0f;
        // 3 long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4;
        // 1 working ?? MtrKWh1 = (((long)sdm220_modbus.getResponseBuffer(0x0) + sdm220_modbus.getResponseBuffer(0x1) << 16)/6.f);
        // 2 working ?? MtrKWh1 = ((long)sdm220_modbus.getResponseBuffer(0x0) << 16 | sdm220_modbus.getResponseBuffer(0x1)) / 100.3f;
        // 3 working MtrKWh1 = (( sdm220_modbus.getResponseBuffer(0x0)  << 16) |  sdm220_modbus.getResponseBuffer(0x1))  / 16.3f;
        //
       // float MtrKWh0 =((float)(sdm220_modbus.getResponseBuffer( 0) << 16 | sdm220_modbus.getResponseBuffer( 1)));
        //      Serial.print(MtrKWh0);
        //    Serial.print(" MtrKWh0     ");

    signed long MtrKWh1 = sdm220_modbus.getResponseBuffer(0x0);
    Serial.print(" ");
    Serial.print(MtrKWh1);
    Serial.print(" MtrKWh1");

    MtrKWh1 = MtrKWh1 << 16;
    Serial.print(" ");
    Serial.print(MtrKWh1);
    Serial.print(" MtrKWh1<<16");

    word MtrKWh2 = sdm220_modbus.getResponseBuffer(0x1);
    Serial.print(" ");
    Serial.print(MtrKWh2);
    Serial.print(" MtrKWh2");

    signed long MtrKWh3 = MtrKWh1 | MtrKWh2;
    Serial.print(" ");
    Serial.print(MtrKWh3);
    Serial.print(" MtrKWh3");

    float (MtrKWh) = float (MtrKWh3) / 10000.0;
    Serial.print(" ");
    Serial.print(MtrKWh);
    Serial.print(" MtrKWh     ");

    //uint32_t x = 0x3f322e3f;
    //float y = *(float*)&x;
    //Serial.print (y, 6);
    // Serial.print(" MtrKWhxxx ");

       }
       else
       {
        rs485DataReceived = false;
        Serial.println("Fail sdm220_modbus.readInputRegisters(0x0, 1) ");
       }

title: float not a float

Answers: 2

body:
You need to convert the format by overlaying one type on top of the other, rather than casting from one type to another.

1000 as an integer cast to a floating point value is still 1000.

You have an example of how it can be done in comments:

    //float y = *(float*)&x;

However this method is called *type punning* and is frowned upon (there are compiler options that can prevent it being used).  Instead using a *union* is a better option:

    union ifloat {
        uint8_t bytes[4];
        float val;
    };

    void setup() {
        ifloat f;
        Serial.begin(115200);
        f.bytes[3] = 0x43;
        f.bytes[2] = 0x59;
        f.bytes[1] = 0xE1;
        f.bytes[0] = 0x89;
        Serial.println(f.val, 4);

    }

    void loop() {
    }

So you can get the byte order right your current numeric value of 1129963913 is 0x4359E189 in hexadecimal. Byte 3 is therefore the most significant byte and byte 0 the least significant. Note that it can change from system to system depending on the *endianness* of the chip.

How it works is quite simple. You have 4 bytes in memory, and the union just gives you different views of those 4 bytes.

You can either see them as four individual bytes (f.bytes[0-3]) or as a floating point value (f.val).

You can understand more about how the four bytes describe the floating point number by understanding more about the [IEEE 754 Single Precision Floating Point Format](https://en.wikipedia.org/wiki/Single-precision_floating-point_format).

----

You can achieve the same thing using `reinterpret_cast`, but that has to be done using *pointers*, not the values, which makes it a little more complex to understand:

    // Your incoming 32-bit value
    uint32_t l = 1129963913;

    // A pointer to the same memory with a different type
    float *f = reinterpret_cast<float *>(&l);

    // Print the *content* of the pointer interpreted as a float.
    Serial.println(*f, 3);

body:
OK. So I never got the reinterpret_cast, thing to work. Went with Majenko's solution.
This code goes above Setup

    // UNION, used to re-jig float
    union ifloat {
    uint8_t bytes[4];
    float val;
    };
    // END UNION
And this is the modified code, with all the comments and bug print statements removed.

      // MtrV, MtrC, MtrW, MtrKWh
     //void AddressRegistry_0()
     result = sdm220_modbus.readInputRegisters(0x48, 2);
     if (result == sdm220_modbus.ku8MBSuccess)
     {
    signed long MtrKWh1 = sdm220_modbus.getResponseBuffer(0x0);
    word MtrKWh2 = sdm220_modbus.getResponseBuffer(0x1);
    byte msb3 = MtrKWh1;
    byte msb4 = MtrKWh1 >> 8;
    byte msb1 = MtrKWh2;
    byte msb2 = MtrKWh2 >> 8;
    ifloat f;
    f.bytes[3] = msb4;
    f.bytes[2] = msb3;
    f.bytes[1] = msb2;
    f.bytes[0] = msb1;
    Serial.println(f.val,3 );
      }
     else
     {
    rs485DataReceived = false;
    Serial.println("Fail sdm220_modbus.readInputRegisters(0x0, 1) ");
     }

And it is giving me the right numbers!
Thanks for input to all who did, it helps some times to be show which door to walk through.
Majenko, if you have time, and inclination, it would really help my understanding if you could describe your code. I am using it, but not sure how it works,or what most of it is doing. If you have the time.


body:
I am new to Arduino and IoT. I plan to build a product that I will connect to an app and they have to be able to communicate from a very far distance (kilometers).

Bluetooth is not a good option then (because the distance is too far). So would Wifi work? I read something about a module called esp8266 that might be what I am searching for.

title: What is the best way/module to talk to an Arduino from far away (WIFI)?

Answers: 3

body: Esp8266 range is about 400m. So if you have your mobile within 400m then you may be able to communicate. But for long distance communication I would not prefer but if you have any Internet connection available nearby esp then you may be able to transmit your messages via it. Well for long distance communication  I would prefer you to use any GSM shield in which you need to plug in a sim card and it can be used upto when you have coverage in that area.

body:
The simplest option is to use GSM for the communication. Range isn't an issue, since point A isn't communicating with point B, instead point A and point B are both communicating via third party communication subsystem C which has a much greater coverage than anything you could build yourself.

I use GSM modules for communication with agricultural monitoring and control systems at remote locations. It works well, and you're pretty much guaranteed to have a signal.

For those times when GSM isn't a possibility (no signal, or the customer doesn't want the subscription cost) you really need *line of sight* between the two locations. Then you can use a highly directional antenna (e.g., parabolic dish or Yagi array) to extend any other suitable wireless communication signal over a long range (WiFi can reach tens of kilometres with parabolic dishes) and there are companies that specialise in that kind of equipment (such as [this one that claims 8 mile range](http://www.simplewifi.com/8-mile-antenna.html) - of course you need two of them, one for each end of the link).  Of course, with some skill and determination it's possible to get [incredibly long distances from WiFi](https://www.wired.com/2007/06/w_wifi_record_2/). Not for your average user though...

body:
**LoRa** is apparently the most popular [low-speed, low-power, wide-area network][1] at the moment.

Many people use LoRa for direct point-to-point links around a kilometer.
Other people use LoRa for "last mile" wireless links as part of a **LoRaWAN** to some gateway hard-wired to the internet, much like a Wifi access point -- except trading off data rates in order to get longer wireless range than WiFi.

details:

* "LoRa is de facto dominant" -- ["LoRaWAN across the globe: LoRa Internet of Things networks overview"][2]
* [LoRa range tests][3] using the RFM95 [Anarduino LoRa Modules][4], similar to the , [LoRa IoT Development Kit][5] (using a ["LoRa Bee"][6]), [RFM95W LoRa Module for Arduino][7], [RFM95W Breakout Board for LoRa][8], [RFM95 LoRa mikroBUS Module][9], etc.
* ["LoRa range experiments Urban test"][10] using the Microchip RN2483 module; I can't quite see which breakout board he's using -- I'm guessing it's one of the [Sodaq LoRabee RN2483][11], the [RN2483 LoRa Technology PICtail][12], the [Azzy RN2483 breakout board][13], the [Azzy LoRaWAN RN2483/RN2903 Breakout board][14] , etc.
* [The Vinduino][15] measures wind and soil moisture using an Arduino and reports back those measurements with a [Globalsat LM-210 LoRa module][16]
* "LoRaWAN ... Range: 2-5km (urban environment), 15km (suburban environment)" --
["11 Internet of Things (IoT) Protocols You Need to Know About"][17]
* [LoRaWAN Part 1: How to Get 15 km Wireless and 10-Year Battery Life for IoT][18]
* "low power wide area (LPWA) technologies have become popular. In various LPWA technologies, narrowband (NB)-IoT and long range (LoRa) are two leading technologies." -- ["A survey on LPWA technology: LoRa and NB-IoT"][19]
* "[The LoRa shield: an Open Source Arduino’s long-range communication module][20]" apparently uses the [Open-Electronics LoRa shield for Arduino - Mounted][21]
* ["Building your own private LoRa network"][22] mentions several different LoRa shields
* [The LoRa Alliance][23]
* [arduino-lmic][24]: the IBM LMIC (LoraMAC-in-C) library, slightly modified to run in the Arduino environment
* ["LoRa and Long Range Wireless IoT"][25]
* "The low data-rate (down to few bytes per second) and LoRa modulation lead to ... more than 22km (13.6 miles) in LOS links and up to 2km (1.2miles) in NLOS links in urban environment (going through buildings)." -- ["Extreme Range Links: LoRa 868 / 900MHz SX1272 LoRa module for Arduino Waspmote and Raspberry Pi"][26] tested a [SX1272 LoRa module][27] on a Multiprotocol Radio Shield on an Arduino Uno and links to a few other LoRa modules / [LoRaWAN kits][28].

  [1]: https://en.wikipedia.org/wiki/LPWAN
  [2]: https://www.i-scoop.eu/internet-of-things-guide/iot-network-lora-lorawan/
  [3]: http://forum.anarduino.com/posts/list/46.page
  [4]: http://www.anarduino.com/?cid=24
  [5]: https://www.tindie.com/products/edwin/lora-iot-development-kit/
  [6]: https://www.tindie.com/products/edwin/lora-bee/
  [7]: https://www.tindie.com/products/blkbox/rfm95w-915mhz-module-for-arduino/
  [8]: https://www.tindie.com/products/arduinopraxis/rfm95w-breakout-board-for-lora-applications/
  [9]: https://www.tindie.com/products/CascoLogix/rfm95-lora-mikrobus-module/
  [10]: http://www.hexnut.net/2016/02/lora-range-experiments-urban-test.html
  [11]: https://shop.sodaq.com/en/lorabee-rn2483.html
  [12]: https://www.microchipdirect.com/productsearch.aspx?Keywords=RN-2483-PICTAIL
  [13]: https://www.tindie.com/products/DrAzzy/rn2483-breakout-bare-board/
  [14]: https://www.tindie.com/products/DrAzzy/lorawan-rn2483rn2903-breakout-board-assembled/
  [15]: https://hackaday.io/project/6444-vinduino-a-wine-growers-water-saving-project
  [16]: https://hackaday.io/project/6444-vinduino-a-wine-growers-water-saving-project/log/39541-lora-network-module-review
  [17]: https://www.rs-online.com/designspark/eleven-internet-of-things-iot-protocols-you-need-to-know-about
  [18]: https://www.digikey.com/en/articles/techzone/2016/nov/lorawan-part-1-15-km-wireless-10-year-battery-life-iot
  [19]: http://www.sciencedirect.com/science/article/pii/S2405959517300061
  [20]: https://www.open-electronics.org/the-lora-shield-an-open-source-arduinos-long-range-communication-module/
  [21]: https://store.open-electronics.org/index.php?_route_=FT1190M
  [22]: https://docs.mbed.com/docs/lora-with-mbed/en/latest/intro-to-lora/
  [23]: https://www.lora-alliance.org/
  [24]: https://github.com/matthijskooijman/arduino-lmic
  [25]: https://www.postscapes.com/long-range-wireless-iot-protocol-lora/
  [26]: https://www.cooking-hacks.com/documentation/tutorials/extreme-range-lora-sx1272-module-shield-arduino-raspberry-pi-intel-galileo/
  [27]: https://www.cooking-hacks.com/sx1272-lora-module-for-arduino-raspberry-pi-intel-galileo-868-mhz
  [28]: https://www.cooking-hacks.com/shop/wireless/lorawan


body:
I'm working on a webserver on ESP32 in Arduino IDE and would like to load an html-file. Tried to use SPIFFS.open from the library FS.h from [github][1].
Errormessage says SPIFFS was not declared in this scope. (As far as I can see, there's no bracket in the wrong place.)

I did not find any example for ESP32 and FS.h and desperately hope for some help. Thanks in advance.

Here is my code:

    #include "FS.h"
    #include "WiFi.h"

/*Wifi Access data*/
const char* ssid_ap = "AccessPoint";
const char* password_ap = "12345678";

const char * ssid_sta     = "<SSID>";
const char * password_sta = "<Password>";

/* set global variables */
byte WiFiMode = 0;  // WIFI_STA = 1 = Workstation  WIFI_AP = 2  = Accesspoint
int request_counter;
String sHTML;
String sHTMLRequest;

/* Create instance of server on Port 80 */
WiFiServer server(80);
WiFiClient client;

/*
 * ******SETUP*******************************************************
 */
void setup() {

/*initialize GPIO*/

/*start serial communication */
  Serial.begin(115200);
  SPIFFS.format();
  Serial.println("Spiffs formatted");

/* start WiFi as workstation (STA), if not possible
   start as Acess Point
   initialize server */
  WiFi_Start_STA();
  if (WiFiMode == 0) WiFi_Start_AP();
}

/*
 * **LOOP*************************************************************
 */
void loop() {

  /* Check if a client has connected */
  client = server.available();
  if (!client)
  {
    return;
  }

 /*Wait for the client to send data */
  Serial.println("neuer Client verbunden");
  /*Count Aufruf der Seite: */
  request_counter ++;
  unsigned long clTimeout = millis()+250;
  while(!client.available() && (millis()<clTimeout) )
  {
    delay(1);
  }
  if(millis()>clTimeout)
  {
    Serial.println("time-out bei Client-Verbindung!");
    return;
  }

/****** open html files  *******/
 SPIFFS.begin();
 File f = SPIFFS.open("/home.txt", "r");
    if (!f) {
    Serial.println("file open failed");
    }
    f.close();

  }

/**********************************************************************
 *
 **************** FUNCTIONS ********************************************
 *
 **********************************************************************
 */

/*
 * Fct tries to start WiFi in workstation mode,
 * if not possible sets WiFiMode=AP
 * starts server
 */
void WiFi_Start_STA() {
  unsigned long timeout;

  WiFi.mode(WIFI_STA);   //  Try to start WiFi as Workstation

  WiFi.begin(ssid_sta, password_sta);
  timeout = millis() + 12000L;
  while (WiFi.status() != WL_CONNECTED && millis() < timeout) {
  delay(10);
  }

  if (WiFi.status() == WL_CONNECTED) {
    server.begin();
    WiFiMode = WIFI_STA;

  Serial.print("Verbunden mit IP - Addresse: ");
    for (int i = 0; i < 3; i++) {
      Serial.print( WiFi.localIP()[i]);
      Serial.print(".");
    }
    Serial.println(WiFi.localIP()[3]);

  }
  else {
    WiFi.mode(WIFI_OFF);

    Serial.println("WLAN-Verbindungsaufbau fehlgeschlagen");
    }
}

/*
 *starts WiFi in AP-mode
 *starts server
 */
void WiFi_Start_AP() {
  WiFi.mode(WIFI_AP);   // Access Point mode
  WiFi.softAP(ssid_ap, password_ap);
  server.begin();       // start server
  IPAddress ApIP = WiFi.softAPIP();   //read IP of Access Point
  WiFiMode = WIFI_AP;

  Serial.print("ESP-Netzwerk: ");
  Serial.print(ssid_ap);
  Serial.print(" aufgebaut. ");
  Serial.print( " IP-Addresse: ");
  Serial.println(ApIP);
}

  [1]: https://github.com/espressif/arduino-esp32/tree/master/libraries/FS

title: ESP32 in Arduino-IDE with FS.h and SPIFFS

Answers: 1

body:
The answer is belated but since the question is still open...

The code does not include spiffs library. The line below should fix the problem.Note it should be below the the include statement for FS

    include <SPIFFS.h>

So the code should look like

    #include "FS.h"
    #include "WiFi.h"
    #include "SPIFFS.h"


body:
I have some devices that, when I plug in, will display a unique name, usually a serial number, as opposed to "COM #" is there any way I can have my Arduino Uno (or Mega) give itself a different name in my program's set up structure?

Edit: My purpose here is that I'm writing a program on the computer side that needs to find the Arduino among multiple possible COM ports. I'm deploying this program over multiple computers that I don't have admin access to so changing the registry is likely a non-starter.

Right now, I'm going through each port and sending a *`idn?\n` (which my program responds to with a specific string). For another device I have, I can search the possible connections for a port named [device serial number] and test that one first.

title: Programmatically Change Arduino Com Port Name

Answers: 2

body:
On Windows you can change the "Friendly names" assigned to devices and COM ports are devices.  The process is basically open the device manager, open the device properties, find the 'Device Key' and then locate that in the registry and change the 'Friendly Name' value.

See this page for more details:
https://www.eightforums.com/customization/15321-tutorial-how-change-device-names-device-manager.html

body:
1.  If you read [this](https://arduino.stackexchange.com/questions/11823/can-i-change-the-usb-device-name-of-arduino) So it says:

   You'll have to change the software on the Arduino USB chip itself,
    and you may need to modify the drivers for the Arduino USB interface
    on the computer side. It's not trivial, and probably not worth it.

Then according to this you need to toggle and tinker with the Driver software

2. Wait that means it is not the correct answer. So according to your plan you need to maybe toggle with IDE that is instead of manually changing the ports you want the software to identify on its own. So for that purpose you have to tweak with Arduino board bootloader, and say it send a message to the Arduino IDE on startup . After that you have to tweak with Arduino ide source codes and then tweak it to Search for that message and then it reads down the address that is its COM


body: So I'm making a Robot for my AP Comp Sci Class, and I'm borrowing an Arduino, as well as a Pi from the school. What I plan to do is have my Pi output from the normal GPIO pins and into the Arduino's digital inputs to "Tell" the Arduino what servos to run. The reason I'm doing it this way is so I don't have to screw with interfacing and all that crap. Is it safe for the Arduino? If so, what would I need for resistors and such?

title: RasPi GPIO into Arduino Digital Inputs

Answers: 1

body:
I think you are talking about writing to a GPIO and that being received by the Arduino if so the Pi is 3.3v and the Arduino is 5V so you will need a "Level Shifter" to boost the voltage to 5V so the Arduino can read the signals.

Other than that there is no problem with doing what you are doing, apart from its a lazy solution and you won't score very highly.  I know you don't want to mess with protocols but if you can use I2C from the Pi then use that to send messages to the Arduino.  Your protocol could be as simple as 1 byte saying which pin you want to light up, you'll get better marks.

Edit

To use I2C is really quite simple because someone has done almost all the work for you in Wire.h, so just include that file and then to send a byteits simply a case of:

    Wire.beginTransmission(device_address);
    Wire.write(data_byte);
    Wire.endTransmission();

Reading data sheets for devices makes it look a lot harder with all the transmission sequence diagrams, but you don't need to worry about that its all done for you.  The hardest bit to remember is the pull up resistors on the data lines.

Have a look at these links for more information:

 - http://tronixstuff.com/2010/10/20/tutorial-arduino-and-the-i2c-bus/
 - http://howtomechatronics.com/tutorials/arduino/how-i2c-communication-works-and-how-to-use-it-with-arduino/
 - https://www.arduino.cc/en/Tutorial/MasterReader


body:
I'm guessing that the answer to this is "no," but I'm curious if there is any way to save writing some code by specifying a function to do the opposite of whatever another function does. For example the inverse of:

    int FW (int in)
    {
      int out=2+in;
      Return out
    }

would be

    int RV (int in)
    {
      int out=in-2;
      Return out
    }

However, would there be any way to call the inverse of `FW()` if it was a more complicated function that still had one and only one input for each output?

title: Any good way to inverse a function?

Answers: 1

body:
No. A function does what it does and that is all. No other function can know what some other function does.

You could write a function that does different things depending on what parameters you pass to it, but that's the closest you can get, and is pretty pointless when you can just write different functions anyway.


body:
I've seen * used with arrays in some programs but not in others. [The page on arrays](https://www.arduino.cc/en/reference/array) doesn't mention it at all, but I often see it near functions when values are being passed.

Where would I find more information on this?

title: What is the meaning of [type]* for arrays?

Answers: 1

body:
You are asking about Pointers -
 https://www.tutorialspoint.com/cprogramming/c_pointers.htm.


body:
I'm a bit new to this and I have the following function that I'm having trouble getting it to compile. The intent is to create a message to write out to a software serial port. Inputs are two int values of Function address and the data passed to the device while the output is a series of char characters

    void Create_Message(int Address, int Data)
    {
      byte S1Add = 1;
      byte FuCode = 2;
      byte AddHi = Address>>8;
      byte AddLo = Address;
      byte DatHi = Data>>8;
      byte DatLo = Data;
      byte AdDa[] = {AddHi,AddLo,DatHi,DatLo};
      unsigned int crc=CRC(AdDa,4);
      byte CrcHi = crc >> 8;
      byte CRCLo = crc & 0xFF;
     /*U8 Slave Address, U8, Function Code, U16 Address, U16 Data, U16 CRC
     * to
     *[U8 Address Split High, U8 Address Split Low, U8 Data Split High, U8 Data Split Low, U8 Function Code]
     */
     unsigned char cmd[]={S1Add,FuCode,AddHi,AddLo,DatHi,DatLo,CrcHi,CRCLo};

      digitalWrite(SSerialTxControl, RS485Transmit);  // Enable RS485 Transmit
      for (int i=0; i< clen; i++)
      {
        RS485Serial.write(cmd[i]);   // Send string someplace
        Serial.write(cmd[i]); //echo back
      }
      digitalWrite(SSerialTxControl, RS485Receive);  // Disable RS485 Transmit
    }

    byte CRC(byte AdDa, int Size )
    {
    unsigned int crc16 = 0xFFFF;
    int pos = 0;
    int i = 0;

    /*Write CRC*/
      for (pos = 0; pos < Size; pos++) {
        crc16 ^= AdDa[pos];          // XOR byte into least sig. byte of crc

        for (i = 8; i != 0; i--) {    // Loop over each bit
          if ((crc16 & 0x0001) != 0) {      // If the LSB is set
            crc16 >>= 1;                    // Shift right and XOR 0xA001
            crc16 ^= 0xA001;
          }
          else                            // Else LSB is not set
            crc16 >>= 1;                    // Just shift right
        }
      }
      /*Note, this number has low and high bytes swapped,
      so use it accordingly (or swap bytes)*/
      byte crc[]={crc16>>8,crc16};
      return crc;
    }
Any help with optomizition would also be greatly appreciated :)

title: Create an a message from two inputs[Programming Help]

Answers: 1

body:
If you want help with optimisation then "Code Review" would be the better forum.

Its very difficult to optimise code that's hard to read.  You have used an inconsistent formatting style (which might be because of the post but your failure to fix it indicates a lack of interest in the answers.

You passed all you function arguments by value, you should pass them by constant reference.

You are doing a number of implicit casts, because you have mismatched types.

You are sending a byte to serial.write, what happens if the value is outside of the printable range, it would be better to print this as a hex number.

I assume someone has already pointed out CRC should return a byte*.

As for the algorithm, the code isn't readable enough to comment on that.