# DC motor with 3(or more) programmed limits

Hello Guys

I have a project to build one DC motor in a machine, and need to have 3 pre programmed position. The Shiftautomations sketch is the what is very similar to my project.

With the original sketch you are be able to definied 3 coordinates, and to store them, with button. After you can moove with push buttons in this targets.

What I need to change?

1.To have already definied coordinates in sketch instead of "store" them with button.

2.Before the motor arrive to target to slow down (to have a precise position)

I try to do myself but without sucess.

Here is the sketch from Shiftautomation:

const int RELAY[] = {6,7}; //RELAY[0] and RELAY[1] to access the pins
const int BTN_EXTEND = 4;
const int BTN_RETRACT = 5;
const uint8_t MANUAL = 1; //a constant to indicate manual mode
const uint8_t AUTOMATIC = 2; //a constant to indicate automatic mode
const int BTN_MEM_PIN[] = {8,9,10};
const int BTN_SET_MEM = 11;

//Set up the linear actuator encoder
//On many of the Arduino boards pins 2 and 3 are interrupt pins
// which provide the best performance of the encoder data.
Encoder myEnc(2, 3);
long oldPosition = -999;
long targetPosition = 0;
#define ACCURACY 10 //How close to your target position is close enough. Higher accuracy may result in
// a bit of jitter as the actuator nears the position
#define DEBOUNCE_MS 20 //A debounce time of 20 milliseconds usually works well for tactile button switches.
#define PULLUP true //To keep things simple, we use the Arduino's internal pullup resistor.
#define INVERT true //Since the pullup resistor will keep the pin high unless the
//switch is closed, this is negative logic, i.e. a high state
//means the button is NOT pressed. (Assuming a normally open switch.)
uint8_t MODE = MANUAL;

