Controlling Servos with Arduino - arduino

I am trying to control a small servo motor with an Arduino and I am running into a problem where the Servo continuously runs even when I want it to stop. I have pasted a picture of my code below. The for loops should make the Servo stop when it rotates 180 degrees, but it just keeps spinning.
I am trying to control the direction of the servos using the Serial monitor as input.
#include <Servo.h>
Servo myservo;
int i = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
myservo.attach(9);
}
void loop() {
// put your main code here, to run repeatedly:
keyboardControl();
}
void keyboardControl() {
if (Serial.available() > 0) {
int data = Serial.read();
switch (data) {
case '1' :
for (i = 0; i <= 180; i += 1) {
myservo.write(i);
delay(15);
if (i = 180) {
break;
}
case '2':
for (i = 180; i >= 0; i -= 1) {
myservo.write(i);
delay(15);
break;
}
}
}
}
}

I would give this code a try:
void stop()
{
while(1 = 180);
}

Related

How to control the display and non-display of sensor values ​in Arduino using Bluetooth?

I have a sensor that connects to the body and displays muscle signals.
In the setup guide of this sensor, it is said to upload the following code on Arduino, and when we open the Serial Monitor, the sensor values start to be displayed.
Now I want to control the display of these signals using Bluetooth.
So that when I click on the start button in my App, Serial.print() will start working. Also, when I click on the Stop button, the display of these signals and numbers will stop.
Sensor setup guide is this :
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(analogRead(A0));
}
And this is how it works properly :
But when I upload a piece of code that I wrote to my Arduino, it only shows me just on value.
this is my code :
#include <SoftwareSerial.h>
SoftwareSerial BTserial(0, 1); // RX | TX
char Incoming_value = 0;
void setup() {
Serial.begin(9600);
BTserial.begin(9600);
}
void loop() {
Incoming_value = Serial.read(); // "1" is for Start
if (Incoming_value == '1') {
Serial.println(Incoming_value);
StartSensor();
}
}
int StartSensor() {
int sensorValue = analogRead(A0);
Serial.println(sensorValue);
delay(200);
}
also please tell me How to write StopSensor Function for Stop print Sensor Value.
Try this code first (Without Bluetooth module)
#include <SoftwareSerial.h>
SoftwareSerial BTserial(0, 1); // RX | TX
char Incoming_value = 0;
int state = 0;
void setup() {
Serial.begin(9600);
//BTserial.begin(9600);
}
void loop() {
Incoming_value = Serial.read(); // "1" is for Start
if (Incoming_value == '1') {
state = 1;
}
else if (Incoming_value == '0') {
state = 0;
}
if (state == 1) {
StartSensor();
} else {
Serial.println(0);
}
}
int StartSensor() {
int sensorValue = analogRead(A0);
Serial.println(sensorValue);
delay(200);
}

issue with Arduino using FastLed with IRremote change mode

