I'm currently trying to make a RC car on Arduino and facing the following issue, where I'm unable to reset the L298P Motor Driver (By Keyes) Shield to stop motor from moving (Using only one motor at Motor B port).
Basically, the motor sticks to one direction rotating and not stopping when JoyStick's position is resetted.
Here's the current code I'm using. (Also Includes my pathetic trials).
#include <Servo.h>
Servo myservo;
#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 5, 6, 7, 8);
int JoyStick_X = 0; //Analog
int JoyStick_Y = 1; //Analog
int JoyStick_Z = 1; //Digital
int SpeedPin = 11;
int Direction = 13;
void setup(void) {
myservo.attach(9);
lcd.begin(16, 2);
lcd.clear();
pinMode(JoyStick_Z, INPUT_PULLUP);
pinMode(Direction, OUTPUT);
Serial.begin(9600);
}
void loop(void) {
int x, y, z;
x = analogRead(JoyStick_X);
y = analogRead(JoyStick_Y);
z = digitalRead(JoyStick_Z);
lcd.setCursor(0, 0);
lcd.print("Car Status");
lcd.setCursor(0, 1);
lcd.print("Spd:");
lcd.print(x);
/* if (z == 0) {
lcd.print("High");
}
else if (z == 0 && x < 250) {
lcd.print("RHgh");
}
else if (x > 510 && x < 530) {
lcd.print("No ");
}
else if (x > 530 && x < 730) {
lcd.print("Low ");
}
else if (x > 730) {
lcd.print("Med ");
}
else if (x < 510 && x > 250) {
lcd.print("RLow");
}
else if (x < 250) {
lcd.print("RMed");
}*/
lcd.print(" ");
lcd.setCursor(10, 1);
lcd.print("Trn:");
if (y < 500) {
lcd.print("L ");
}
else if (525 > y && y > 500) {
lcd.print("-");
}
else if (y > 525) {
lcd.print("R ");
}
lcd.setCursor(11, 0);
lcd.print("Bst:");
if (z == 0) {
lcd.print("Y");
}
else {
lcd.print("N");
}
myservo.write(40 + y * 8.7890625 / 100);
if (x > 530) {
digitalWrite(Direction, HIGH);
}
else if (x < 510) {
digitalWrite(Direction, LOW);
}
if (x > 510 && x < 530) {
digitalWrite(0, 0);
}
//int speed = ((0.520408 * x ) - 275.816326 );
analogWrite(SpeedPin, 255);
/*int value = 255;
digitalWrite(M1,LOW);
analogWrite(E1, value);*/
/*var n;
switch (n)
{
case 1:
digitalWrite(Direction, HIGH);
break;
case 2:
digitalWrite(Direction, LOW);
break;
default:
digitalWrite(0, 0);
}*/
}
I think you're missing analogWrite(SpeedPin, 0); somewhere in your code. Since SpeedPin seems to be how you're controlling speed, you need to write a zero to it to stop.
Related
I'm using Arduino to control a project which contains addressable LEDs and buttons.
The libraries I'm using are in the title.
For an unknown reason, when I use each code separately everything works fine, but when I combine them the FastLED library blocks the button reading and causes weird things - like giving double press, or stop doing other things.
How can I fix the issue? (I tried to eliminate the delay(), but it wasn't helpful)
Thanks in advance!
/*
Author: Yuval Kedar - KD Technology
Instagram: https://www.instagram.com/kd_technology/
Date: Oct 19
Dev board: Arduino Uno
There are two button types: Red and Blue.
Red btn = -1
Blue btn = +1
On the machine's background there is an LED matrix which shows the user's progress.
There are 4 levels (square frames) until one reaches the core and wins.
The trick? The floor, which includes the buttons, is spinning.
*/
#include <FastLED.h>
#include <ezButton.h>
#include "Arduino.h"
#define WINNING_SENSOR_PIN (12)
#define LED_DATA_PIN (6)
#define BLUE_BTN_PIN (A0)
#define RED_BTN_PIN (A3)
#define SERIAL_BAUDRATE (115200)
#define NUM_LEDS (64)
#define LED_BRIGHTNESS (200)
#define WINNING_FX_TIME (1000)
ezButton blue_btn(BLUE_BTN_PIN);
ezButton red_btn(RED_BTN_PIN);
CRGB leds[NUM_LEDS];
uint8_t score = 0;
uint8_t last_score = 0;
uint8_t level[] = {0, 28, 48, 60, 63}; //levels 0 to 4
void level_up(uint8_t led_num) {
uint8_t start_point = 0;
if (led_num == level[1]) start_point = 0; //up from level 0 to 1
if (led_num == level[2]) start_point = 28; //up from level 1 to 2
if (led_num == level[3]) start_point = 48; //up from level 2 to 3
if (led_num == level[4]) start_point = 60; //...
for (uint8_t current_pixel = start_point; current_pixel < led_num; current_pixel++) {
leds[current_pixel] = CRGB::Blue;
FastLED.show();
delay(50);
}
delay(2500); //debounce
}
void level_down(uint8_t led_num) { //clear prev level's frame and do the opposite direction effect with red color
uint8_t start_point = 0;
if (led_num == level[0]) start_point = 28; //down from level 1 to 0
if (led_num == level[1]) start_point = 48; //down from level 2 to 1
if (led_num == level[2]) start_point = 60; //down from level 3 to 2
if (led_num == level[3]) start_point = 63; //...
for (int8_t i = start_point - 1; i > led_num; i--) {
leds[i] = CRGB::Red;
FastLED.show();
delay(50);
}
for (int8_t i = start_point - 1; i > led_num; i--) {
leds[i] = CRGB::Black;
FastLED.show();
}
delay(2500); //debounce
}
void fadeall() {
for(uint8_t i = 0; i < NUM_LEDS; i++) {
leds[i].nscale8(250);
}
}
void winning() {
static uint8_t hue = 0;
for(uint8_t x = 0; x < 5; x++) {
for(int8_t i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(hue++, 255, 255);
FastLED.show();
fadeall();
// delay(10);
}
for(int8_t i = (NUM_LEDS)-1; i >= 0; i--) {
leds[i] = CHSV(hue++, 255, 255);
FastLED.show();
fadeall();
// delay(10);
}
}
}
void reset_game() {
score = 0;
last_score = 4;
digitalWrite(WINNING_SENSOR_PIN, LOW);
FastLED.clear();
FastLED.show();}
void winning_check() {
(score == 4) ? analogWrite(WINNING_SENSOR_PIN, 175) : digitalWrite(WINNING_SENSOR_PIN, LOW);
}
void update_score() {
if (blue_btn.isPressed()) {
Serial.println("+PLUS+");
if (score++ >= 4) score = 4;
}
if (red_btn.isPressed()) {
Serial.println("-MINUS-");
if (score-- <= 0) score = 0;
}
if (score == 0){
if (last_score == 1) level_down(level[0]);
last_score = 0;
digitalWrite(WINNING_SENSOR_PIN, LOW);
}
else if (score == 1) {
if (last_score == 0) level_up(level[1]); // if last_score was 0 make the blue effect because level is up
if (last_score == 2) level_down(level[1]); // if last_score was 2 make the red effect because level is down
last_score = 1;
digitalWrite(WINNING_SENSOR_PIN, LOW);
}
else if (score == 2) {
if (last_score == 1) level_up(level[2]);
if (last_score == 3) level_down(level[2]);
last_score = 2;
digitalWrite(WINNING_SENSOR_PIN, LOW);
}
else if (score == 3) {
if (last_score == 2) level_up(level[3]);
if (last_score == 4) level_down(level[3]);
last_score = 3;
digitalWrite(WINNING_SENSOR_PIN, LOW);
}
else if (score == 4) {
winning_check();
// winning(); //this func makes issue when using ezButton.h. It calls "show" too many times.
reset_game();
}
}
void setup() {
Serial.begin(SERIAL_BAUDRATE);
pinMode(WINNING_SENSOR_PIN, OUTPUT);
digitalWrite(WINNING_SENSOR_PIN, LOW);
blue_btn.setDebounceTime(150);
red_btn.setDebounceTime(150);
FastLED.addLeds<NEOPIXEL, LED_DATA_PIN>(leds, NUM_LEDS); // GRB ordering is assumed
FastLED.setBrightness(LED_BRIGHTNESS);
FastLED.clear();
FastLED.show();
Serial.println(F(
"_______________________________\n"
"\n"
" G e a r M a c h i n e \n"
"_______________________________\n"
"\n"
" ~ Made by KD Technology ~ \n"
"\n"));
}
void loop() {
blue_btn.loop();
red_btn.loop();
Serial.println(score);
update_score();
FastLED.show();
}
The reason is that, you used the delay() function. If you use the delay, some pressed events will be missed, not only for ezButton, but also for any kind of button press implementation. The ezButton already has the internal debounce function.
I am trying to create a simple project using Blynk on D1 Mini where I can select any animation any time and that should play unless I stop that using my Blynk App. While everything else working perfectly, I am not able to figure out what is wrong on my theaterchaserainbow function, that while selected, my D1 gets disconnected and connected again. Here is the code.
I understood from various forum that I must use blynk.timer instead and set count more than 1000L in setup. But that won't help me either for this particular theaterchaserainbow function. All other functions works perfectly. Any help would be greatly appreciated.
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Adafruit_NeoPixel.h>
#include <wifi_credentials.h>
#define BLYNK_PRINT Serial
#define myPixelPin D2
#define myPixels 16
char auth[] = "xxxxxxxmy_authxxxxxx";
int select;
BlynkTimer timer;
// Instatiate the NeoPixel from the ibrary
Adafruit_NeoPixel strip = Adafruit_NeoPixel(myPixels, myPixelPin, NEO_GRB + NEO_KHZ800);
// Timer to repeat animations
void myTimerEvent() {
if (select == 1) {
allOff();
} else if (select == 12) {
theaterChaseRainbow(50);
}
}
// NeoPixel all off Switch
BLYNK_WRITE(V0) {
int pinValue = param.asInt();
select = 1;
}
// Menu based Animation Selection
BLYNK_WRITE(V1) {
int pinValue = param.asInt();
switch (pinValue) {
case 1: // Item 1
select = 11;
break;
case 2: // Item 2
select = 12;
break;
}
}
void setup()
{
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
strip.begin();
strip.show();
timer.setInterval(1000L, myTimerEvent);
}
void loop() {
Blynk.run();
timer.run(); // Initiates BlynkTimer;
}
// Theatre Chase Rainbow
//*****************************************************************************
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Clear Program
//*****************************************************************************
void allOff() {
for ( int i = 0; i < strip.numPixels(); i++ ) {
strip.setPixelColor(i, 0, 0, 0 );
}
strip.show();
}
// Default Wheel defination
//*****************************************************************************
uint32_t Wheel(byte WheelPos) {
if (WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
I'm getting :
invalid types 'int[int]' for array subscript
when I try to compile my code for my Arduino and for the life of me I can't figure out what I'm doing wrong.
Here's my code (feel free to use it although it isn't done yet).
/*
* Changelog 0.5
* pins[], pinFV[], pinV[], pinDelay[] moved
* to pins[][]
*/
int analogPins[6] = {A0, A1, A2, A3, A4, A5};
int pins[4][4];
int mode = 0;
void setup() {
int x = 6;
do {
pinMode(analogPins[x], INPUT);
x--;
} while (x > 0);
int pins[4] = {9, 5, 6, 3};
x = 4;
do {
pinMode(pins[0][x], INPUT);
x--;
} while (x > 0);
x = 4;
do{
pins[1][x] = random(5, 10);
x--;
}while(x>0);
x = 4;
do{
pins[2][x] = random(50, 75);
x--;
}while(x>0);
x = 4;
do{
pins[3][x] = 255;
x--;
}while(x>0);
//this is the section causing the problem
pins[0][0] = 8;
pins[0][1] = 9;
pins[0][2] = 10;
pins[0][3] = 11;
//end section
pinMode(8, OUTPUT);
Serial.begin(19200);
}
void readAnalogDecode() {
//analogAverage(pin);
//elseIf statements to set what mode to use
//catch anything out of bounds for mode select
if (analogRead(A5) > 800 || analogRead(A5) < 0) {
mode = 0;
}
if (analogRead(A5) > 4 && analogRead(A5) < 8) {
mode = 0;
}
if (analogRead(A5) > 8 && analogRead(A5) < 15) {
mode = 1;
}
if (analogRead(A5) > 15 && analogRead(A5) < 20) {
mode = 2;
}
if (analogRead(A5) > 20 && analogRead(A5) < 26) {
mode = 3;
}
if (analogRead(A5) > 26 && analogRead(A5) < 47) {
mode = 4;
}
if (analogRead(A5) > 47 && analogRead(A5) < 185) {
mode = 5;
}
if (analogRead(A5) > 185 && analogRead(A5) < 345) {
mode = 6;
}
}
void pinFader(int pin, int value) {
digitalWrite(8, LOW);
if (pins[3][pin] < value) {
do {
pins[3][pin] = pins[3][pin] + pins[1][pin];
if (pins[3][pin] > 255) {
pins[3][pin] = 255;
}
Serial.println(analogRead(A5));
Serial.println(" ");
Serial.println(analogRead(A4));
analogWrite(pins[0][pin], pins[3][pin]);
digitalWrite(8, LOW);
delay(pins[2][pin]);
} while (pins[3][pin] < value);
}
if (pins[3][pin] > value) {
do {
pins[3][pin] = pins[3][pin] - pins[1][pin];
if (pins[3][pin] < 0 ) {
pins[3][pin] = 0;
}
digitalWrite(8, LOW);
analogWrite(pins[0][pin], pins[3][pin]);
delay(pins[2][pin]);
} while (pins[3][pin] > value);
}
}
void loop() {
Serial.println(" " );
Serial.print(analogRead(A0));
Serial.print(" " );
Serial.print(analogRead(A1));
Serial.print(" " );
Serial.print(analogRead(A2));
Serial.print(" " );
Serial.print(analogRead(A3));
Serial.print(" " );
Serial.print(analogRead(A4));
Serial.print(" " );
Serial.print(analogRead(A5));
Serial.print(" " );
Serial.print(mode);
readAnalogDecode();
if (mode == 0) {
pinFader(1, 255); //no green
pinFader(2, 255); //no red
pinFader(1, 0); //green on
pinFader(3, 255); //no blue
pinFader(2, 0); //red on
pinFader(1, 255); //no green
pinFader(3, 0); //blue on
pinFader(1, 0); //green on
readAnalogDecode();}
if (mode == 1) {
analogWrite(9, 0);
delay(500);
analogWrite(9, 255);
/* delay(500);
analogWrite(10, 0);
delay(500);
analogWrite(10, 255);
delay(500);
analogWrite(11, 0);
delay(500);
analogWrite(11, 255);
*/delay(500);
readAnalogDecode();
}
}
Is this not how to assign a value to a 2-d array? pins[0][0] = 8;
I apologize in advance if the problem is related to syntax. I'm used to java and python.
You have 2 arrays with the same name. Inside setup the local one is the one that is referred to and it isn't a 2D array so you can't use it as such.
At global scope:
int pins[4][4];
And inside setup:
int pins[4] = {9, 5, 6, 3};
Try naming one of them something different. Having two things with the same name can be terribly confusing.
I have a question about my Arduino Leonardo. What I want to do with my Arduino is that the higher the value of AnalogWrite is, the more lights will go on. I've used a if else statement but I need a 'until value' function. Now all the lights will go on because I only used a < > but not a value from 0 till 50, 50 till 100 etc. Can somebody figure out how I need to write this?
int analogInPin = A3;
int sensorValue = 0;
int ledPin1 = 3;
int ledPin2 = 5;
int ledPin3 = 6;
int ledPin4 = 9;
int ledPin5 = 10;
int analogPin = 3;
void setup() {
Serial.begin(9600);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT);
}
void loop() {
sensorValue = analogRead(analogInPin);
Serial.println("sensor = ");
Serial.println(sensorValue);
delay(2);
if ( sensorValue < 50 ) {
analogWrite(ledPin1, sensorValue);
} else if ( sensorValue > 50 ) {
analogWrite(ledPin2, sensorValue);
}
if ( sensorValue < 100 ) {
analogWrite(ledPin2, sensorValue);
}
if ( sensorValue < 150 ) {
analogWrite(ledPin3, sensorValue);
}
}
First your else if and your if (sensorValue < 100) will make two both if the value is between 50 and 100.
If I understand, you want to turn on the ledPin1 in range 0-50, led pin2 in range 50-100 and led pin 3 100-150?
if (sensorValue >= 0 && sensorValue <= 50 ) {
analogWrite(ledPin1, sensorValue);
analogWrite(ledPin2, LOW);
analogWrite(ledPin3, LOW);
}
else if (sensorValue > 50 && sensorValue <= 100) {
analogWrite(ledPin2, sensorValue);
analogWrite(ledPin1, LOW);
analogWrite(ledPin3, LOW);
}
else if (sensorValue > 100 && sensorValue <= 150) {
analogWrite(ledPin3, sensorValue);
analogWrite(ledPin1, LOW);
analogWrite(ledPin2, LOW);
}
Let me know if it's results!
I have an if statement inside a for loop. When the the condition in if statement is true, I want to break out of the for loop.
here is what exactly I have
if (data < voltage && data2 < voltage) {
digitalWrite(pump, HIGH);
digitalWrite(valve, HIGH);
digitalWrite(valve2, HIGH);
for (int i = 0; i < 10; i++) {
lcd.setCursor(0, 2);
lcd.print("S_1:");
if (data > 260 && data < 295)
lcd.print("MID");
else if (data < 260)
lcd.print("LOW");
else
lcd.print("HIGH");
lcd.setCursor(7, 0);
lcd.print("Pump:ON");
lcd.setCursor(0, 1);
lcd.print("V1:ON");
lcd.setCursor(9, 2);
lcd.print("S_2:");
if (data2 > 260 && data2 < 295)
lcd.print("MID");
else if (data2 < 260)
lcd.print("LOW");
else
lcd.print("HIGH");
lcd.setCursor(7, 1);
lcd.print("V2:ON");
lcd.setCursor(14, 1);
lcd.print("V3:OFF");
sum += data;
sum2 += data2;
delay(1000);
}
average = sum / 10;
average2 = sum2 / 10;
if (average > voltage || average2 > voltage) {
digitalWrite(pump, LOW);
digitalWrite(valve, LOW);
digitalWrite(valve2, LOW);
}
sum = 0;
sum2 = 0;
lcd.clear();
}
It seams not going throw the whole conditions.
You could use the break keyword.
for (int i = 0; i < 100; i++){
if (i == 2){
break;
}
}
Also, this is considered by OOD people a gotoish code, prefer inserting the break condition in the for condition :
boolean shouldBreak = false;
for (int i = 0; i < 100 && !shouldBreak; i++){
if (i == 2){
shouldBreak = true;
}
}
Use the break; keyword to do that.