Button btnExtend(BTN_EXTEND, PULLUP, INVERT, DEBOUNCE_MS);
Button btnRetract(BTN_RETRACT, PULLUP, INVERT, DEBOUNCE_MS);
Button btnSetPos(BTN_SET_MEM, PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos1(BTN_MEM_PIN[0], PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos2(BTN_MEM_PIN[1], PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos3(BTN_MEM_PIN[2], PULLUP, INVERT, DEBOUNCE_MS);

long memPosition[] = {0,0,0};

void setup() {
pinMode(RELAY[0], OUTPUT);
pinMode(RELAY[1], OUTPUT);

Serial.begin(9600);
}

void loop() {

if (btnExtend.isPressed()) {
extendActuator();
MODE = MANUAL;
}

if (btnRetract.isPressed()) {
retractActuator();
MODE = MANUAL;
}

if (!btnExtend.isPressed() && !btnRetract.isPressed() && MODE == MANUAL) {
stopActuator();
MODE = MANUAL;
}

if(btnPos1.wasReleased()) {
Serial.println("btnPos1");
MODE = AUTOMATIC;
targetPosition = memPosition[0];
}
if(btnPos2.wasReleased()) {
Serial.println("btnPos2");
MODE = AUTOMATIC;
targetPosition = memPosition[1];
}
if(btnPos3.wasReleased()) {
Serial.println("btnPos3");
MODE = AUTOMATIC;
targetPosition = memPosition[2];
}

//check the encoder to see if the position has changed
if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.println(newPosition);
}

if(MODE == AUTOMATIC && newPosition != targetPosition) {
Serial.print("Target/Actual:");Serial.print(targetPosition);Serial.print(" / ");Serial.print(newPosition);Serial.print(" [");Serial.print(abs(targetPosition - newPosition));Serial.println("]");
if(targetPosition < newPosition) {
Serial.println("AUTO RETRACT");
retractActuator();
MODE = AUTOMATIC;
}
if(targetPosition > newPosition) {
Serial.println("AUTO EXTEND");
extendActuator();
MODE = AUTOMATIC;
}
if( (targetPosition == newPosition) || abs(targetPosition - newPosition) <= ACCURACY) {
Serial.println("AUTO STOP");
stopActuator();
MODE = MANUAL;
}
}

if(btnSetPos.isPressed()) {
if(btnPos1.isPressed())
memPosition[0] = newPosition;
if(btnPos2.isPressed())
memPosition[1] = newPosition;
if(btnPos3.isPressed())
memPosition[2] = newPosition;

}
}

void extendActuator() {
//Serial.println("extendActuator");
digitalWrite(RELAY[0], HIGH);
digitalWrite(RELAY[1], LOW);
}

void retractActuator() {
//Serial.println("retractActuator");
digitalWrite(RELAY[0], LOW);
digitalWrite(RELAY[1], HIGH);
}

void stopActuator() {
//Serial.println("stopActuator");
digitalWrite(RELAY[0], HIGH);
digitalWrite(RELAY[1], HIGH);
}

To make it easier for people to help you please modify your post and use the code button </> `so your code looks like this` and is easy to copy to a text editor. See How to use the Forum

Your code is too long for me to study quickly without copying to a text editor.

...R

Sorry Robin I forget it.

Here is the sketch:

``````#include  //http://www.pjrc.com/teensy/arduino_libraries/Encoder.zip
#include   //https://github.com/JChristensen/Button

const int RELAY[] = {6,7};  //RELAY[0] and RELAY[1] to access the pins
const int BTN_EXTEND = 4;
const int BTN_RETRACT = 5;
const uint8_t MANUAL = 1;    //a constant to indicate manual mode
const uint8_t AUTOMATIC = 2; //a constant to indicate automatic mode
const int BTN_MEM_PIN[] = {8,9,10};
const int BTN_SET_MEM = 11;

//Set up the linear actuator encoder
//On many of the Arduino boards pins 2 and 3 are interrupt pins
// which provide the best performance of the encoder data.
Encoder myEnc(2, 3);
long oldPosition  = -999;
long targetPosition = 0;
#define ACCURACY 10		   //How close to your target position is close enough. Higher accuracy may result in
// a bit of jitter as the actuator nears the position
#define DEBOUNCE_MS 20     //A debounce time of 20 milliseconds usually works well for tactile button switches.
#define PULLUP true        //To keep things simple, we use the Arduino's internal pullup resistor.
#define INVERT true        //Since the pullup resistor will keep the pin high unless the
//switch is closed, this is negative logic, i.e. a high state
//means the button is NOT pressed. (Assuming a normally open switch.)
uint8_t MODE = MANUAL;

Button btnExtend(BTN_EXTEND, PULLUP, INVERT, DEBOUNCE_MS);
Button btnRetract(BTN_RETRACT, PULLUP, INVERT, DEBOUNCE_MS);
Button btnSetPos(BTN_SET_MEM, PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos1(BTN_MEM_PIN[0], PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos2(BTN_MEM_PIN[1], PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos3(BTN_MEM_PIN[2], PULLUP, INVERT, DEBOUNCE_MS);

long memPosition[] = {0,0,0};

void setup() {
pinMode(RELAY[0], OUTPUT);
pinMode(RELAY[1], OUTPUT);

Serial.begin(9600);
}

void loop() {

if (btnExtend.isPressed()) {
extendActuator();
MODE = MANUAL;
}

if (btnRetract.isPressed()) {
retractActuator();
MODE = MANUAL;
}

if (!btnExtend.isPressed() && !btnRetract.isPressed() && MODE == MANUAL) {
stopActuator();
MODE = MANUAL;
}

if(btnPos1.wasReleased()) {
Serial.println("btnPos1");
MODE = AUTOMATIC;
targetPosition = memPosition[0];
}
if(btnPos2.wasReleased()) {
Serial.println("btnPos2");
MODE = AUTOMATIC;
targetPosition = memPosition[1];
}
if(btnPos3.wasReleased()) {
Serial.println("btnPos3");
MODE = AUTOMATIC;
targetPosition = memPosition[2];
}

//check the encoder to see if the position has changed
if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.println(newPosition);
}

if(MODE == AUTOMATIC && newPosition != targetPosition) {
Serial.print("Target/Actual:");Serial.print(targetPosition);Serial.print(" / ");Serial.print(newPosition);Serial.print(" [");Serial.print(abs(targetPosition - newPosition));Serial.println("]");
if(targetPosition < newPosition) {
Serial.println("AUTO RETRACT");
retractActuator();
MODE = AUTOMATIC;
}
if(targetPosition > newPosition) {
Serial.println("AUTO EXTEND");
extendActuator();
MODE = AUTOMATIC;
}
if( (targetPosition == newPosition) || abs(targetPosition - newPosition) <= ACCURACY) {
Serial.println("AUTO STOP");
stopActuator();
MODE = MANUAL;
}
}

if(btnSetPos.isPressed()) {
if(btnPos1.isPressed())
memPosition[0] = newPosition;
if(btnPos2.isPressed())
memPosition[1] = newPosition;
if(btnPos3.isPressed())
memPosition[2] = newPosition;

}
}

void extendActuator() {
//Serial.println("extendActuator");
digitalWrite(RELAY[0], HIGH);
digitalWrite(RELAY[1], LOW);
}

void retractActuator() {
//Serial.println("retractActuator");
digitalWrite(RELAY[0], LOW);
digitalWrite(RELAY[1], HIGH);
}

void stopActuator() {
//Serial.println("stopActuator");
digitalWrite(RELAY[0], HIGH);
digitalWrite(RELAY[1], HIGH);
}
``````

Sorry there is left the libraries what are used

#include <Button.h>
#include <Encoder.h>

I try to solve this problems by myself but it wasnt working....

If somebody have idea?

I think you need to greatly simplify (shorten) the program so it is doing nothing else but moving a motor from one position to another.

Make a backup copy of your program and then get rid of all the button code and the automatic and manual stuff.

When you can control the motor the way you want then you can add back the other parts step by step, testing at every stage.

What sort of motor are you using? You say DC motor but I don't see any code for controlling the speed of the motor.

...R

Simple DC wiper motor(from garage door) and there is added the encoder instead of limit switches.

I try to add some position for test, but the system always need some change on sketch.

With the original code is working properly.

Please give some idea how can i start.

The hardest thing is,that the system need to know where is actual position of encoder, and need to decide

that the next position is in extend or in retract way.

A

Brinarpi:
Please give some idea how can i start.

If it was my problem I would do what I recommended in Reply #5

With a much shorter program {A} you might figure out what is needed and {B} it will be much easier to get help here.

...R

I try to do something, and with this solution its work.

It was left the slow down before reach a target. Please study this sketch, and help me in first steps, how can I define the slowing down.

A

``````#include <Button.h>
#include  <Encoder.h>

const int RELAY[] = {6,7};  //RELAY[0] and RELAY[1] to access the pins
const int BTN_EXTEND = 4;
const int BTN_RETRACT = 5;
const uint8_t MANUAL = 1;    //a constant to indicate manual mode
const uint8_t AUTOMATIC = 2; //a constant to indicate automatic mode
const int BTN_MEM_PIN[] = {8,9,10};
const int BTN_SET_MEM = 11;

Encoder myEnc(2, 3);
long oldPosition  = -999;
long targetPosition = 0;
#define ACCURACY 10

#define DEBOUNCE_MS 20
#define PULLUP true
#define INVERT true

uint8_t MODE = MANUAL;

Button btnExtend(BTN_EXTEND, PULLUP, INVERT, DEBOUNCE_MS);
Button btnRetract(BTN_RETRACT, PULLUP, INVERT, DEBOUNCE_MS);
Button btnSetPos(BTN_SET_MEM, PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos1(BTN_MEM_PIN[0], PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos2(BTN_MEM_PIN[1], PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos3(BTN_MEM_PIN[2], PULLUP, INVERT, DEBOUNCE_MS);

long memPosition[] = {0,0,0};

void setup() {
pinMode(RELAY[0], OUTPUT);
pinMode(RELAY[1], OUTPUT);

Serial.begin(9600);
}

void loop() {

if (btnExtend.isPressed()) {
extendActuator();
MODE = MANUAL;
}

if (btnRetract.isPressed()) {
retractActuator();
MODE = MANUAL;
}

if (!btnExtend.isPressed() && !btnRetract.isPressed() && MODE == MANUAL) {
stopActuator();
MODE = MANUAL;
}

if(btnPos1.wasReleased()) {
Serial.println("btnPos1");
MODE = AUTOMATIC;
targetPosition = memPosition[0] ;
}
if(btnPos2.wasReleased()) {
Serial.println("btnPos2");
MODE = AUTOMATIC;
targetPosition = memPosition[1] ;
}
if(btnPos3.wasReleased()) {
Serial.println("btnPos3");
MODE = AUTOMATIC;
targetPosition = memPosition[2] ;
}

//check the encoder to see if the position has changed
if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.println(newPosition);
}

if(MODE == AUTOMATIC && newPosition != targetPosition) {
Serial.print("Target/Actual:");Serial.print(targetPosition);Serial.print(" / ");Serial.print(newPosition);Serial.print(" [");Serial.print(abs(targetPosition - newPosition));Serial.println("]");
if(targetPosition < newPosition) {
Serial.println("AUTO RETRACT");
retractActuator();
MODE = AUTOMATIC;
}
if(targetPosition > newPosition) {
Serial.println("AUTO EXTEND");
extendActuator();
MODE = AUTOMATIC;
}
if( (targetPosition == newPosition) || abs(targetPosition - newPosition) <= ACCURACY) {
Serial.println("AUTO STOP");
stopActuator();
MODE = MANUAL;
}
}

if(btnPos1.isPressed()){
memPosition[0] = 1000;
}
if(btnPos2.isPressed()){
memPosition[1] = -1000;
}
if(btnPos3.isPressed()){
memPosition[2] = 10;

}
}

void extendActuator() {

digitalWrite(RELAY[0], HIGH);
digitalWrite(RELAY[1], LOW);
}

void retractActuator() {

digitalWrite(RELAY[0], LOW);
digitalWrite(RELAY[1], HIGH);
}

void stopActuator() {

digitalWrite(RELAY[0], HIGH);
digitalWrite(RELAY[1], HIGH);
}
``````

Brinarpi:
I try to do something, and with this solution its work.

It was left the slow down before reach a target. Please study this sketch, and help me in first steps, how can I define the slowing down.

That looks very like the code in Reply #2. It is certainly not simplified in the way that I suggested.

First thing is that you CANNOT control the speed of a DC motor if you are just controlling it with relays. Relays just permit ON/OFF control. If you want to control the speed of the motor you need a motor driver that can take a PWM signal from an anlaogWrite() instruction in your Arduino code.

By the way I assume the motor is thing called Actuator in your program.

How is the encoder connected to the motor?
How many encoder pulses per second will you be getting at maximum motor speed?

...R

Yes I already use a H bridge to move the motor instead of relays. The encoder was mounted on the geared shaft of the motor. The encoder was 360/rev. Ordinary chinese.

I try to do next:

void extendActuator() {

analogWrite(RELAY[0], 200);
analogWrite(RELAY[1], 0);
}

void retractActuator() {

analogWrite(RELAY[0], 0);
analogWrite(RELAY[1],100); //digitalWrite(RELAY[1], HIGH);
}

void stopActuator() {

analogWrite(RELAY[0],0);
analogWrite(RELAY[1], 0);
}

The motor is turning only in extend way. If I move retract back to digitalWrite it is working again. In extend with PWM, in retract with high speed. Also in MANUAL mode do the same.

It was be good if we split the MANUAL from AUTOMATIC and be able to set up speed separately. Also if I set up PWM in AUTOMATIC, it is working all the time with one setted PWM.

I think it is also a good solution if we do the job with only 2 PWM. To start with 255 and finish with 50(for example). The garage door motors do the same. Working with 2 voltage. 24 and 12VDC.

The question is how can I define where is the switching point between the fast and the slow motion.?

A

Brinarpi:
The motor is turning only in extend way. If I move retract back to digitalWrite it is working again. In extend with PWM, in retract with high speed. Also in MANUAL mode do the same.

This suggests to me that you need to go ALL THE WAY back to basics and just write a short program that moves the motor at medium speed in one direction for a few seconds and then in the other direction.

As you have not posted a link to the datasheet for your H-bridge I cannot suggest the details for that code but the overall style would be like this

``````void loop() {

analogWrite(motorReversePin,0);
analogWrite(motorForwardPin, 100);
delay(1000);

analogWrite(motorForwardPin, 0);
analogWrite(motorReversePin, 100);
delay(1000);
}
``````

Then you can experiment to find the range of speeds that you want to use.

And also experiment to count the pulses from the encoder and identify the motor direction

...R

Your sketch is in the loop. I dont want a loop, but I need to act on the button press.

I'll try to simplify as possible and come on next:

``````#include <Button.h>
#include  <Encoder.h>

const int RELAY0 =  6;
const int RELAY1 =  7;
const int BTN_EXTEND = 4;
const int BTN_RETRACT = 5;
const int BTN_MEM_PIN[] = {8,9,10};

Encoder myEnc(2, 3);
long oldPosition  = -999;
long targetPosition = 0;
#define ACCURACY 8

#define DEBOUNCE_MS 20
#define PULLUP true
#define INVERT true

Button btnPos1(BTN_MEM_PIN[0], PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos2(BTN_MEM_PIN[1], PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos3(BTN_MEM_PIN[2], PULLUP, INVERT, DEBOUNCE_MS);

long memPosition[] = {0,0,0};

void setup() {
pinMode(RELAY0, OUTPUT);
pinMode(RELAY1, OUTPUT);
analogWrite(RELAY0, 0);
analogWrite(RELAY1, 0);

Serial.begin(9600);
}

void loop() {
memPosition[0] = 100;
memPosition[1] = -100;
memPosition[2] = 0;

if(btnPos1.wasReleased()) {
Serial.println("btnPos1");
targetPosition = memPosition[0] ;

}
if(btnPos2.wasReleased()) {
Serial.println("btnPos2");
targetPosition = memPosition[1] ;
}
if(btnPos3.wasReleased()) {
Serial.println("btnPos3");
targetPosition = memPosition[2] ;
}

if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.println(newPosition);
}

if( newPosition != targetPosition) {
Serial.print("Target/Actual:");Serial.print(targetPosition);Serial.print(" / ");Serial.print(newPosition);Serial.print(" [");Serial.print(abs(targetPosition - newPosition));Serial.println("]");
if(targetPosition < newPosition) {
Serial.println("AUTO RETRACT");
retractActuator();

}
if(targetPosition > newPosition) {
Serial.println("AUTO EXTEND");
extendActuator();
}
if( (targetPosition == newPosition) || abs(targetPosition - newPosition) <= ACCURACY) {
Serial.println("AUTO STOP");
stopActuator();
}
}
}

void extendActuator() {

analogWrite(RELAY0, 50);
analogWrite(RELAY1, 0);

}

void retractActuator() {

analogWrite(RELAY0, 0);
digitalWrite(RELAY1, HIGH);

}

void stopActuator() {

analogWrite(RELAY0, 0);
analogWrite(RELAY1, 0);
delay(15);

}
``````

1.Please help to me what can I do to able to change in "void retractActuator" a digital write to analog becouse if I type in analog it does not wotk that way. Only like in the sketch is work.

A

Ohh Robin.
Now I check that the PWM is not working on pin 7. And moove to pin 5 and now its OK.

The other I think last problem is how can I implement in a memory position moovement 2 speeds. First 255 and then (for example) 50 to run into target.

Here is the last version with cut out everything possible?

``````#include <Button.h>
#include  <Encoder.h>

const int PWM0 =  6;
const int PWM1 =  5;
const int BTN_EXTEND = 4;
const int BTN_RETRACT = 5;
const int BTN_MEM_PIN[] = {8,9,10};

Encoder myEnc(2, 3);
long oldPosition  = -999;
long targetPosition = 0;
#define ACCURACY 1

#define DEBOUNCE_MS 20
#define PULLUP true
#define INVERT true

#define motorSpeed 50
#define motorSpeed1 50

Button btnPos1(BTN_MEM_PIN[0], PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos2(BTN_MEM_PIN[1], PULLUP, INVERT, DEBOUNCE_MS);
Button btnPos3(BTN_MEM_PIN[2], PULLUP, INVERT, DEBOUNCE_MS);

long memPosition[] = {0,0,0};

void setup() {
pinMode(PWM0, OUTPUT);
pinMode(PWM1, OUTPUT);
analogWrite(PWM0, 0);
analogWrite(PWM1, 0);

Serial.begin(9600);
}

void loop() {
memPosition[0] = 100;
memPosition[1] = -100;
memPosition[2] = 0;

if(btnPos1.wasReleased()) {
Serial.println("btnPos1");
targetPosition = memPosition[0] ;

}
if(btnPos2.wasReleased()) {
Serial.println("btnPos2");
targetPosition = memPosition[1] ;
}
if(btnPos3.wasReleased()) {
Serial.println("btnPos3");
targetPosition = memPosition[2] ;
}

if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.println(newPosition);
}

if( newPosition != targetPosition) {

if(targetPosition < newPosition) {
retractActuator();

}
if(targetPosition > newPosition) {
extendActuator();
}
if( (targetPosition == newPosition) || abs(targetPosition - newPosition) <= ACCURACY) {
stopActuator();
}
}
}
void retractActuator() {

analogWrite(PWM0, 0);
analogWrite(PWM1, motorSpeed1);

}

void extendActuator() {

analogWrite(PWM0, motorSpeed);
analogWrite(PWM1, 0);

}

void stopActuator() {

analogWrite(PWM0, 0);
analogWrite(PWM1, 0);
delay(15);

}
``````

Brinarpi:
Your sketch is in the loop. I dont want a loop, but I need to act on the button press.

I know that. But you need to start with the simplest possible program.

Brinarpi:
Here is the last version with cut out everything possible?

IMHO it still has far too much irrelevant stuff in it.

When I develop a program I do it in the tiniest of steps.

• Get the motor speed control working based on values in program variables (no user data entry).
• Add a little bit to read the encoder data and show it on the Serial Monitor
• Add a little bit more to see if I can use the encoder data to get the motor to stop at a specific place
• Add a little bit to learn how to ramp the speed up and down depending on the encoder values

Note that none of that has anything to do with buttons. Leave that for another day

...R

Ok Robin.

I am not afraid to start from a begining, but I am not skilled enough to do it from myself. If You help to me in steps(as you post) I am ready to start with step by step.

If You remember my project before(wich is ready thaks to You) I learn a lot of things, but this is something else(other area with PWM, accel/decel, encoder etc.

Your simple sketch is the base. If I come on something with that I will post it.

First thing:

"Get the motor speed control working based on values in program variables (no user data entry)."

I dont understand exacly what do you mean with program variables?

Brinarpi:
First thing:

"Get the motor speed control working based on values in program variables (no user data entry)."

I dont understand exacly what do you mean with program variables?

I just mean something like this

``````byte motorSpeed = 123;
byte motorFwdPin = 5;
byte motorRevPin = 6;

void setup() {
pinMode(motorFwdPin, OUTPUT);
pinMode(motorRevPin, OUTPUT);
analogWrite(motorRevPin, 0);
analogWrite(motorFwdPin, motorSpeed);
}

void loop() {

}
``````

But you still have not posted a link to the motor driver you are using so that code may not be suitable.

...R

I posted in No.13 please check.

Sorry, I missed that. The link says

2.ENA1 is motor enable port,can connect with PWM to adjust 1# motor speed;ENA2 can regulate speed for 2# motor
3.IN1,IN2 can control 1# motor positive/negative rotate,braking,trigging;IN3,IN4 can control 2# motor

which would require slightly different code. Something like this

``````byte motorSpeed = 123;
byte motorSpeedPin = 6;
byte motorFwdPin = 7;
byte motorRevPin = 8;

void setup() {
pinMode(motorSpeedPin, OUTPUT);
pinMode(motorFwdPin, OUTPUT);
pinMode(motorRevPin, OUTPUT);
digitalWrite(motorRevPin, 0);
digitalWrite(motorFwdPin, 1);
analogWrite(motorSpeedPin, motorSpeed);
}

void loop() {

}
``````

...R