Hi I am trying to build a arduino project to control led strip and change the light pattern when pressed different button
the code i am using is
#include <IRremote.h> //include the library
#include <FastLED.h>
// How many leds in your strip?
#define NUM_LEDS 70
#define DATA_PIN 3
#define CLOCK_PIN 13
#define Button_0 0xFF9867
#define Button_1 0xFFA25D
#define Button_2 0xFF629D
#define Button_3 0xFFE21D
#define Button_4 0xFF22DD
#define Button_5 0xFF02FD
#define Button_6 0xFFC23D
#define Button_7 0xFFE01F
#define Button_8 0xFFA857
#define Button_9 0xFF906F
int receiver = 7; //initialize pin 13 as recevier pin.
IRrecv irrecv(receiver); //create a new instance of receiver
decode_results results;
CRGB leds[NUM_LEDS];
void setup() {
Serial.begin(9600);
LEDS.addLeds<WS2812,DATA_PIN,RGB>(leds,NUM_LEDS);
LEDS.setBrightness(84);
irrecv.enableIRIn(); //start the receiver
}
void loop() {
if (irrecv.decode(&results)) { //if we have received an IR signal
Serial.println (results.value, HEX); //display HEX results
irrecv.resume(); //next value
if (results.value == Button_0) {
RunningLightSlow();
}
else if(results.value == Button_1) {
RainbowLights();
}
// switch (results.value) {
//
// case Button_0: RunningLightSlow(); break;
// case Button_1: RainbowLights(); break;
// }
}
}
// LIGHTSHOW 0 starts --------------------------------------------------------------------------------------------------
void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } }
void RunningLightSlow() {
while(1) {
static uint8_t hue = 0;
Serial.print("x");
// First slide the led in one direction
for(int i = 0; i < NUM_LEDS; i++) {
// Set the i'th led to red
leds[i] = CHSV(hue++, 255, 255);
// Show the leds
FastLED.show();
// now that we've shown the leds, reset the i'th led to black
// leds[i] = CRGB::Black;
fadeall();
// Wait a little bit before we loop around and do it again
delay(10);
}
Serial.print("x");
// Now go in the other direction.
for(int i = (NUM_LEDS)-1; i >= 0; i--) {
// Set the i'th led to red
leds[i] = CHSV(hue++, 255, 255);
// Show the leds
FastLED.show();
// now that we've shown the leds, reset the i'th led to black
// leds[i] = CRGB::Black;
fadeall();
// Wait a little bit before we loop around and do it again
delay(10);
}
}
}
// LIGHTSHOW 0 ends --------------------------------------------------------------------------------------------------------
// LIGHTSHOW 1 STARTS ------------------------------------------------------------------------------------------------------
void RainbowLights() {
randomSeed(millis());
int wait=random(10,30);
int dim=random(4,6);
int max_cycles=8;
int cycles=random(1,max_cycles+1);
while(1) {
rainbowCycle(wait, cycles, dim);
}
}
void rainbowCycle(int wait, int cycles, int dim)
{
Serial.println("Let's make a rainbow.");
//loop several times with same configurations and same delay
for(int cycle=0; cycle < cycles; cycle++)
{
byte dir=random(0,2);
int k=255;
//loop through all colors in the wheel
for (int j=0; j < 256; j++,k--)
{
if(k<0)
{
k=255;
}
//Set RGB color of each LED
for(int i=0; i<NUM_LEDS; i++)
{
CRGB ledColor = wheel(((i * 256 / NUM_LEDS) + (dir==0?j:k)) % 256,dim);
leds[i]=ledColor;
}
FastLED.show();
FastLED.delay(wait);
}
}
}
CRGB wheel(int WheelPos, int dim)
{
CRGB color;
if (85 > WheelPos)
{
color.r=0;
color.g=WheelPos * 3/dim;
color.b=(255 - WheelPos * 3)/dim;;
}
else if (170 > WheelPos)
{
color.r=WheelPos * 3/dim;
color.g=(255 - WheelPos * 3)/dim;
color.b=0;
}
else
{
color.r=(255 - WheelPos * 3)/dim;
color.g=0;
color.b=WheelPos * 3/dim;
}
return color;
}
Now the issue i am facing is when i press a button (for eg 0) it runs the function RunningLightSlow(); i have written the infinite loop code because i want infinite light show and when i press button 1 it does not change the light pattern ,
Root cause would be once the function goes into infinite loop it then never receives the ir signal and hence never change the light pattern
Remove all infinite loops from your program and create a simple structure in loop() where you check for IR signal and update a "state" variable with the last button pressed.
void loop() {
// create a function or add here whatever is needed to read the IR code
irCode = readIrCode();
// check if the new code is identical to a previous code
if (lastIrCode != irCode) {
// memorize the current code
lastIrCode = irCode;
/ act according to user selection
switch (irCode) {
case Button_0:
doThis(); // this could be your RunningLightSlow()
break;
case Button_1:
doThat(); // maybe RainbowLights()
break;
default:
// for cases you have not handled above
doWhatever();
}
}
}
Do not forget to remove the infinite loops from the functions that run the lights and obviously you would need to declare the variables and set the correct calls.

Servo rotating infinitely when I want it to do so only once

I am very new to Arduino. I want to make a simple setup, in which, pressing a button on a remote will make the servo rotate 90 degree and come back to 0.
Here is my code:
#include <Servo.h>
#include <IRremote.h>
int receiver = 13;
IRrecv irrecv(receiver);
decode_results results;
Servo myServo;
int pos = 0;
void setup() {
// put your setup code here, to run once:
myServo.attach(9);
Serial.begin(9600);
irrecv.enableIRIn();
myServo.write(0);
delay(200);
}
void loop() {
// put your main code here, to run repeatedly:
if (irrecv.decode(&results)){
if (results.value== 0xC0000C){
for (pos = 0; pos <= 90; pos += 1) {
// in steps of 1 degree
myServo.write(pos);
delay(15);
}
for (pos = 90; pos >= 0; pos -= 1) {
myServo.write(pos);
delay(15);
}
}
}
delay(100);
}
However, when I press the button assigned, the servo keeps swinging from 0 to 90 degree and back infinitely, but I only want it to do so once, each time the button is pressed. How do I do that?
You need to add the line
irrecv.resume();
to the end if loop just before that final delay in order to clear out the results and start looking for a new signal.
void loop() {
// put your main code here, to run repeatedly:
if (irrecv.decode(&results)){
if (results.value== 0xC0000C){
for (pos = 0; pos <= 90; pos += 1) {
// in steps of 1 degree
myServo.write(pos);
delay(15);
}
for (pos = 90; pos >= 0; pos -= 1) {
myServo.write(pos);
delay(15);
}
}
}
irrecv.resume();
delay(100);
}

