body:
i have a project to control a relay by sms and call by arduino and sim800L gsm modem
and i need to modify the code below to by adding command to reboot or reset the modem ever hour
i mean delete all sms and call history and reboot the modem because the modem is always on for long time and the modem after few days of operation becomes not responsive
any one can help me and solve the problem

```

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10,11);  // (Rx,Tx  > Tx,Rx)

char incomingByte;
String inputString;
int relay = 4; // Output for Relay Control
int LEDG = 8;
int buzzer = 5;
int LED = 6;
int buttonPin = 2;
int buttonState = 0;
void setup()
{
      pinMode(relay, OUTPUT);
      pinMode(buzzer, OUTPUT);
      pinMode(LED , OUTPUT);
        pinMode(LEDG , OUTPUT);
      pinMode(buttonPin, INPUT);
      digitalWrite(relay, LOW); // Initial state of the relay
       digitalWrite(buzzer, LOW);
        digitalWrite(LED, LOW);
        digitalWrite(LEDG, LOW);

      Serial.begin(9600);
      mySerial.begin(9600);

     while(!mySerial.available()){
        mySerial.println("AT");
        delay(1000);
        Serial.println("Connecting...");
        }
      Serial.println("Connected!");
      delay(30000);

      mySerial.println("AT+CMGF=1");  //Set SMS to Text Mode

      delay(1000);

      mySerial.println("AT+CNMI=1,2,0,0,0");  //Procedure to handle newly arrived messages(command name in text: new message indications to TE)
      delay(1000);
      mySerial.println("AT+CMGL=\"REC UNREAD\""); // Read Unread Messages
      delay(1000);
       mySerial.println("AT+CLIP=1");
        delay(1000);
      digitalWrite( LEDG , HIGH);
     }

void loop()
{

 m:
  if(mySerial.available()> 0){
      delay(100);

    inputString = mySerial.readString();
    Serial.println(inputString);

     if(inputString.indexOf("0000000") > 0)
      {
             mySerial.println("ATH");
             delay(250);
            digitalWrite(relay, HIGH);
            delay(250);
            digitalWrite( buzzer , HIGH);
            delay(250);
            digitalWrite( LED , HIGH);
            delay(300);
            digitalWrite( relay , LOW);

            while(1){
               inputString = mySerial.readString();
                    Serial.println(inputString);
                  if (inputString.indexOf("00000000")>0 && inputString.indexOf("OFF") > -1){

                     digitalWrite( buzzer , LOW);
                     digitalWrite( LED , LOW);
                     goto m;
                  }
            buttonState = digitalRead(buttonPin);
           if (buttonState == HIGH) {
                    digitalWrite( buzzer , LOW);
                     digitalWrite( LED , LOW);
                   goto m ;
                   }
                   }

          }

    if(inputString.indexOf("000000") >0 && inputString.indexOf("1") > -1 )
      {

            digitalWrite(relay, HIGH);
            delay(250);
            digitalWrite( buzzer , HIGH);
            delay(250);
            digitalWrite( LED , HIGH);
            delay(300);
            digitalWrite( relay , LOW);
               while(1){
                   inputString = mySerial.readString();
                    Serial.println(inputString);
                  if (inputString.indexOf("00000000")>0 && inputString.indexOf("OFF") > -1){

                     digitalWrite( buzzer , LOW);
                     digitalWrite( LED , LOW);
                     goto m;
                  }

           buttonState = digitalRead(buttonPin);
           if (buttonState == HIGH) {
                    digitalWrite( buzzer , LOW);
                      digitalWrite( LED , LOW);

                       goto m;
                   }

                   }

          }

  }
}

```

title: sim800l gsm module reboot command

Answers: 0


body:
I have an esp8266-12e that I want to activate the reset side of a latching relay.  The problem is that the 12e only puts out 12mA/pin and the relay needs more than that.  I am using a transistor on the set side from a rf antenna signal.  I only have one 3.3v power source.  Is there a way to have two pins go HIGH at the exact same time and be connected to the reset side of the relay so there is enough current?  Would this work, would it hurt anything, and how would I write the code for it and how would I wire it up?

I have tried the code where one pin is written HIGH right after the other like this

```
digitalWrite (5,HIGH);
digital Write (6,HIGH);
```
but I think pin 5 goes of before pin 6.
Any way to get them to go off at the same time?

Thanks for the help

title: activate a relay with two esp8266 -12e pins

Answers: 1

body:
That is not a good idea.

Isolating the relay from the IO pin is not just about the current limit of an IO pin, it's also about preventing back-EMF spikes from the relay coil(s) from damaging the delicate internals of the chip.

Instead you *must* at least use a transistor and a back-EMF protecting diode.

However - if you *did* want to theoretically have two pins *safely* controlled to provide double the current (though I stress again, do *not* do this for driving a relay), it is possible.

But it's not straight forward.

It's not possible on the ESP8266 to use port manipulation to make two pins change state at the same time. However it is possible to go *via a third state* that makes it safe.

**Note: this will only be "safe" for IO pins that do not do strange things at bootup, and many of the pins on the ESP8266 do strange things.**

IO pins actually have three states, not two:

* High
* Low
* High Impedance

The latter is the state the pin is in when in INPUT mode. And we can use that to our advantage.

When in High Impedance mode it's like the pin is disconnected.  So we could:

1. Make sure both pins are in INPUT mode
2. Switch one pin to OUTPUT and set it to the desired state
3. Switch it back to INPUT mode (keeping the desired state latched)
4. Switch the other pin to OUTPUT and set it to the desired state
5. Set the first pin back to OUTPUT mode again.

This can be slightly compressed as we don't really need to set both pins to INPUT at the start, only one.  So here's some code that might do it:

```
void digitalDoubleWrite(int pina, int pinb, bool level) {
    pinMode(pina, INPUT);
    pinMode(pinb, OUTPUT);
    digitalWrite(pinb, level);
    pinMode(pinb, INPUT);
    pinMode(pina, OUTPUT);
    digitalWrite(pina, level);
    pinMode(pinb, OUTPUT);
}
```

You might ask why we'd want to switch to OUTPUT just to latch a level into the pin. Well, that's because of a quirk of the Arduino API. A historical artefact that is lingering in there to this day:

* `digitalWrite()` on a pin set to INPUT mode was used to turn the internal pullup resistor on and off

It's actually how the AVR's IO ports control the pullup resistors internally, and that has most often been copied in software for other chips to maintain backward compatibility with old code. So as a result we have to switch to OUTPUT mode so that the API code knows that we mean to set the output latch state and not the pullup resistor state.


body:
I have ldr module with 4 pins
 1. Vin
 2. Gnd
 3. AO
 4. DO

I want to know how can i take advantage of DO suppose i want to turn on lcd display when light falls on the ldr sensor!

[![enter image description here][1]][1]
I have noticed when light falls on ldr sensor the Green  led with DO written next to it lights up.

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

title: How to use DO pin on ldr module?

Answers: 1

body:
The DO pin gives a Digital Output that is HIGH when the light falling on the LDR is above a threshold, and LOW when it's below a threshold. Just connect it to a digital input pin and read that pin with `digitalRead()`.

You can change the threshold by adjusting the small blue trimpot.


body:
I am using the ATMega32u4 to generate a pulse at 1 kHz. I am using Timer 3, which is a 16-bit timer and using a prescaler of 1, so I have a 0.0625uS resolution. The good news is that this is working, I can control the frequency and pulse length of the square wave. The issue is that I noticed the pulse always seems to be 1uS off.

If I set a period of 1000uS, and a pulse of 500uS, the oscilloscope shows a period of 1001uS and a pulse of 501uS.

If I set a period of 100uS, and pulse of 10uS, the oscilloscope shows a period of 101uS, and a pulse of 11uS.

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

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

If the Timer had an error percentage, then both the period and pulse should be off by the same percentage, but there are always off by the same 1uS length. I assume I am doing something wrong, so I have posted my code below.

    const int pin1 = 4;

    void setup() {
      //Set pin to output
      pinMode(pin1, OUTPUT);

      // Reset Timer 3 Control Register to 0
      TCCR3A = 0;

      // Set prescaler to 1
      TCCR3B &= ~(1 << CS32); //0
      TCCR3B &= ~(1 << CS31); //0
      TCCR3B |= (1 << CS30);  //1

      //Reset Timer 3 and set compare value
      TCNT3 = 0;

      // Enable Timer 3 compare interrupt A and B
      TIMSK3 |= (1 << OCIE3B);
      TIMSK3 |= (1 << OCIE3A);

      //Enable global interrupts
      sei();

      //Set Refresh Rate
      OCR3A = 1000;
      OCR3B = 100 / 0.0625;
    }

    void loop() {
      delay(100);
    }

    ISR(TIMER3_COMPA_vect) {
      PORTD &= ~_BV(pin1); //LOW
      OCR3A = 160;
    }

    ISR(TIMER3_COMPB_vect) {
      TCNT3 = 0;
      PORTD |= _BV(pin1); //HIGH
    }

  [1]: https://i.stack.imgur.com/sWAcq.png
  [2]: https://i.stack.imgur.com/l1HFG.png

title: Timer Accuracy Always off by 1uS

Answers: 1

body:
The problem is here:

```c++
ISR(TIMER3_COMPB_vect) {
  TCNT3 = 0;
  ...
```

If you want to get anything that vaguely looks like accurate timings,
you should **never** reset the timer. The MCU needs time to process an
interrupt: it has to save the program counter to the stack, load the
address of the interrupt vector, execute it (it's typically a jump),
save all the registers it needs to the stack, and only then can it start
executing the code you wrote in the ISR. From your experiment, it looks
like all this process takes about 1 µs. But don't take this delay
for granted: from time to time the interrupt will fire while the MCU is
processing another interrupt, and this will increase the latency.

You have two options:

1. Update the compare registers in order to program the next interrupts
   some time in the future. In this case, the COMPB ISR would do
   `OCR3A = OCR3B + 160; OCR3B += 1600;`. Do not worry about the
   overflows: they do the Right Thing.

2. Let the timer reset itself to zero: it will then do so without
   loosing a single cycle. See the CTC and fast PWM modes of the timer.

For your specific use case, PWM seems like the obvious choice. Not only
will the timer handle the resetting itself, it can also generate the
output signal without requiring you to write any ISR. Beware that in
this case the period of the signal is whatever you load in corresponding
compare register _plus one_, and the duration of the pulse is another
compare register _plus one_.

As a side note:

```c++
  // Reset Timer 3 Control Register to 0
  TCCR3A = 0;
```

I would also reset `TCCR3B`. The Arduino core configures both registers
for it's own purposes, so it would be safer to clear them both.


body:
i am trying to interface pc8563 with arduino uno . I have small doubt related to RTC slave address reading

RTC datasheet says page no 14
where device slave address is A2 for write and Read A3
i would like to know how A2 /A3

Example code from website device id mentioned as 0X51

**My question how to config exact slave address ??**

    #include "Wire.h"
    #define PCF8563address 0x51

    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    String days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

    byte bcdToDec(byte value)
    {
      return ((value / 16) * 10 + value % 16);
    }

    byte decToBcd(byte value){
      return (value / 10 * 16 + value % 10);
    }

    void setPCF8563()
    // this sets the time and date to the PCF8563
    {
      Wire.beginTransmission(PCF8563address);
      Wire.write(0x02);
      Wire.write(decToBcd(second));
      Wire.write(decToBcd(minute));
      Wire.write(decToBcd(hour));
      Wire.write(decToBcd(dayOfMonth));
      Wire.write(decToBcd(dayOfWeek));
      Wire.write(decToBcd(month));
      Wire.write(decToBcd(year));
      Wire.endTransmission();
    }

    void readPCF8563()
    // this gets the time and date from the PCF8563
    {
      Wire.beginTransmission(PCF8563address);
      Wire.write(0x02);
      Wire.endTransmission();
      Wire.requestFrom(PCF8563address, 7);
      second     = bcdToDec(Wire.read() & B01111111); // remove VL error bit
      minute     = bcdToDec(Wire.read() & B01111111); // remove unwanted bits from MSB
      hour       = bcdToDec(Wire.read() & B00111111);
      dayOfMonth = bcdToDec(Wire.read() & B00111111);
      dayOfWeek  = bcdToDec(Wire.read() & B00000111);
      month      = bcdToDec(Wire.read() & B00011111);  // remove century bit, 1999 is over
      year       = bcdToDec(Wire.read());
    }

    void setup()
    {
      Wire.begin();
      Serial.begin(9600);
      // change the following to set your initial time
      second = 0;
      minute = 28;
      hour = 9;
      dayOfWeek = 2;
      dayOfMonth = 13;
      month = 8;
      year = 13;
      // comment out the next line and upload again to set and keep the time from resetting every reset
      setPCF8563();
    }

    void loop()
    {
      readPCF8563();
      Serial.print(days[dayOfWeek]);
      Serial.print(" ");
      Serial.print(dayOfMonth, DEC);
      Serial.print("/");
      Serial.print(month, DEC);
      Serial.print("/20");
      Serial.print(year, DEC);
      Serial.print(" - ");
      Serial.print(hour, DEC);
      Serial.print(":");
      if (minute < 10)
      {
        Serial.print("0");
      }
      Serial.print(minute, DEC);
      Serial.print(":");
      if (second < 10)
      {
        Serial.print("0");
      }
      Serial.println(second, DEC);
      delay(1000);
    }

[RTC datasheet][1]

  [1]: https://www.nxp.com/docs/en/data-sheet/PCF8563.pdf

title: PC8563 Arduino interface

Answers: 1

body:
Normal I2C addresses are 7-bit long. On the first frame of an I2C
transaction, the master sends an 8-bit byte containing the address of
the slave followed by a bit specifying whether this is a read or a write
operation. Some people tend to call “address” the whole 8-bit frame,
which causes confusion. Because of this, we end up having three flavors
of I2C addresses:

 * the 7-bit address, which is the real device address
 * the 8-bit “write address”, which is the address followed by a 0
   meaning “write operation”
 * the 8-bit “read address”, which is the address followed by a 1
   meaning “read operation”

For your RTC, the 3 addresses are the following, in hex and binary:

    7-bit = 0x51 = 0b1010001
    write = 0xA2 = 0b10100010
    read  = 0xA3 = 0b10100011

The Arduino Wire library expects the 7-bit address.


body: I used some firmware I found online to turn the UNO into an emulated HID device. The Arduino is no longer connected to a Serial COM port so I can't send serial data from my computer to the device. Is there a way that the Arduino can receive data from the computer in order to drive a function while in the HID emulated state?

title: HID communication between Arduino Uno and computer

Answers: 1

body: You could use a second USB on the PC and use Hardware Serial to transmit commands. (Either via a second Arduino or a FTDI adapter)<br> But be aware that at least the [firmware I use](https://github.com/NicoHood/HID) and the controller programs are very sensitive to being disturbed in the loop. So you should have a good understanding of timers, interupts and non blocking code.


body:
This code runs without issues, scoped and seen from serial output:
```
#include <Wire.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Wire.begin();
  Wire.onReceive(receiveEvent);

  while (!Serial);
}

void loop()
{
  Serial.println("1");
  Wire.beginTransmission(8);
  Serial.println("2");
  Wire.write(0x1);
  Serial.println("3");
  delay(100);
  Wire.endTransmission();
  delay(100);
  Serial.println("4");
  delay(500);
}

void receiveEvent(int howmany)
{
  delay(100);
}
```

This one hangs on Wire.endtransmission():

```
#include <Wire.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Wire.begin(10);
  Wire.onReceive(receiveEvent);

  while (!Serial);
}

void loop()
{
  Serial.println("1");
  Wire.beginTransmission(8);
  Serial.println("2");
  Wire.write(0x1);
  Serial.println("3");
  delay(100);
  Wire.endTransmission();
  delay(100);
  Serial.println("4");
  delay(500);
}

void receiveEvent(int howmany)
{
  delay(100);
}
```

The problem starts as soon as I assign an address in Wire.begin(). As I understand, a slave is also allowed to send data and temporarily becoming a master when addressing another device.

title: Wire.endTransmission() hangs, but only, if wire.begin(); is called with an address (MKR WiFi 1010)

Answers: 2

body:
> I want to push data from the slaves to the master immediately when they receive said data.

So that means, that each slaves becomes master directly after it has received data from the MKR. This is still a multi-master setup, even while you are avoiding collisions through a fixed protocol. The `Wire` library does not support multi-master.

But I also don't understand, why you would need this. Your protocol does this: The MKR sends data to a slave (triggering it and maybe also sending some commands). Then the slave should send data back to the master. Then the transmission ends. This is normally done in I2C with just one master. The master does a master write (via `Wire.endTransmission()` and sends some command data to the slave. The slave will prepare the data, that the master requested, in it's buffer. Then the master will start a master read (via `Wire.requestFrom()`) which reads the data from the slave.

So you don't need a multi-master setup for this. It does exactly, what you described, but with only one master.

body:
While the wire library supports multi-master for AVR, it doesn't for ATSAMD.

Temporary promotion to master is disabled when given a slave address, so the program will hang on wire.endTransmission().


body:
I am working on a project where i need to store as fast I can following :

1 - Acceleration on X

2 - Acceleration on Y

3 - Acceleration on Z

4 - timestamp

5 - A value from some other sensor

Because I need to get these as fast as I can I am thinking to not do any calculation while acquire values and just store them for 30 -60 seconds and then when the "test" is complete to compute calculations.
My question is if will be better to create 5 arrays and put these values there or create a matrix and store values there.
I need these values to be stored like they are "connected"
e.g. on reading 1 i get 5 values and put them on array[0] , then on reading 1 and so on
Also an important thing to mention, this will run on a esp32.

Thank you

title: 5 arrays or one matrix?

Answers: 1

body:
I fully agree with Edgar Bonet.

My opinion is keeping a 'matrix' is better, or actually one array (of structs), where each array elements stores all information for one measurement (which is stored inside one struct). This has some benefits:

- Data of one measurement is consecutive in memory, so you can easily transfer it (to some external memory or sending it). It's exact one struct (and you can use `sizeof(struct_item)` to know how many bytes you have to transfer.

- It's good practice in general to keep information together, creating 5 always-equal length arrays seems strange.
- If for some reason you want to make a single array dynamic or change it to a ring buffer for example, you can easily add/remove items (instead of dynamically changing 5 arrays).
- Locality of change (see comments of Kwasmich/DuncanC)

There is also one benefit about having separate arrays (where each array stores one type of information, like an acceleration or timestamp: when you have a function (especially in another class) that only needs one of them, you can specifically send that array (or pointer/reference), so the other information is hidden from that function.


body:
Can we use the vin pin of the lolin v3 nodeMCU as a 5V supply. If yes, i checked mine with a multimeter. At max, it gives a voltage of 2V. Is my pin blown out? Also, can use the VU pin as a 5V supply? Will using it cause any problems to my laptop's USB port? Can somebody help me out?

I need 5V to drive a relay using the v3

title: Vin & VU pins of NodeMCU V3

Answers: 1

body:
On the NodeMCU “v3” (and only on the v3) there’s a pin called VU (Vusb) that is connected to the +5V on the USB bus of the NodeMCU socket. This pin can be used to feed external components when it’s connected to USB, within the limits of the USB power supply it’s connected to.

The Vin pin (which is available on all NodeMCUs (and not just the v3) is a +5V power *input* which can be used to power the NodeMCU if it is not connected to USB. It can not be used as an output and it needs a stabilized supply.


body:
I need to play an intro file and one of 50 different files after it in order each time the switch is pressed, with a short delay between the intro and next file.

For example let's say the intro is called "intro.wav," and each of the 50 other sound files are just named 01.wav-50.wav.

The logic would be:

```
TRIGGER
PLAY intro.wav
250ms DELAY
PLAY 01.wav
END
```

```
TRIGGER
PLAY intro.wav
250ms DELAY
PLAY 02.wav
END
```

```
TRIGGER
PLAY intro.wav
250ms DELAY
PLAY 03.wav
END
```
and so on, until all 50 files are played, then start over.

The messages are going to be a curated group of words. I'm not sure what the intro will be yet, but it will just be something like:

intro.wav = "The word of the day is"

01.wav = "help"

02.wav = "climb"

03.wav = "think"

I'm looking for some guidance on where to start with this, if an Arduino product would be suitable, and if so, which one.  I've worked with the Adafruit Audio FX Sound Board before, and that can *almost* do what I need it to do, but not by itself. It looks like I'll need an Arduino of some kind to accomplish this, so I went ahead ordered an Uno.

I'm not married to the idea of having the intro and word files separate either. If I need to create all 50 files to contain the intro and the word, that would be fine, as long as each one is triggered sequentially.

In that scenario, 01.wav could be "The word of the day is ... help" and the button would basically be the "next track" command.  I don't really have a problem with doing that because I'm all about keeping things simple and I don't think I'd run out of space, but I think it would be less time consuming to just dump all the individual word files onto the card.

The important thing is that the track(s) would play once, then stop, and when the button is pressed again, the next one plays.

title: With the press of a button, I need to play an intro sound file, then one of 50 other sounds in order, each time a button is pressed

Answers: 1

body:
You will find all the code and thelibrary you need on the [Adafruit learn center](https://learn.adafruit.com/adafruit-audio-fx-sound-board/serial-audio-control).<br>
For such a project I would use a DF-robot (clone) MP3 player (~4$), an Uno, a speaker and an SD card. The [library for the player](https://github.com/DFRobot/DFRobotDFPlayerMini) includes examples to get you started and the sound project you plan is possible even with low programming skills. Look at the example codes provided and start to program.


body:
I've got two arrays, defined as:

    uint8_t array1[10];
    uint8_t array2[10];

I'd like to swap the arrays (actually the pointers to each array) using code like this:

    uint8_t *tmp = array1;
    array1 = array2;
    array2 = tmp;

However, I keep getting errors like:

    invalid array assignment

for the last two lines. I don't recall this being such a problem in traditional C++. I've tried all sorts of casting to no avail. Is there something I'm missing?

I can get the code to run properly if I switch the declarations for the arrays to use `new` and have them just be more-or-less pointers rather than arrays, but I'd rather not have to do that:

    uint8_t *array1 = new uint8_t[10];
    uint8_t *array2 = new uint8_t[10];

Code is running on an ARM-based SAMD51 (Cortex M4 processor).

Thanks for any tips!

title: Swap two arrays (using pointers, not copy)

Answers: 1

body:
Figured it out. Though using `new` works, I wanted to keep the buffers out of the heap. The following declarations work with the swap code:

    uint8_t a1[10];
    uint8_t a2[10];
    uint8_t *array1 = a1;
    uint8_t *array2 = a2;

    uint8_t *tmp = array1;
    array1 = array2;
    array2 = tmp;


body:
Im trying to use sipo and piso shift registers simultaneously with ESP32 using SPI. However the sipo(SN74AHC) reads data on the rising edge of clock and the piso(SN74HC165) outputs data on the rising edge of the clock. Using the arduino SPI library, there is not a spi mode that can accomidate this. As a result, I am losing a bit from either device no matter what I do.

Is there something I can do to get both read and write at the rising edge or will I be forced to read and then write, changing the spi mode in between?

title: Is there a way to both read and write on the rising edge of the SPI Clock?

Answers: 0


body:
I have a setup consisting of a magnet suspended above a sensor coil. It acts as a pendulum and creates a ~ 4 mV signal when it swings over the coil - this goes through two stages of an LM358 to generate a 5V signal. The signal is very messy with lots of 'ringing'
This signal is fed into pin A0 of an Arduino Uno. I used MegunoLink.h and Filter.h which is an exponential filter library then applied constrain and map, finally converting to a clean 0 - 400 (units?) square wave of about 1 second with a varying duty cycle. This is the information I want as it tells me that the magnet is homing in on the sensor (the duty cycle increases as it gets close).
But when I apply pulseInLong I only get a string of zeros on the serial monitor.
What am I doing wrong?
Here is the sketch:
```
//  Coding by Jeremy 130520
//  further development for ricochet module
//https://www.megunolink.com/documentation/arduino-libraries/exponential-filter/
//https://www.google.com/search?q=how+to+use+arduino+pulsein

#include "MegunoLink.h"
#include "Filter.h"
// Create a new exponential filter with a weight of 5 and an initial value of 0.
ExponentialFilter<long> ADCFilter(5, 0);

int coilPin = 8;
int analogIn = A0;
unsigned long pulseLength;
unsigned long signal_1;

void setup()
{
  pinMode(coilPin, OUTPUT);
  pinMode(analogIn,INPUT);
  Serial.begin(9600);
  }

void loop()
{
 int RawValue = analogRead(analogIn);
  ADCFilter.Filter(RawValue);
 signal_1 =(ADCFilter.Current());
 signal_1 = constrain(signal_1,80, 200);
 signal_1 = map(signal_1, 80, 200,0,400);
 if (signal_1 >= 200) {signal_1 = 400; digitalWrite(coilPin, HIGH);}
 if (signal_1 < 200) {signal_1 = 0; digitalWrite(coilPin, LOW);}

 Serial.println(signal_1); //using the plotter

//pulseLength = pulseInLong(coilPin, HIGH);
 //Serial.println(pulseLength);
 delay(10);
}
```
[![changed duty cycle][1]][1]

[![output at end][2]][2]

  [1]: https://i.stack.imgur.com/k5Xwp.jpg
  [2]: https://i.stack.imgur.com/NNHsc.jpg

title: Need help with using pulseInLong to time a sensor

Answers: 1

body:
You cannot use `pulseInLong()` because it is a _blocking function_. It
waits until the input rises, then waits until it falls again, and only
then it returns a value. While it's waiting, the rest of the program
cannot run. This means you will not be able to actually generate the
signal you are trying to time.

The easiest solution is to time things yourself with `micros()`. You
have to implement an _edge detector_, i.e. some logic that remembers the
previous state of the signal and notices when it changes:

```c++
static bool is_high;  // is the input currently HIGH?
static uint32_t time_of_rise;  // when did it rise?

if (!is_high && signal_1 >= 200) {  // rising edge
    time_of_rise = micros();
    is_high = true;
} else if (is_high && signal_1 < 200) {  // falling edge
    uint32_t pulse_width = micros() - time_of_rise;
    is_high = false;
    Serial.println(pulse_width);
}
```


body:
I have a analog inputs to my Uno that I am cleaning up and using to keep a digital pin high until the output drops to zero. At this point I want to stop reading that input because it may come back up after being low for a short time.
Is there any way to set a variable that can be triggered by that first zero that prevents the loop from sending the digital pin high from then on?
Like a latch of some sort, or could I use an interrupt somehow?

title: How do I set a variable so that after a condition is met the loop ignores input?

Answers: 1

body:
You've already described what you need to do.  Just set a boolean variable.  It really couldn't be easier.

    boolean runThisPart = true;

    void loop() {

      if(runThisPart) {
         // this part only runs if runThisPart is true
         //  if something happens and you don't want
         //  to run this part anymore then
         if(some-condition){
            runThisPart = false;
         }
      }
      //  The rest of your code can also set runThisPart
      //  to true or false to turn that section on or off.
    }


body:
I am struggling with my Arduino Due and the Timer Counter functionallity. The following is what I am trying to achieve:

I want to execute a function to a specific point of time or more precisley after a specific amount of rising edges given by an external clock signal with a frequency of approx. 4 MHz. Thus I read the Atmel Datasheet, Section 36, Timer Counter. My approach was to trigger an interrupt every rising edge and increment a counter variable until I reached the desired amount of rising edges and call my function then. I can confirm that I am in fact counting rising edges with my current approach but I am reading way too slow. Is there any kind of register or hardware counter which automates the counting process. Like I set the register to a specific value and wait for an overflow, execute my function and reset the register? From my web research I found that this is possible on the Uno and Mega but I could not find anything for the Due and to be honest I am a bit overwhelmed by the Atmel Datasheet. Why not just use an Arduino Due or Mega then? I need the 3.3 Volts of the Due and from what I found the Uno and Mega are 5 V devices.

This is my code:

```

// define capture channels
#define CAPTURE_TC TC0
#define CAPTURE_CHANNEL 0
#define CAPTURE_IRQn TC0_IRQn
#define CAPTURE_Handler TC0_Handler
#define CAPTURE_ID ID_TC0
#define CAPTURE_PIN 2
#define CAPTURE_CLOCK_SELECTION TC_CMR_TCCLKS_TIMER_CLOCK3

// clock divisors corresponding to CAPTURE_CLOCK_SELECTION
static const uint32_t divisors[5] = { 2, 8, 32, 128, 0};

volatile uint32_t captured_pulses = 0;
volatile uint32_t captured_ra = 0;
volatile uint32_t captured_rb = 0;
volatile float frequency, duty_cycle, active_time;

/*
* Function:  setup
* ------------------------------------------------------------------------------
* Setup code. Will be executed once.
*/
void setup() {

  // init serial connection
  Serial.begin(115200);
  Serial.print("Initializing...");

  // configure the PIO pin as peripheral
  const PinDescription *config = &g_APinDescription[CAPTURE_PIN];
  PIO_Configure(config->pPort, config->ulPinType, config->ulPin, config->ulPinConfiguration);

  // enable timer peripheral clock
  pmc_enable_periph_clk(CAPTURE_ID);

  // configure the timer
  TC_Configure(CAPTURE_TC, CAPTURE_CHANNEL,
    CAPTURE_CLOCK_SELECTION   // Clock Selection
    | TC_CMR_LDRA_RISING      // RA Loading: rising edge of TIOA
    | TC_CMR_LDRB_FALLING     // RB Loading: falling edge of TIOA
    | TC_CMR_ABETRG           // External Trigger: TIOA
    | TC_CMR_ETRGEDG_FALLING  // External Trigger Edge: Falling edge
 );

  // configure TC interrupts
  NVIC_DisableIRQ(CAPTURE_IRQn);
  NVIC_ClearPendingIRQ(CAPTURE_IRQn);
  NVIC_SetPriority(CAPTURE_IRQn, 0);
  NVIC_EnableIRQ(CAPTURE_IRQn);

  // enable interrupts
  CAPTURE_TC->TC_CHANNEL[CAPTURE_CHANNEL].TC_IER = TC_IER_LDRBS;

  // start timer counter
  CAPTURE_TC->TC_CHANNEL[CAPTURE_CHANNEL].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;

  Serial.println("ready!");

} // setup

/*
* Function:  loop
* ------------------------------------------------------------------------------
* Loop code. Will be executed repeatedly after setup completed.
*/
void loop() {

 // Serial.print("Captured rising edges: "); Serial.println(captured_ra);
} // loop

/*
* Function:  CAPTURE_Handler
* ------------------------------------------------------------------------------
*
*/
void CAPTURE_Handler() {
 if ((TC_GetStatus(CAPTURE_TC, CAPTURE_CHANNEL) & TC_SR_LDRBS) == TC_SR_LDRBS) {
   captured_pulses++;
   // captured_ra = CAPTURE_TC->TC_CHANNEL[CAPTURE_CHANNEL].TC_RA;
   // captured_rb = CAPTURE_TC->TC_CHANNEL[CAPTURE_CHANNEL].TC_RB;

   if (captured_pulses == 4164303) {
    captured_pulses = 0;
    // specific_function_call();
   }
 }
} // CAPTURE_Handler
```

Thanks for your time, any help is grealty appreciated.

title: Is it possible to count rising edges of a 4 MHz clock on an Arduino Due and trigger an interrupt like all 4'000'000 edges?

Answers: 1

body:
First of all excuse my inactivity but as you know it's crazy times right now. However I finally figured it out, it's for sure not the most elegant solution but it meets my requirements. Thanks for your help @KamilCuk.

Here is my code if anyone may ever have the same problem as I did. External signal goes on Digital Pin 2. Works fine with a 4.2 MHz external clock.

```

// define capture channels
#define CAPTURE_TC TC0
#define CAPTURE_CHANNEL 0
#define CAPTURE_IRQn TC0_IRQn
#define CAPTURE_Handler TC0_Handler
#define CAPTURE_ID ID_TC0
#define CAPTURE_PIN 2
#define CAPTURE_CLOCK_SELECTION TC_CMR_TCCLKS_TIMER_CLOCK3

/*
* Function:  setup
* ------------------------------------------------------------------------------
* Setup code. Will be executed once.
*/
void setup() {

  // init serial connection
  Serial.begin(115200);
  Serial.print("Initializing...");

  // configure the PIO pin as peripheral
  const PinDescription *config = &g_APinDescription[CAPTURE_PIN];
  PIO_Configure(config->pPort, config->ulPinType, config->ulPin, config->ulPinConfiguration);

  // enable timer peripheral clock
  pmc_enable_periph_clk(CAPTURE_ID);

  // configure the timer
  TC_Configure(CAPTURE_TC, CAPTURE_CHANNEL,
    CAPTURE_CLOCK_SELECTION   // Clock Selection
    | TC_CMR_LDRA_RISING      // RA Loading: rising edge of TIOA
    | TC_CMR_ABETRG           // External Trigger: TIOA
    | TC_CMR_CPCTRG           // RC Compare
  );

  // configure TC interrupts
  NVIC_DisableIRQ(CAPTURE_IRQn);
  NVIC_ClearPendingIRQ(CAPTURE_IRQn);
  NVIC_SetPriority(CAPTURE_IRQn, 0);

  // enable interrupts and start counter
  CAPTURE_TC->TC_CHANNEL[CAPTURE_CHANNEL].TC_IER = TC_IER_CPCS;                  // enable RC Compare Interrupt
  CAPTURE_TC->TC_CHANNEL[CAPTURE_CHANNEL].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;  // the datasheet said I need this
  NVIC_EnableIRQ(CAPTURE_IRQn);                                                  // enable interrupts

  // set the trigger value for RC_Compare
  CAPTURE_TC->TC_CHANNEL[CAPTURE_CHANNEL].TC_RC = 4164303;

  Serial.println("ready!");

} // setup

/*
* Function:  loop
* ------------------------------------------------------------------------------
* Main code. Will be executed repeatedly.
*/
void loop() {

} // loop

/*
* Function:  CAPTURE_Handler respectively TC0_Handler
* ------------------------------------------------------------------------------
* Timer capture trigger. Will be executed if TC0_RA == TC0_RC
*/
void CAPTURE_Handler() {
  // reset status register
  TC_GetStatus(CAPTURE_TC, CAPTURE_CHANNEL);

  // do something
  Serial.println("Trigger");
  // function_call()
}
```


body: I am trying to create a robotic arm. The problem is that I could not run all 6 servo motors -3 MG966r servo motors and 3 MG90S servo motors - simultaneously, using 12V and 3A AC to DC adaptor. Last time I tried, My arduino uno is totally broken. If you can, Could you provide the schematics for the circuit? or Is there any methods to solve this problem?. Also Is it a better idea to use servo motor shield?

title: How to power 6 servo motors using battery to create a robotic arm?

Answers: 1

body:
For this task you should use an extra power supply not running trough the Arduino. For this kind of setup I use PCA9865 16-channel servo dirver board cost around 5$, needs two pins only and can run all servos (strong 5V power supply provided => Amperage) simultaniously. For a max of 8 servos a 5V/2-2.5A power supply (wall wart) should be sufficient.<br>
See this example circuit for how to connect:
[![PCA9685-Schematic][1]][1]

The [PCA9865 library has examples](https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library) how to drive servos via program. As this board is an I/O board you could also attach joystick(s) or buttons to it to save pins on your board.

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


body:
I'm trying to read data sent from my phone to arduino via HM-10 Bluetooth Module. I downloaded the app, I paired the module to phone but I can't read data.
If I just upload a blank sketch to arduino and open Serial Monitor, if I sent "1" from phone, it appears on the monitor, it's ok. But if I write Serial.begin(9600) in setup loop then noting happens and I can't see anymore the data from phone and Serial.read() is useless. Can you help me?

This don't work:

    char incomingValue = 0;
    int doorPin = 13;
    void setup() {
      Serial.begin(9600);
      pinMode(doorPin, OUTPUT);
    }

    void loop() {
      if (Serial.available() > 0) {
        incomingValue = Serial.read();
        Serial.print("\n");
        if (incomingValue == '1') {
          digitalWrite(doorPin, HIGH);
        } else {
          digitalWrite(doorPin, LOW);
        }
      }
    }

And with this I cand see to the Serial Monitor what I'm sending from phone but I can't read the character.

    char incomingValue = 0;
    int doorPin = 13;
    void setup() {
     // Serial.begin(9600);
      pinMode(doorPin, OUTPUT);
    }

    void loop() {
      if (Serial.available() > 0) {
        incomingValue = Serial.read();
        Serial.print("\n");
        if (incomingValue == '1') {
          digitalWrite(doorPin, HIGH);
        } else {
          digitalWrite(doorPin, LOW);
        }
      }
    }

title: Bluetooth Module 4.0 BLE

Answers: 0


body: I'm trying to use an arduino as a controller adapter. How would I get USB-in to get the signal from a usb video game controller?

title: How to use USB-in on an arduino?

Answers: 1

body:
It makes actually no sense to plug an USB-Controller via an Arduino to a PC. The direct way and using an autofire/macro /custom key programmer app is more efficient.<br>

 - The Arduino UNO (with 32u4) can either replace an USB controller as [demostrated in NicoHood HID library](https://github.com/NicoHood/HID) or
 - additionally act as an interface for controller with strange vendor specific plugs [demostrated in UNOJOY](https://github.com/AlanChatham/UnoJoy) and you can build your own Controller/interface out of nearly every old non usb controller by cutting the hardware specific plug (e.g. old Xbox) and attach to an UNO who acts as "interface" to the PC. Another example is a [C64-Joystick to the PC](https://create.arduino.cc/projecthub/fpfaffendorf/commodore-64-joystick-usb-adapter-c64joy-fc2389)
 - The other option for using an Arduino is interfacing with "old video game systems" . For some there are already more or less succesfull projects. When connecting the USB controller via an USB shield you have normally a high lag time due to the USB shield library, so the better approach is to cut the USB plug and directly interface with the Arduino.

Project with USB Host-shield:

 - [C64 - with USB Joysticks](https://create.arduino.cc/projecthub/DocSnyderde/connect-usb-joystick-to-commodore-c64-2fb5ba)

Project old Joystick to USB-PC:

 - [NES controller to PC USB](https://www.allaboutcircuits.com/projects/nes-controller-interface-with-an-arduino-uno/)

Project Arduino as controller for NES/SNES:

 - [UNO to NES/SNES](https://github.com/jtrinklein/SConE)

Info on the [pinout/protocol cn be found in this page](https://github.com/dfanara/NESDuino)


body:
Arduino Leonardo as keyboard in the computer works! But not with the Xbox360.
The Teensy works perfectly on the PC but how to emulate a keyboard device for the Xbox360.

I know the Xbox360 has security IC, but a simple USB keyboard works!

What is the diference ?

How i can emulate an usb keyboard for the Xbox360?

title: Why can the Xbox360 not detect the Arduino Leonardo as keyboard?

Answers: 1

body:
Like Juraj and Majenko said. Arduino Keyboard library does emulate "Boot Keyboard".

I use [NicoHood HID library][1] and now it works.

  [1]: https://github.com/NicoHood/HID


body:
My purpose was to send SMS using [GSM SIM800L coreboard ][1] and Arduino UNO. Here is the code
```

    #include <SoftwareSerial.h>

//Create a software serial object to communicate with SIM800L
SoftwareSerial mySerial(3, 2); //SIM800L Tx & Rx is connected to Arduino #3 & #2

void setup()
{
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(115200);

  //Begin serial communication with Arduino and SIM800L
  mySerial.begin(115200);

  Serial.println("Initializing...");
  delay(1000);

  mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
  updateSerial();

  mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
  updateSerial();
  mySerial.println("AT+CMGS=\"+ZZxxxxxxxxx\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
  updateSerial();
  mySerial.print("TEST"); //text content
  updateSerial();
  mySerial.write(26);
}

void loop()
{
}

void updateSerial()
{
  delay(500);
  while (Serial.available())
  {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(mySerial.available())
  {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
  }
}

```

And here is the serial monitor output
```
 22:31:19.430 -> Initializing...
```

However, when I run the code, I get the text message to my mobile phone, but [I can't see any AT commands in the serial monitor. It only outputs "Initializing..." ][2].
All the connections and baud rates are okay, checked a thousand times. Has connected 2A, 4.4v power supply to the GSM coreboard and shorten the wires, and sho No bad soldering joints. GSM module red led flash per 3 seconds. And again, I'm getting the text message to my phone. So that means the problem is with the Arduino serial monitor or code, not in the hardware. I need to see AT commands because I need to put more commands through the serial monitor, I tried typing and click send, But it's not showing anything. Any assistance you can provide would be greatly appreciated.

  [1]: https://i.stack.imgur.com/daxN0.jpg
  [2]: https://i.stack.imgur.com/DOSR7.png

title: Program is executing but AT commands not showing in serial monitor

Answers: 0


body:
I am having an issue splitting an incoming string from a computer program to arduino.
The incoming format is as follows:
123.456,987.654 \r\n

The comma separates the two values.
code is this(edit to add code most likely too many variables):

    char c;
    String com;
    String targetstr;
    String actualstr;
    bool newdata = true;
    float target =1;
    float actual = 5;
    float diff;
    int pwm = 0;
    float firstup = 2.75;
    float firstdown = 2.25;
    float intensifier = 5;
    unsigned long lasttime = 0;
    unsigned long currenttime = 0;
    int watchdog = 1000;

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

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

    while(Serial.available()>0&&newdata == true){
      c = Serial.read();
    // switched to '\r' from '\n' for testing.
      if(c == 0x0D){}

      if(c ==0x0A){
      targetstr = getValue(com,0x2C,0);
      //targetstr = com.substring(0,com.indexOf(0x2C));
      target = targetstr.toFloat();
      actualstr = getValue(com,0x2C,1);
      //actualstr = com.substring(com.indexOf(0x2C)+1);
      actual = actualstr.toFloat();
      com = "";//reset string
      diff = actual - target;
      newdata = false; //reset flag
      lasttime = currenttime;
      //Serial.print("Diff = ");
      //Serial.println(diff);
      Serial.print("Tgt ");
      Serial.print(targetstr);
      Serial.print(" Act ");
      Serial.println(actualstr);
      }
      else{
        com += c;
      }

The getValue is an example that I found on stack exchange

    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]) : "";
    }
So I have attempted two different ways to make this work. If I use the arduino serial monitor the code executes perfectly, but if I use the computer program it will not split the values.

In a serial monitor this is the sent code to the arduino via serial monitor(hex and ascii)

31 32 33 2E 34 35 36 2C 34 35 36 2E 31 32 33 0A   123.456,456.123.

and this is the arduino response
54 67 74 20 31 32 33 2E 34 35 36 20 41 63 74 20 34 35 36 2E 31 32 33 0D 0A                         Tgt 123.456 Act 456.123..

And this is code sent from the computer program to arduino:

 31 36 31 2E 39 35 32 2C 31 35 30 2E 38 30 30 0D 0A    161.952,150.800..

arduino response:

54 67 74 20 2E 39 35 32 2C 31 35 30 2E 38 30 30 0D 20 41 63 74 20 0D 0A                   Tgt 161.952,150.800. Act ..

I am not sure of the reason of not splitting, I have tried ascii and hex in the code for the comma, as well as two methods of actually splitting.

What are some other things I can try?

title: Splitting a string in arduino from computer

Answers: 0


body:
I am quite new to idea of encryption and am trying to use aes-256-ecb encryption.
 I am using library called "Arduino cryptography". Unfortunately I could not find any tutorial that would explain how to encrypt a json string (and other things latter) using a  key.

I have a function that generates same key on both sides of Arduino and php script on a server side, but I could not find a working tutorial (except the case of obsolete buggy library with instruction like : "copy this text" and even that doesn't work.
Unfortunately libraries examples do not bother to show how to retrieve  encrypted string or explain what is what and instead just focus on checking how long encryption takes.

Does any of you know of some tutorial or an example from which I could engineer a solution?
library link:[The library][1]

in buioltin example there is a code of:
```
cipher->decryptBlock(buffer, test->ciphertext);
```
But I do not understand where is the output and where the input here

Second  question would be if I can use other modes like the mentioned GCM simply by changing the value in
```
static TestVector const testVectorAES256 = {
    .name        = "AES-256-ECB",
    .key         = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
                    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
                    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F},
    .plaintext   = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
                    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
    .ciphertext  = {0x8E, 0xA2, 0xB7, 0xCA, 0x51, 0x67, 0x45, 0xBF,
                    0xEA, 0xFC, 0x49, 0x90, 0x4B, 0x49, 0x60, 0x89}
};
```
or how?

  [1]: https://rweather.github.io/arduinolibs/index.html

After bits and strougles I have managed to get this working, but next step is how to make it take a string:
```
/*Skúška kódovania GCM-AES256#*/

#include <Crypto.h>
#include <AES.h>
#include <GCM.h>
//#include <pgmspace.h>

struct TestVector
{
    const char *name;
    uint8_t key[32];
    uint8_t plaintext[60];
    uint8_t ciphertext[60];
    uint8_t authdata[20];
    uint8_t iv[12];
    uint8_t tag[16];
    size_t authsize;
    size_t datasize;
    size_t tagsize;
    size_t ivsize;
};

static TestVector const testVectorGCM PROGMEM = {
    .name        = "AES-256 GCM",
    .key         = {0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
                    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
                    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
                    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08},
    .plaintext   = {0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
                    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
                    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
                    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
                    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
                    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
                    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
                    0xba, 0x63, 0x7b, 0x39},
    .ciphertext  = {0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
                    0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
                    0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
                    0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
                    0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
                    0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
                    0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
                    0xbc, 0xc9, 0xf6, 0x62},
    .authdata    = {0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
                    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
                    0xab, 0xad, 0xda, 0xd2},
    .iv          = {0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
                    0xde, 0xca, 0xf8, 0x88},
    .tag         = {0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
                    0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b},
    .authsize    = 20,
    .datasize    = 60,
    .tagsize     = 16,
    .ivsize      = 12
};

TestVector testVector;
byte buffer[128];

bool testCipher_N(AuthenticatedCipher *cipher, const struct TestVector *test, size_t inc)
{
    size_t posn, len;
    uint8_t tag[16];

    crypto_feed_watchdog();

    cipher->clear();
    if (!cipher->setKey(test->key, cipher->keySize())) {
        Serial.print("setKey ");
        return false;
    }
    if (!cipher->setIV(test->iv, test->ivsize)) {
        Serial.print("setIV ");
        return false;
    }

    memset(buffer, 0xBA, sizeof(buffer));

    for (posn = 0; posn < test->authsize; posn += inc) {
        len = test->authsize - posn;
        if (len > inc)
            len = inc;
        cipher->addAuthData(test->authdata + posn, len);
    }

    for (posn = 0; posn < test->datasize; posn += inc) {
        len = test->datasize - posn;
        if (len > inc)
            len = inc;
        cipher->encrypt(buffer + posn, test->plaintext + posn, len);
    }

    Serial.println("Vystup:\n");
    for(uint8_t i=0; i<sizeof(buffer); i++) printf("0x%X,",buffer[i]);

    return true;
}

void testCipher(AuthenticatedCipher *cipher, const struct TestVector *test)
{
    bool ok;

    memcpy_P(&testVector, test, sizeof(TestVector));
    test = &testVector;

    Serial.print(test->name);
    Serial.print(" ... ");

    ok  = testCipher_N(cipher, test, test->datasize);
    /*ok &= testCipher_N(cipher, test, 1);
    ok &= testCipher_N(cipher, test, 2);
    ok &= testCipher_N(cipher, test, 5);
    ok &= testCipher_N(cipher, test, 8);
    ok &= testCipher_N(cipher, test, 13);
    ok &= testCipher_N(cipher, test, 16);*/

    if (ok)
        Serial.println("Passed");
    else
        Serial.println("Failed");
}

void perfCipherSetKey(AuthenticatedCipher *cipher, const struct TestVector *test, const char *name)
{
    unsigned long start;
    unsigned long elapsed;
    int count;

    crypto_feed_watchdog();

    memcpy_P(&testVector, test, sizeof(TestVector));
    test = &testVector;

    Serial.print(name);
    Serial.print(" SetKey ... ");

    start = micros();
    for (count = 0; count < 1000; ++count) {
        cipher->setKey(test->key, cipher->keySize());
        cipher->setIV(test->iv, test->ivsize);
    }
    elapsed = micros() - start;

    Serial.print(elapsed / 1000.0);
    Serial.print("us per operation, ");
    Serial.print((1000.0 * 1000000.0) / elapsed);
    Serial.println(" per second");
}

void perfCipherEncrypt(AuthenticatedCipher *cipher, const struct TestVector *test, const char *name)
{
    unsigned long start;
    unsigned long elapsed;
    int count;

    crypto_feed_watchdog();

    memcpy_P(&testVector, test, sizeof(TestVector));
    test = &testVector;

    Serial.print(name);
    Serial.print(" Encrypt ... ");

    cipher->setKey(test->key, cipher->keySize());
    cipher->setIV(test->iv, test->ivsize);
    start = micros();
    for (count = 0; count < 500; ++count) {
        cipher->encrypt(buffer, buffer, 128);
    }
    elapsed = micros() - start;

    Serial.print(elapsed / (128.0 * 500.0));
    Serial.print("us per byte, ");
    Serial.print((128.0 * 500.0 * 1000000.0) / elapsed);
    Serial.println(" bytes per second");
}

void setup(){
 Serial.begin(115200);
 Serial.println("Začínam\n");
 GCM <AES256> *gcm=0;
 gcm= new GCM<AES256>();
 gcm->setKey(testVectorGCM.key, 32);
 gcm->setIV(testVectorGCM.iv,testVectorGCM.ivsize);
 crypto_feed_watchdog();
 //gcm->encrypt(buffer,testVectorGCM.plaintext,60);
 testCipher(gcm,&testVectorGCM);
 delete gcm;
 //gcm.encrypt(&vstupny,&vystup,49);
 crypto_feed_watchdog();
    Serial.println("Vystup: \n");
    for(uint8_t i=0; i<50;i++) Serial.print(buffer[i]);
}

void loop(){
 delay(1000);
 Serial.print(".");
}
```
I need to be able to get the text on PHP side

title: Arduino AES encryption, working example or tutorial

Answers: 1

body:
Kind of an answer. After the advise from @Kwasmich I have converted to aes-256-gcm.

Upgraded to UTF-8 thanks to Edgar Bonet

Based mostly on GCMTest example comming with Arduino Cryptograhy libraries:

-----------------------------------------------

**Shared between Encryption and decrition**

First need to define parts which will not change:

```
#include <Crypto.h>
#include <AES.h>
#include <GCM.h>

struct TestVector
{
    const char *name;
    uint8_t key[32];
    uint8_t authdata[20];
    uint8_t iv[12];
    uint8_t tag[16];
    size_t authsize;
    size_t tagsize;
    size_t ivsize;
};

static TestVector const testVectorGCM PROGMEM = {   //Dont forget to change the Values here
    .name        = "AES-256 GCM",
    .key         = {0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
                    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
                    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
                    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08},
    .authdata    = {0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
                    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
                    0xab, 0xad, 0xda, 0xd2},
    .iv          = {0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
                    0xde, 0xca, 0xf8, 0x88},
    .tag         = {0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
                    0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b},
    .authsize    = 20,
    .tagsize     = 16,
    .ivsize      = 12
};
```
Now create a global buffer (easier to understand then pointers)
```
TestVector testVector;
byte buffer[128];
```

**Encrytpion**

```void encrypt(AuthenticatedCipher *cipher, const struct TestVector *test, size_t datasize)
{
    memcpy_P(&testVector, test, sizeof(TestVector));   //Load into memory
    test = &testVector;
    size_t posn, len;
    uint8_t tag[16];
    crypto_feed_watchdog();    //To protect from Watchdog reseting this function
```
It is important to clear memory of any ciphering before doing one:
```
    cipher->clear();
```
```
    cipher->setKey(test->key, cipher->keySize());    //Setting key
    cipher->setIV(test->iv, test->ivsize);     //vector
    for (posn = 0; posn < test->authsize; posn += datasize) {
        len = test->authsize - posn;
        if (len > datasize)
            len = datasize;
        cipher->addAuthData(test->authdata + posn, len);   //To make hack even more confusing
    }
    Serial.print("input numbers ");
 for(uint8_t i=0; i<60; i++) Serial.printf("%X",buffer[i]);
 Serial.println();

    for (posn = 0; posn < datasize; posn += datasize) {
        len = datasize - posn;
        if (len > datasize) len = datasize;
        crypto_feed_watchdog();
        cipher->encrypt((uint8_t*)buffer + posn, buffer + posn, len); //This is why we are here
        crypto_feed_watchdog();
    }
    Serial.println("Vystup:\n");
    for(uint8_t i=0; i<sizeof(buffer); i++) printf("0x%X,",buffer[i]);
}
```

**Decryption**

```
void decrypt(AuthenticatedCipher *cipher, const struct TestVector *test, size_t datasize){
    bool ok;

    memcpy_P(&testVector, test, sizeof(TestVector));
    test = &testVector;
    size_t posn, len;
    uint8_t tag[16];
    crypto_feed_watchdog();
    cipher->clear();
    cipher->setKey(test->key, cipher->keySize());
    cipher->setIV(test->iv, test->ivsize);
    for (posn = 0; posn < test->authsize; posn += datasize) {
        len = test->authsize - posn;
        if (len > datasize)
            len = datasize;
        cipher->addAuthData(test->authdata + posn, len);
    }

    for (posn = 0; posn < datasize; posn += datasize) {
        len = datasize - posn;
        if (len > datasize)
            len = datasize;
        cipher->decrypt((uint8_t*)buffer + posn, buffer + posn, len);
    }

    Serial.print("\nVystup: ");
    for(uint8_t i=0; i<60;i++) Serial.printf("%c",(char)buffer[i]);
    Serial.println();

}
```

-----------------------------------------------

full example:
```
/*Skúška kódovania GCM-AES256#*/

#include <Crypto.h>
#include <AES.h>
#include <GCM.h>

struct TestVector
{
    const char *name;
    uint8_t key[32];
    uint8_t authdata[20];
    uint8_t iv[12];
    uint8_t tag[16];
    size_t authsize;
    size_t tagsize;
    size_t ivsize;
};

static TestVector const testVectorGCM PROGMEM = {
    .name        = "AES-256 GCM",
    .key         = {0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
                    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
                    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
                    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08},
    .authdata    = {0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
                    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
                    0xab, 0xad, 0xda, 0xd2},
    .iv          = {0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
                    0xde, 0xca, 0xf8, 0x88},
    .tag         = {0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
                    0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b},
    .authsize    = 20,
    .tagsize     = 16,
    .ivsize      = 12
};

TestVector testVector;
byte buffer[128];

void encrypt(AuthenticatedCipher *cipher, const struct TestVector *test, size_t datasize)
{
    memcpy_P(&testVector, test, sizeof(TestVector));
    test = &testVector;
    size_t posn, len;
    uint8_t tag[16];
    crypto_feed_watchdog();

    cipher->clear();
    cipher->setKey(test->key, cipher->keySize());
    cipher->setIV(test->iv, test->ivsize);
    for (posn = 0; posn < test->authsize; posn += datasize) {
        len = test->authsize - posn;
        if (len > datasize)
            len = datasize;
        cipher->addAuthData(test->authdata + posn, len);
    }
    Serial.print("Cisla: ");
 for(uint8_t i=0; i<60; i++) Serial.printf("%X",buffer[i]);
 Serial.println();

    for (posn = 0; posn < datasize; posn += datasize) {
        len = datasize - posn;
        if (len > datasize) len = datasize;
        crypto_feed_watchdog();
        cipher->encrypt((uint8_t*)buffer + posn, buffer + posn, len);
        crypto_feed_watchdog();
    }
    Serial.println("Vystup:\n");
    //  Decrypt
    for(uint8_t i=0; i<sizeof(buffer); i++) printf("0x%X,",buffer[i]);
}

void decrypt(AuthenticatedCipher *cipher, const struct TestVector *test, size_t datasize){
    bool ok;

    memcpy_P(&testVector, test, sizeof(TestVector));
    test = &testVector;
    size_t posn, len;
    uint8_t tag[16];
    crypto_feed_watchdog();
    cipher->clear();
    cipher->setKey(test->key, cipher->keySize());
    cipher->setIV(test->iv, test->ivsize);
    for (posn = 0; posn < test->authsize; posn += datasize) {
        len = test->authsize - posn;
        if (len > datasize)
            len = datasize;
        cipher->addAuthData(test->authdata + posn, len);
    }

    for (posn = 0; posn < datasize; posn += datasize) {
        len = datasize - posn;
        if (len > datasize)
            len = datasize;
        cipher->decrypt((uint8_t*)buffer + posn, buffer + posn, len);
    }

    Serial.print("\nVystup: ");
    for(uint8_t i=0; i<60;i++) Serial.printf("%c",(char)buffer[i]);
    Serial.println();

}

void setup(){
 Serial.begin(115200);
 Serial.println("Začínam\n");
 GCM <AES256> *gcm=0;
 gcm= new GCM<AES256>();
 gcm->setKey(testVectorGCM.key, 32);
 gcm->setIV(testVectorGCM.iv,testVectorGCM.ivsize);
 crypto_feed_watchdog();
 memset(buffer, (int)'\0', sizeof(buffer));
 char vstup[30]="Tak to netuším";     //String containing Non-Asci characters
 for(uint8_t i=0; i<30; i++) buffer[i]=vstup[i];
 encrypt(gcm,&testVectorGCM,30);
 decrypt(gcm,&testVectorGCM,30);
 delete gcm;
}

void loop(){
 delay(1000);
 Serial.print(".");
}

```
simple key generator in PHP:
```
<?php
for($i=0;$i<31;$i++) printf("0x%X,",random_int(0,0xFF));
printf("0x%X\n",random_int(0,0xFF));
?>
```


body:
I purchased [these slide switches][1] recently because I want to use them in my project:

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

But I don't know what to connect up the three pins to and I can't find any information about them online. Nor can I find sample code. Can someone show me how to wire them up and provide sample code please? I just want to be able to check their state and save it as a boolean variable.

  [1]: https://www.amazon.com/gp/product/B007QAJUUS/
  [2]: https://i.stack.imgur.com/nq9Jz.jpg

title: How to use this 3-pin slide-switch?

Answers: 3

body:
Since it has two possible positions, and three pins, you have a connection between pin 1 and 2 when position 1 is selected, and between pin 1 and 3 when position 2 is selected.
As BSF comment below, the middle pin is common. This means it will be connected to the outside pins depending on where the switch is moved towards.

However, you always can verify this, in the following way:

To find out which is pin 1, pin 2 and pin 3, use a multimeter. Set it to continuity mode, or if you don't have that mode, to resistance mode, and put the red/black probes to two random pins. Check if the resistance is 0, in that case you know those two pins will be connected when position 1 is selected. If there is resistance, try other pins with the probes, until you know which are connected.

Than switch the position, and do it again.

Instead of a multimeter you also can 'hardwire'  it to e.g. 5V -> pin 1, pin 2 -> resistor of 220 ohm -> LED -> GND
And change pin 1 and pin 2 until you found which pins connect for which positions.

To use it for you Arduino, check for a normal simple switch example, but these are two in one, one for each position.

body:
These switches are actually a lot more simple than you would think.  You have two positions, but you really only care about one of them, since if it's not in that position it must be in the other.

The central pin is the common, and when slid to one side it connects that central pin to the corresponding outside pin.

So you just use the central pin and *one* of the outside pins as if it were any other on-off switch or pushbutton.  Treat it *exactly* the same (pullup resistor, which may be internal to the AVR chip, and connect the IO pin to ground through the switch).

If it's "on" (reads LOW) then the switch is in one position. If it's "off" (reads HIGH) then it's in the other position.

The only times you'd want to use both outer pins is if you were wanting to direct a signal to one of two different places, or select between two different incoming signals, or if the switch were a "3 position on-off-on" switch where it can be in either outer position or *neither* position (centre off), in which case you treat it as two separate switches, but with a common central pin that connects both to ground.

body:
As others have said, this is a SPDT (Single Pole Double Throw) switch. The center pin is common. When the switch is slid one way, it connects the center pin to the outer pin on that side. When you slide the switch the other way, it connects the center pin to the opposite outer pin.

See the link about SPDT switches Edgar provided in his comment: http://www.learningaboutelectronics.com/Articles/What-is-a-single-pole-double-throw-switch-SPDT

That explains these switches pretty clearly.

Connect the center pin of the switch to a digital pin on your Arduino. Connect one of the outer pins to ground.

Set the digital pin on the Arduino to `INPUT_PULLUP` mode.

Then, when you read the digital state of the pin, if it is LOW, the switch is closed. (Slid to the side of the pin you attached to ground.)


body:
I want to add counter in multiple-buttons-to-control-relays:

    int relay1 = 23;
    int relay2 = 25;
    int relay3 = 27;
    int relay4 = 29;
    int relay5 = 31;
    int relay6 = 33;
    int relay7 = 35;
    int relay8 = 37;
    ////////////int mode =  41;      // select mode AUTO/MANUAL if HIGH=AUTO else LOW=MANUAL
    //////////int start = 43;      // select START/STOP auto mode
    //////////int tool =  13;       // tool Sw
    int sw1 = 2;
    int sw2 = 4;
    int sw3 = 6;
    int sw4 = 8;

    int sw5 = 3;  //additional
    int sw6 = 5;
    int sw7 = 7;
    int sw8 = 9;
     ////////int modeState =  1;  //modelState for //start stop and tool
    /////////int startState = 1; //start1State
    /////////int toolState =  1;
    int sw1Status, sw2Status, sw3Status, sw4Status,sw5Status, sw6Status, sw7Status, sw8Status;
    int order = 1; // default is to set all relays off.
    /// for counter//////////////////////////////////////////////////
    int val = 0; // variable for reading the pin status
    int counter = 0;
    int currentState = 0;
    int previousState = 0;
    //// for counter ////////////////////////////////////////////////
    void setup() {
      pinMode(relay1, OUTPUT);
      pinMode(relay2, OUTPUT);
      pinMode(relay3, OUTPUT);
      pinMode(relay4, OUTPUT);
      pinMode(relay5, OUTPUT);
      pinMode(relay6, OUTPUT);
      pinMode(relay7, OUTPUT);
      pinMode(relay8, OUTPUT);

      // input pull-up, so default state of buttons is HIGH.
      pinMode(sw1, INPUT_PULLUP);
      pinMode(sw2, INPUT_PULLUP);
      pinMode(sw3, INPUT_PULLUP);
      pinMode(sw4, INPUT_PULLUP);
      pinMode(sw5, INPUT_PULLUP);  ///additional
      pinMode(sw6, INPUT_PULLUP);
      pinMode(sw7, INPUT_PULLUP);
      pinMode(sw8, INPUT_PULLUP);
      Serial.begin(9600);
    }

    void loop() {
      // read the buttons status
      sw1Status = digitalRead(sw1);
      sw2Status = digitalRead(sw2);
      sw3Status = digitalRead(sw3);
      sw4Status = digitalRead(sw4);
      sw5Status = digitalRead(sw5);
      sw6Status = digitalRead(sw6);
      sw7Status = digitalRead(sw7);
      sw8Status = digitalRead(sw8);
      ///// tool state example
      ////if (sw1Status == LOW && sw2Status == LOW && sw3Status == LOW && sw4Status == LOW && toolState == HIGH) { //

      if (sw1Status == LOW && sw2Status == LOW && sw3Status == LOW && sw4Status == LOW) { // if button 1 pressed
        order = 2; // go to case 2 start up state
        Serial.println("all switch off follow order 2");
      }
      if (sw1Status == HIGH && sw2Status == LOW && sw3Status == LOW && sw4Status == LOW) { // if button 2 pressed
        order = 3;// go to case 3
         Serial.println("order 3 sw 1 relay 1 on");
      }
      if (sw1Status == HIGH && sw2Status == LOW && sw3Status == LOW && sw4Status == HIGH) { // if button 3 pressed
         //// possible if (order != 5) { // if order is not equal 5 turn on relay 1 & 4
        order = 4;// go to case 4
        Serial.println(" order 4 sw 1,4 relay 1,7,8 on");

      }
      if (sw1Status == HIGH && sw2Status == LOW && sw3Status == HIGH && sw4Status == LOW) { // if button 3 pressed
        order = 5;// go to case 5
        Serial.println(" order 5 sw 2 3 on relay 1on now right down");
      }
      if (sw1Status == LOW && sw2Status == HIGH && sw3Status == HIGH && sw4Status == LOW) { // if button 3 pressed
        order = 6;// go to case 6
        Serial.println(" order 6 sw 3 and 2 on");
      }
      if (sw1Status == LOW && sw2Status == HIGH && sw3Status == LOW && sw4Status == HIGH) { // if button 2 pressed
        order = 7;// go to case
         Serial.println(" order 7 ");
      }
      if (sw1Status == LOW && sw2Status == HIGH && sw3Status == HIGH && sw4Status == LOW && sw7Status == LOW) { //
        order = 8;// go to case
        Serial.println("orde 8 left side ");
      }
      if (sw1Status == LOW && sw2Status == LOW && sw3Status == LOW && sw8Status == HIGH && sw8Status == LOW) { //
        order = 9;// go to case
        Serial.println(" spare order 9 sw 4 high");
      }

      if (sw1Status == LOW && sw2Status == LOW && sw3Status == LOW && sw4Status == LOW) { // button 4 toggle
        if (order != 10) { // if order is not equal
          Serial.println("  spare order 10 all off ");

          order = 10;
        }
        else { // else go to case 1, which will turns off all relays
          order = 1;
        }
      }

      switch (order) {
        case 1: // if order equals 1
        delay(200);
          digitalWrite(relay1, LOW);
          digitalWrite(relay2, HIGH);
          digitalWrite(relay3, HIGH);
          digitalWrite(relay4, HIGH);
          digitalWrite(relay5, HIGH);
          digitalWrite(relay6, HIGH);
          digitalWrite(relay7, HIGH);
          digitalWrite(relay8, HIGH);
          Serial.println("default start up ");

          break;

        case 2: // if order equals 2
        delay(1000);
          digitalWrite(relay1, LOW);
          digitalWrite(relay2, HIGH);
          digitalWrite(relay3, HIGH);
          digitalWrite(relay4, HIGH);
          digitalWrite(relay5, HIGH);
          digitalWrite(relay6, HIGH);
          digitalWrite(relay7, HIGH);
          digitalWrite(relay8, HIGH);
          Serial.println("move up case 2");

          break;

        case 3: // if order equals 3
          delay(1000);
          digitalWrite(relay1, HIGH);
          digitalWrite(relay2, LOW);
          digitalWrite(relay3, HIGH);
          digitalWrite(relay4, HIGH);
          digitalWrite(relay5, HIGH);
          digitalWrite(relay6, HIGH);
          digitalWrite(relay7, HIGH);
          digitalWrite(relay8, HIGH);
          Serial.println("move right case 3");

          break;{

        case 4: // if order equals 4
          delay(1000);
          digitalWrite(relay1, LOW);
          digitalWrite(relay2, HIGH);
          digitalWrite(relay3, HIGH);
          digitalWrite(relay4, LOW);
          digitalWrite(relay5, HIGH);
          digitalWrite(relay6, HIGH);
          digitalWrite(relay7, LOW);
          digitalWrite(relay8, LOW);
          Serial.println("move down case 4");
          break;}

        case 5: // if order equals 5
          digitalWrite(relay1, LOW);
          digitalWrite(relay2, HIGH);
          digitalWrite(relay3, HIGH);
          digitalWrite(relay4, HIGH);
          digitalWrite(relay5, HIGH);
          digitalWrite(relay6, HIGH);
          digitalWrite(relay7, LOW);
          digitalWrite(relay8, LOW);
          Serial.println("move down  case 5");
          break;
          case 6: // if order equals 6
          delay(1000);
          digitalWrite(relay1, LOW);
          digitalWrite(relay2, HIGH);
          digitalWrite(relay3, HIGH);
          digitalWrite(relay4, HIGH);
          digitalWrite(relay5, HIGH);
          digitalWrite(relay6, HIGH);
          digitalWrite(relay7, HIGH);
          digitalWrite(relay8, HIGH);
          Serial.println("move up case 6");
          break;
              case 7: // if order equals
              delay(1000);
              val = digitalRead(sw2Status); // read input value
              if (val == HIGH)  // check if the input is HIGH (button released)
                currentState = 1;
                if(currentState != previousState)
                if(currentState == 1)
                  counter = counter + 1;
                  else
                  case 10: // if order equals
                Serial.println(counter);

          digitalWrite(relay1, LOW);
          digitalWrite(relay2, HIGH);
          digitalWrite(relay3, HIGH);
          digitalWrite(relay4, HIGH);
          digitalWrite(relay5, HIGH);
          digitalWrite(relay6, HIGH);
          digitalWrite(relay7, HIGH);
          digitalWrite(relay8, HIGH);

          Serial.println("move up rly 1");
          break;

        case 8: // if order equals
        delay(1000);
          digitalWrite(relay1, LOW);
          digitalWrite(relay2, HIGH);
          digitalWrite(relay3, LOW);
          digitalWrite(relay4, HIGH);
          digitalWrite(relay5, HIGH);
          digitalWrite(relay6, HIGH);
          digitalWrite(relay7, HIGH);
          digitalWrite(relay8, HIGH);
          Serial.println("new left side");
          break;
          case 9: // if order
          delay(1000);
          digitalWrite(relay1, HIGH);
          digitalWrite(relay2, LOW);
          digitalWrite(relay3, HIGH);
          digitalWrite(relay4, LOW);
          digitalWrite(relay5, LOW);
          digitalWrite(relay6, LOW);
          digitalWrite(relay7, HIGH);
          digitalWrite(relay8, HIGH);
          Serial.println(" on right side");
          break;

        default: // if none of above cases is valid go to case 1
          order = 1;
          break;
      }
    }

 multiple button switch case for multiple relays

title: multiple button switch case how to add counter

Answers: 0


body:
EDIT2: Well, this is the "new" code and it just displays random dots on the matrices:

```
#include "RTClib.h"

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 16
#define NUM_ZONES 4

#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary output pins
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

RTC_DS3231 rtc;
#define SPEED_TIME  25
#define PAUSE_TIME  1000

uint8_t lastUpdateMin = 0;
uint8_t lastUpdateHour = 0;

// Global variable
const char  *pc[NUM_ZONES] =
{
  "TIME",
  "ROOM", //0
  "SUBJECT", //1
  "GRADE",//2
  };

void setup(void)
{

  P.begin();
    if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

 if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
//     If the RTC have lost power it will set the RTC to the date & time this sketch was compiled in the following line
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
 }

 P.begin(4);
  P.setZone(0, 0, 3); // Modules 0-3 in zone 0
  P.setZone(1, 4, 7); // Modules 4-7 in zone 1
  P.setZone(2, 8, 11); // Modules 8-11 in zone 2
  P.setZone(3, 12, 15); // Modules 12-15 in zone 3
}

void loop(void)
{

 DateTime now = rtc.now();
 if(lastUpdateMin != now.minute()){  // change every minute
     lastUpdateMin = now.minute();
 char buffer[] = "hh:mm";  // hours and minutes
P.displayZoneText(0,now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);

    if(lastUpdateHour != now.hour()){     // change every hour
     lastUpdateHour = now.hour();
   P.displayZoneText(1, pc[1], PA_RIGHT, 0, 0, PA_PRINT, PA_NO_EFFECT);
   P.displayZoneText(2, pc[2], PA_LEFT, 0, 0, PA_PRINT, PA_NO_EFFECT);  // display
   P.displayZoneText(3, pc[3], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
   }
  }
   P.displayAnimate();
}

```
If I do just this:
```
void loop(void)
{

 DateTime now = rtc.now();
 if(lastUpdateMin != now.minute()){  // change every minute
     lastUpdateMin = now.minute();
 char buffer[] = "hh:mm";  // hours and minutes
P.displayZoneText(0,now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
 }
     if(lastUpdateHour != now.hour()){     // change every hour
     lastUpdateHour = now.hour();

     }

   P.displayAnimate();
}
```
it displays the hour:minutes.
the problem is it doesn't display the time and the other text at the same time

EDIT: If I execute this code below it will display text on the first row, but my question will be how do I manage to display simultaneously the hour:minutes from the clock and some text of my choice?
```
void setup(void)
{

  P.begin();
    if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

 if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
//     If the RTC have lost power it will set the RTC to the date & time this sketch was compiled in the following line
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
 }

 P.begin(4);
  P.setZone(0, 0, 3); // Modules 0-3 in zone 0
  P.setZone(1, 4, 7); // Modules 4-7 in zone 1
  P.setZone(2, 8, 11); // Modules 8-11 in zone 2
  P.setZone(3, 12, 15); // Modules 12-15 in zone 3

for (uint8_t i=0; i<NUM_ZONES; i++)
    P.displayZoneText(0, pc[0], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);

}

void loop(void)
{

 DateTime now = rtc.now();
 char buffer[] = "hh:mm";  // hours and minutes

// P.displayZoneText(0,now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);  // display
//if(now.hour()==12){
//  P.displayZoneText(0, pc[0], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
//}
//else{
 // P.displayZoneText(1, pc[1], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);  // display
//}
   P.displayAnimate();
}
```

I have multiple FC-16 modules based on MAX7219 led matrices and I want to use them and a real time clock, DS3231, to build a classroom timetable.

I want the led modules to operate on the concept of zones. I want to create a zone for each row of text (a zone is a contiguous block of modules forming a kind of sub-display) as I did here: ```P.begin(4); // We will have 4 zones
P.setZone(0, 0, 3); // Modules 0-3 in zone 0
P.setZone(1, 4, 7); // Modules 4-7 in zone 1
P.setZone(2, 8, 11); // Modules 8-11 in zone 2
P.setZone(3, 12, 15); // Modules 12-15 in zone 3```

I want this in order to be able to change the text in a row without modifying other rows.

Then, I need to use the hour and minutes from the DS3231 clock module and to display it on the first row of the display and on the other 3 rows I need to display the number of the room, the subject and the class.
```uint8_t  curText;
const char  *pc[NUM_ZONES] =
{
  "ROOM",
  "SUBJECT",
  "CLASS",};
 ```
And when the hour on the first row changes, the text from the other 3 rows should change simultaneously.It's a pretty simple concept but I can't seem to know how to manage this.
This is all the code I gathered up until now:

```
#include "RTClib.h"

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 16
#define NUM_ZONES 4

#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary output pins
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
RTC_DS3231 rtc;
#define SPEED_TIME  25
#define PAUSE_TIME  1000

// Global variables
uint8_t  curText;
const char  *pc[NUM_ZONES] =
{
  "ROOM",
  "SUBJECT",
  "CLASS",

};

void setup(void)
{

  P.begin();
    if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

 if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
//     If the RTC have lost power it will set the RTC to the date & time this sketch was compiled in the following line
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
 }

 P.begin(4);
  P.setZone(0, 0, 3); // Modules 0-3 in zone 0
  P.setZone(1, 4, 7); // Modules 4-7 in zone 1
  P.setZone(2, 8, 11); // Modules 8-11 in zone 2
  P.setZone(3, 12, 15); // Modules 12-15 in zone 3

}

void loop(void)
{

 DateTime now = rtc.now();
 char buffer[] = "hh:mm";  // hours and minutes

   for (uint8_t i=0; i<NUM_ZONES; i++)
    P.displayZoneText(i-1, now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);

P.displayAnimate();
}
```

I dont't know how to display the hour:minutes and my text simultaneously so that I can do the rest then:
```void loop(void)
{

 DateTime now = rtc.now();
 char buffer[] = "hh:mm";  // hours and minutes

   for (uint8_t i=0; i<NUM_ZONES; i++)
    P.displayZoneText(i-3, now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT); //here I want to display the hour:minutes on the first row

P.displayAnimate();
}```

title: Parola library and DS3231 clock

Answers: 1

body:
Your first problem is the definition of the text array:

    const char  *pc[NUM_ZONES] =
    { "TIME",      // This will be replaced by real time its only for logic of rows here
      "ROOM",
      "SUBJECT",
      "CLASS"
    };

then we need a timer, as you only show minutes we only have to change time in that interval to prevent flicker and other unwanted effects and hour for changing texts lateron:

    uint8_t lastUpdateMin = 0;
    uint8_t lastUpdateHour = 0;

Then the loop looks like

    void loop() {
       DateTime now = rtc.now();
       if(lastUpdateMin != now.minute()){  // change every minute
         lastUpdateMin = now.minute();
         char buffer[] = "hh:mm";  // hours and minutes
         P.displayZoneText(0, now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT); // 1st row
        }
      if(lastUpdateHour != now.hour()){     // change every hour
         lastUpdateHour = now.hour();
         P.displayZoneText(1, pc[1], PA_RIGHT, 0, 0, PA_PRINT, PA_NO_EFFECT);  // 2nd row
         P.displayZoneText(2, pc[2], PA_LEFT, 0, 0, PA_PRINT, PA_NO_EFFECT);   // 3rd row
         P.displayZoneText(3, pc[3], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT); // 4th row
        }
    P.displayAnimate();
    }

Things to do - define a two dimensional char table with all the texts needed for the different hours

    #define NUM_LECTUREHOURS 7       // seven hour lectures
    const char *pc[NUM_LECTUREHOURS][NUM_ZONES] = {
      { "TIME", "ROOM_0", "SUBJECT_0", "CLASS_0"},
      { "TIME", "ROOM_1", "SUBJECT_1", "CLASS_1"},
      { "TIME", "ROOM_2", "SUBJECT_2", "CLASS_2"},
      ...
      { "TIME", "ROOM_Last", "SUBJECT_Last", "CLASS_Last"}  // _Last in this example = 6
    };

and display with a variable based on the hour so if your classes start at 9:00 you would use

    uint8_t lectureHour= now.hour() - 9; // as arrays start with 0

and your different texts would be called like

      P.displayZoneText(1, pc[lectureHour][1], PA_RIGHT, 0, 0, PA_PRINT, PA_NO_EFFECT); // 2nd row

If your char array gets to large - depending on the texts - you will have to use PROGMEM which is an issue on its own. Hope this gets you started

**EDIT**
If you want to change every two hours you do

  if(lastUpdateHour != now.hour() && lastUpdateHour +1 != now.hour() ){     // change every two hours

or shorter for a variable timespan (e.g. every three hours)

     if( now.hour() - lastUpdateHour > 3 ){     // change every three hours