arduino interrupts with servo motor

currently am working on project to open a door with access code using arduino UNO and a servo motor. Normal operation requires entering access code using keypad which is working fine. Another option requires pressing a button that causes an interrupt to rotate the servo motor. My problem is my interrupt only works once and never works again. Plus how do i put the for-loop to rotate the servo motor inside the interrupt function with a delay. I know that is not possible but am calling another function that has the delayMicroseconds but all this is not working. Below is my implementation please help
#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Servo.h>
Servo servo;
const int openButtonPin = 2;
void setup() {
// put your setup code here, to run once:
servo.attach(5);
pinMode(openButtonPin, INPUT); //Pin 2 is input
attachInterrupt(0, enforceOpenAccess, HIGH); // PIN 2
}
void(* resetFunc)(void) = 0;
void loop()
{
//My other keypad implementations go here
}
void myDelay(int x) // function to cause delay in the interrupt
{
for(int i = 0; i<x; i++)
{
delayMicroseconds(1000);
}
}
void enforceOpenAccess() // ISR
{
for(int k =0; k<=180; k+=2)
{
servo.write(k); //rotate the servo
myDelay(30); //delay the rotation of the servo
}
}
The code above is run on arduino UNO being simulated in proteus and the interrupt button is a push button. Please if there is other ways of implementing that but with the same behaviour as I have described above help out. Thanks a lot
There are a couple of problems in the slice of code you posted. Just for completeness, you should post the loop function, since we can't guess what you wrote inside.
Just one comment: did you put a pullup? Otherwise use INPUT_PULLUP instead of INPUT for the button pinmode.
The main one is that you attached the interrupt for the HIGH mode, which will trigger the interrupt any time the pin is up, not on the rising edge. And please use the macro digitalPinToInterrupt to map to the correct pin:
attachInterrupt(digitalPinToInterrupt(openButtonPin), enforceOpenAccess, RISING);
Then.. Let's improve the code. You really should use the interrupts only when strictly necessary when you have to respond IMMEDIATELY (= less than a couple of milliseconds) to an input. Here you don't have to, so it's MUCH better to check for the button in the loop (more on turning the motor following)
uint8_t lastState;
void setup()
{
...
lastState = LOW;
}
void loop()
{
uint8_t currentState = digitalRead(openButtonPin);
if ((currentState != lastState) && (currentState == HIGH))
{
// Start turning the motor
}
lastState = currentState;
...
}
This will enable you to properly debounce the button too:
#include <Bounce2.h>
Bounce debouncer = Bounce();
void setup()
{
...
pinMode(openButtonPin, INPUT); //Pin 2 is input
debouncer.attach(openButtonPin);
debouncer.interval(5); // interval in ms
}
void loop()
{
debouncer.update();
if (debouncer.rose())
{
// Start turning the motor
}
...
}
If, on the other way, you REALLY want to use the interrupts (because waiting for a couple of milliseconds is too much for you), you should do something like this:
#include <Bounce2.h>
Bounce debouncer = Bounce();
void setup()
{
...
pinMode(openButtonPin, INPUT);
attachInterrupt(digitalPinToInterrupt(openButtonPin), enforceOpenAccess, RISING);
}
void loop()
{
...
}
void enforceOpenAccess() // ISR
{
// Start turning the motor
}
It looks like your code? No, because now we'll speak about turning the motor
You should NOT use delays to make steps, because otherwise you will wait for 30ms * 180 steps = 5.4s before being able to do anything else.
You can, however, make a sort of reduced state machine. You want your servo to move from 0 to 180 in steps of 1. So let's code the "don't move" state with any value greater than 180, and consequently we can do something like this in the loop:
unsigned long lastServoTime;
uint8_t servoPosition = 255;
const int timeBetweenSteps_in_ms = 30;
void loop()
{
...
if (servoPosition <= 180)
{ // servo should move
if ((millis() - lastServoTime) >= timeBetweenSteps_in_ms)
{
lastServoTime += timeBetweenSteps_in_ms;
servoPosition++;
if (servoPosition <= 180)
servo.write(servoPosition);
}
}
}
Then, using any of the previous examples, instead of // Start turning the motor write
lastServoTime = millis();
servoPosition = 0;
servo.write(servoPosition);
This way you won't block the main loop even when the button is pressed
This is what is in my loop()
char key = keypad.getKey();
if(key)
{
if(j < 10)
{
studentNumber[j] = key;
//holdMaskedNumber[j] = '*';
lcd.setCursor(0,2);
lcd.print(String(studentNumber));
if(j == 9)
{
studentNumber[9] = '\0';
//holdMaskedNumber[9] = 0;
lcd.clear();
//String number = String(studentNumber);
//lcd.print(number);
//delay(1000);
//lcd.clear();
lcd.print("Access Code");
}
j++;
}
else
{
if(i < 5)
{
accessCode[i] = key;
holdMaskedCode[i] = '*';
lcd.setCursor(1,2);
lcd.print(String(holdMaskedCode));
if(i == 4)
{
holdMaskedCode[5] = '\0';
accessCode[5] = '\0';
//lcd.clear();
//lcd.setCursor(0,0);
//accessCodeString = String(accessCode);
//lcd.print(accessCodeString);
//delay(1000);
lcd.clear();
for(int i =0; i<6; i++)
{
lcd.print("Please wait.");
delay(500);
lcd.clear();
lcd.print("Please wait..");
delay(500);
lcd.clear();
lcd.print("Please wait...");
delay(500);
lcd.clear();
}
digitalWrite(4, HIGH);
lcd.print("Access Granted");
for(int k =0; k<=180; k+=2)
{
servo.write(k);
delay(30);
}
resetFunc();
}
i++;
}
}
}

Making a Game With Arduino and Processing

I am trying to form a two player game which requires an audio reflex to a visual. by using littebits sound trigger for sound input and littbits arduino to connect it to the computer. But I am new to this and don't know how to connect arduino to processing and use the input from sound trigger to effect the score when a black square appears.
here is my code in processing and a sample arduino code I have taken from littlebits website and tried to modify a little.
thanks in advance!
float dice;
int playerOne = 0; //player 1 score (left paddle)
int playerTwo = 0; //player 2 score (right paddle)
boolean oneWins = false;
boolean twoWins = false;
void setup(){
size(500, 500);
smooth();
noStroke();
frameRate(2.5);
}
void draw() {
background(255);
showGUI();
dice = random(0, 3);
if (dice < 1.000001 && dice > 0.1){
fill ((0), (255), (0));
ellipse (250,250,100,100);
} else if (dice < 2.000001 && dice > 1.000001){
rectMode(RADIUS);
fill ((255), (0), (0));
rect (250,250,50,50);
} else if (dice < 3.000000 && dice > 1.000000){
rectMode(RADIUS);
fill ((0), (0), (255));
rect (250,250,50,50);
} else if (dice < 0.1){
rectMode(RADIUS);
fill(0);
rect(250,250,50,50);
}
}
----------arduino------
void setup() {
Serial.begin(9600); //Establish rate of Serial communication
establishContact(); //See function below
}
void loop() {
if (Serial.available() > 0) {
int inByte = Serial.read();
int leftTrigger = analogRead(A0);
Serial.print(leftTrigger, DEC);
Serial.print(",");
int rightTrigger = analogRead(A1);
Serial.println(rightTrigger, DEC);
}
}
void establishContact() {
while (Serial.available() <= 0) {
Serial.println("hello");
delay(300);
}
}
You need two pieces of code for this to work: one on the Arduino that sends commands, and one for Processing to receive and parse those commands.
I haven't used the littlebits modules, but here's a button example from this very detailed tutorial.
Arduino code:
int switchPin = 4; // switch connected to pin 4
void setup() {
pinMode(switchPin, INPUT); // set pin 0 as an input
Serial.begin(9600); // start serial communication at 9600bps
}
void loop() {
if (digitalRead(switchPin) == HIGH) { // if switch is ON,
Serial.print(1, BYTE); // send 1 to Processing
} else { // if the switch is not ON,
Serial.print(0, BYTE); // send 0 to Processing
}
delay(100); // wait 100 milliseconds
}
And the matching Processing code:
import processing.serial.*;
Serial port; // create object from Serial class
int val; // data received from the serial port
void setup() {
size(200, 200);
frameRate(10);
// open the port that the board is connected to
// and use the same speed (9600bps)
port = new Serial(this, 9600);
}
void draw() {
if (0 < port.available()) { // if data is available,
val = port.read(); // read it and store it in val
}
background(255); // set background to white
if (val == 0) { // if the serial value is 0,
fill(0); // set fill to black
} else { // if the serial value is not 0,
fill(204); // set fill to light gray
}
rect(50, 50, 100, 100);
}
Notice that the Arduino sends a value that Processing looks for and interprets. You can also look at the PhysicalPixel example from the Arduino IDE for an example on sending data from Processing to Arduino.

Resources