Rectangle pattern using arduino Mega - arduino

I am using an Arduino Mega to implement a Rectangle pattern movement of a device which mean the length and breadth should decrease each time it reaches the end edges. I have written the code but it is not working
//servo header
#include <Servo.h>
#include <Math.h>
Servo myservo;//servo Object
//motor pin config
int m1r = 9;
int m1f = 10;
int m2f = 12;
int m2r = 11;
//infrared counter
int ir1val=0;//pulse count from irval
int ir2val=0;//pulse count from irval
int len=1;
int bred=2;
//Different sensors used
int temp;
int buzz = 8;
const float radpulse = 0.05;//1 pulse = 0.05 meter
double pulsecount1;//pulse counter;
double pulsecount2;//pulse counter;
int pc1;//integer
int pc2;
void setup() {
// initialize the Motor pin as an output:
pinMode(m1f, OUTPUT);
pinMode(m1r, OUTPUT);
pinMode(m2f, OUTPUT);
pinMode(m2r, OUTPUT);
pinMode(buzz,OUTPUT);
myservo.attach(A0);//BLDC motor attachment
Serial.begin(9600);// standard serial bandwidth of all modules
}
void loop()
{
pulsecount1=len/radpulse;
pc1=(int)round(pulsecount1);
pulsecount2=bred/radpulse;
pc2=(int)round(pulsecount2);
pc1=3;
pc2=2;
myservo.write(30);
delay(5000);
labelL1:
if((pc2 == 0)&&(pc1 == 0))
{
goto Stop;
}
while(pc1 > ir1val)
{
temp=((5.0*analogRead(A3)*100)/1024);
if(temp >60)
{
// goto hibernate;
}
/* if((analogread(A14) <= 300 || analogread(A14) >= 400) || (analogread(A15) <= 300) || analogread(A15) == 400))
{
goto Stop;
}*/
digitalWrite(m2f,HIGH);
digitalWrite(m1f,HIGH);
//digitalWrite(m2f,HIGH);
if(digitalRead(A2))
{
ir1val++;
}
}
if(pc1 == ir1val)
{
/*if((analogread(A14) <= 300 || analogread(A14) >= 400) || (analogread(A15) <= 300) || analogread(A15) == 400))
{
goto Stop;
}*/
pc1--;
ir1val=0;
digitalWrite(m1f, HIGH);
digitalWrite(m2f,LOW);
delay(5000);
goto labelB1;
}
labelB1:
while(pc2 != ir1val)
{
temp=((5.0*analogRead(A3)*100)/1024);
if(temp >60)
{
// goto label2;
}
/* if((analogread(A14) <= 300 || analogread(A14) >= 400) || (analogread(A15) <= 300) || analogread(A15) == 400))
{
goto Stop;
}*/
digitalWrite(m1f,HIGH);
digitalWrite(m2f,HIGH);
if(digitalRead(A2))
{
ir2val++;
}
}
if(pc2 == ir2val)
{
/* if((analogread(A14) <= 300 || analogread(A14) >= 400) || (analogread(A15) <= 300) || analogread(A15) == 400))
{
goto Stop;
}*/
pc2=pc2--;
ir2val=0;
digitalWrite(m1f, HIGH);
digitalWrite(m2f,LOW);
delay(5000);
goto labelL1;
}
Stop:
myservo.write(0);// stop servo
digitalWrite(m1f,LOW);// stop motor
digitalWrite(m2f,LOW);//stop motor
digitalWrite(buzz,HIGH);//Buzzer
delay(5000);
goto Stop;
/*
hibernate:
temp=((5.0*analogRead(A2)*100)/1024);
if(temp >40)
{
delay(1000);
goto hibernate;
}
*/}

Related

Why do I get this error in the Ultrassonic context?

I have installed multiple libraries from ultrassonic and the last one I installed was " ultrasonic-master library". Can it be a library issue?
I have this code using ultrasonic sensor but I'm getting the 'unsigned int Ultrasonic::timing()' is private within this context
What can I try to fix this? Any help would be appreciated.
#include <Ultrasonic.h>
const int IN4 = 6;
const int IN3 = 7;
const int IN2 = 5;
const int IN1 = 4;
const int ENA = 3;
const int ENB = 2;
const int echoPin = 8; //digtal pin used for HC-SR04 ECHO in order to receive the signal
const int trigPin = 9; //digtal pin used for HC-SR04 ECHO in order to send the signal
Ultrasonic ultrasonic(trigPin, echoPin); //initializing the arduino pins
int distance;
String result;
int velocity = 0;
//on or off
boolean go = true;
float dist_cm = distance;
void setup() {
pinMode(echoPin, INPUT);
pinMode(trigPin, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
analogWrite(ENA, 145);
analogWrite(ENB, 145);
}
void loop() {
float distance = cmMsec();
dist_cm = distance;
if (dist_cm <= 10) {
decisao();
}
delay(100);
}
float cmMsec() {
float cmMsec;
long microsec = ultrasonic.timing();
cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
return (cmMsec);
delay(10);
}
void go_forward()
{
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENA, velocity);
analogWrite(ENB, velocity);
}
void freio() {
digitalWrite(IN4, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN1, LOW);
analogWrite(ENA, velocity);
analogWrite(ENB, velocity);
}
void decisao() {
// this block is responsible for change the speed of the car when the distance goes UP
if (go == true) {
if (distance > 30) {
while (velocity < 120) {
go_forward();
velocity = velocity + 10;
delay(50);
}
}
if (velocity >= 120) {
while (distance >= 60 && distance <= 70) {
siga_em_frente();
velocity = velocity + 10;
delay(50);
}
}
if (distance < 70) {
while (velocity < 145) {
go_forward();
velocity = velocity + 10;
delay(50);
}
}
if (velocity >= 145) {
while (distance >= 90 && distance <= 100) {
go_forward();
velocity = velocity + 10;
delay(50);
}
}
if (distance < 100) {
while (velocity < 220) {
go_forward();
velocity = velocity + 10;
delay(50);
}
}
}
delay(10000);
// this block is responsible for change the speed of the car when the distance goes UP
if (go == true) {
if (distance >= 90 && distance <= 100) {
while (velocity <= 145) {
go_forward();
velocity = velocity - 10;
delay(50);
}
}
if (velocity > 140 && velocity <= 145) {
while (distance >= 70 && velocity <= 60) {
go_forward();
velocity = velocity - 10;
delay(50);
}
}
if (distance <= 60 && velocity <= 30) {
while (velocity <= 120) {
go_forward();
velocity = velocity - 10;
delay(50);
}
}
if (velocity > 110 && velocity <= 120) {
while (distance < 30) {
velocity = velocity - 10;
delay(50);
}
}
if (distance < 30) {
if (velocity > 5 && velocity <= 0) {
go = !go;
}
}
}
if (go == true) {
break();
}
}
unsigned int Ultrasonic::timing()
Is a private method. Within the Ultrasonic class that method is declared as private. That means it may only be called by the Ultrasonic class itself. It is not intended to be used by you.
In order to use it it would have to be public. So you would need to edit the class.

ultrasonic sensor giving wrong distance when working with tmrpcm library?

I am trying to measurer distance with ultrasonic sensor, for each 10 centimeters a wav file is playing from micro SD. the ultrasonic sensor is working fine alone. but when connected with micro SD and by using tmrpcm library to play sound at some range the measurement is giving wrong distances.
this is my code.
#include "SD.h"
#include "TMRpcm.h"
#include "SPI.h"
const int EchoM = 6;
const int TriggerM = 5;
float distanceM;
unsigned long durationM;
const int SD_ChipSelectPin = 4;
TMRpcm tmrpcm;
void setup()
{
tmrpcm.speakerPin = 9;
Serial.begin(9600);
pinMode(TriggerM, OUTPUT);
digitalWrite(TriggerM, LOW);
pinMode(EchoM, INPUT);
if (!SD.begin(SD_ChipSelectPin)) {
Serial.println("SD fail");
return;
}
tmrpcm.setVolume(5);
}
void loop() {
digitalWrite(TriggerM, HIGH);
delayMicroseconds (50);
digitalWrite(TriggerM, LOW);
durationM = pulseIn(EchoM, HIGH);
distanceM = durationM / 58.0;
if (distanceM >= 1 && distanceM <= 9 ) {
Serial.println(distanceM, 1);
delay(900);
m5();
delay(800);
}
if (distanceM >= 10 && distanceM <= 19 ) {
Serial.println(distanceM, 1);
delay(900);
m15();
delay(800);
}
if (distanceM >= 20 && distanceM <= 29 ) {
Serial.println(distanceM, 1);
delay(900);
m25();
delay(800);
}
if (distanceM >= 30 && distanceM <= 39 ) {
Serial.println(distanceM, 1);
delay(900);
m35();
delay(800);
}
if (distanceM >= 40 && distanceM <= 49 ) {
Serial.println(distanceM, 1);
delay(900);
m45();
delay(800);
}
}
const int vdelay = 400;
void m5() {
tmrpcm.play("m5.wav");
delay (vdelay);
}
void m15() {
tmrpcm.play("m15.wav");
delay (vdelay);
}
void m25() {
tmrpcm.play("m25.wav");
delay (vdelay);
}
void m35() {
tmrpcm.play("m35.wav");
delay (vdelay);
}
void m45() {
tmrpcm.play("m45.wav");
delay (vdelay);
}
I found a solution. the problem was the pulseIn is not accurate when there are multiple libraries. so, I used NewPing library instead and it worked just as I wanted.

ESP32-WROOM-32 PWD with millis

Beginner in Arduino and ESP-32 needs help.
Hello together,
I’m using the Pololu - VNH5019 Motor Driver Carrier to control a 12v motor with an ESP32.
In the following sketch i can speed up and speed down the ramp with delay();.
I tried to archiv the same result with millis(), but until now i could not make it.
What i am missing in my code.
Thanks in advance.
#define MOTOR_IN1 27
#define MOTOR_IN2 16
#define PWMPIN 14
#define frequency 40000
#define resolutionbit 8
const unsigned long eventInterval = 30;
unsigned long previousTime = 0;
void setup() {
pinMode(MOTOR_IN1, OUTPUT);
pinMode(MOTOR_IN2, OUTPUT);
ledcAttachPin(PWMPIN, 0); // assign the speed control PWM pin to a channel
ledcSetup(0, frequency, resolutionbit);
}
void loop() {
//with_delay();
with_millis();
}
//------------------------------------------
void with_delay() {
// set direction
digitalWrite(MOTOR_IN1, HIGH);
digitalWrite(MOTOR_IN2, LOW);
// ramp speed up
for (int i = 0; i <= 255; i++) {
ledcWrite(0, i);
delay(30);
}
// ramp speed down
for (int i = 255; i >= 0; i--) {
ledcWrite(0, i);
delay(30);
}
}
//-------------------------------------------
void with_millis() {
unsigned long currentTime = millis();
if (currentTime - previousTime >= eventInterval) {
digitalWrite(MOTOR_IN1, HIGH);
digitalWrite(MOTOR_IN2, LOW);
for (int i = 0; i <= 255; i++) {
ledcWrite(0, i);
previousTime = currentTime;
}
}
if (currentTime - previousTime >= eventInterval) {
digitalWrite(MOTOR_IN1, HIGH);
digitalWrite(MOTOR_IN2, LOW);
for (int i = 255; i >= 0; i--) {
ledcWrite(0, i);
previousTime = currentTime;
}
}
}
Your problem is that the program gets stuck in the for loop.
You need to also create direction variable so the program that knows which if statement to execute.
You need to create some other logic that will increase the i variable without stopping the whole program.
The code:
//Initialize the i variable globaly:
int i = 0;
bool direction = 0;
//Your function:
void with_millis() {
unsigned long currentTime = millis();
if ((currentTime - previousTime >= eventInterval) && direction == true) {
digitalWrite(MOTOR_IN1, HIGH);
digitalWrite(MOTOR_IN2, LOW);
i++;
if (i <= 255) {
ledcWrite(0, i);
previousTime = currentTime;
} elif (i > 255) {
i = 0;
direction = false;
}
}
if ((currentTime - previousTime >= eventInterval) && direction == false) {
digitalWrite(MOTOR_IN1, LOW);
digitalWrite(MOTOR_IN2, HIGH);
i++;
if (i <= 255) {
ledcWrite(0, i);
previousTime = currentTime;
} elif (i > 255) {
i = 0;
direction = true;
}
}
}

Would love for you to help some bugs and improved code

I wrote a code designed to automatically turn on and off a generator based on whether the battery is full or empty.
There are some bugs in lcd.begin() and lcd.clear() (They both don't work).
error : invalid use of non-static member function.
Thank you!
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
bool Settings = false;
unsigned long time1;
#define RELAY_PORT 10
float Voltage = 0.00;
int VoltOn = 47;
int VoltOff = 56;
int upbutton = 1;
int downbutton = 2;
int okbutton = 3;
int backbutton = 4;
void setup() {
pinMode(upbutton, INPUT);
pinMode(downbutton, INPUT);
pinMode(okbutton, INPUT);
pinMode(backbutton, INPUT);
pinMode(RELAY_PORT, OUTPUT);
// initialize the LCD
lcd.begin();
// Turn on the blacklight and print a message.
lcd.backlight();
lcd.setCursor(0, 1);
lcd.print ("generator: off");
}
void loop() {
int analog_value = analogRead(A0);
Voltage = ((analog_value * 5.0) / 1020) * 12;
lcd.setCursor(0, 0);
lcd.print("Volt: ");
lcd.print(Voltage);
lcd.print("V");
if (Voltage <= VoltOn && digitalRead(RELAY_PORT) == LOW)
{
digitalWrite(RELAY_PORT, HIGH);
lcd.setCursor(0, 1);
lcd.print ("generator: on");
}
if (Voltage >= VoltOff && digitalRead(RELAY_PORT) == HIGH)
{
digitalWrite(RELAY_PORT, LOW);
lcd.setCursor(0, 1);
lcd.print ("generator: off");
}
if ((digitalRead(upbutton) == HIGH && digitalRead(downbutton) == HIGH && digitalRead(okbutton) == HIGH && digitalRead(backbutton) == HIGH) || (Settings = true))
{
lcd.clear;
lcd.print("Settings:");
delay(2000);
time1 = millis();
bool Setting = false;
while (digitalRead(upbutton) == LOW && digitalRead(downbutton) == LOW && digitalRead(okbutton) == LOW && digitalRead(backbutton) == LOW)
{
if (Setting == false)
{
lcd.clear;
lcd.scrollDisplayLeft();
lcd.print("press Up to set turn on");
lcd.setCursor(0, 1);
lcd.print("press down to set turn off");
Setting = true;
}
if (millis() > time1 + 60000)
{
loop();
}
}
time1 = millis();
while (millis() > time1 + 60000)
{
if (upbutton == HIGH)
{
time1 = millis();
//lcd.clear;
lcd.scrollDisplayLeft();
lcd.print("press Up/ Down to up/ Down Voltage turn on");
while (digitalRead(upbutton) == LOW && digitalRead(downbutton) == LOW && digitalRead(okbutton) == LOW && digitalRead(backbutton) == LOW)
{
if (millis() > time1 + 60000)
{
loop();
}
}
time1 = millis();
while (millis() > time1 - 60000)
{
if (upbutton == HIGH)
{
int xdelay = 1000;
time1 = millis();
(VoltOn) = (VoltOn) + 1;
lcd.setCursor(0, 1);
lcd.print("Voltage-on: ");
lcd.print(VoltOn);
lcd.print("V");
delay(xdelay);
xdelay = xdelay / 1.5;
}
if (downbutton == HIGH)
{
int xdelay = 1000;
time1 = millis();
(VoltOn) = (VoltOn) - 1;
lcd.setCursor(0, 1);
lcd.print("Voltage-on: ");
lcd.print(VoltOn);
lcd.print("V");
delay(xdelay);
xdelay = xdelay / 1.5;
}
if (okbutton == HIGH)
{
loop();
}
if (backbutton == HIGH)
{ Settings = true;
}
if (millis() > time1 + 60000)
{
loop();
}
}
}
if (downbutton == HIGH)
{
time1 = millis();
lcd.clear;
lcd.scrollDisplayLeft();
lcd.print("press Up/ Down to up/ Down Voltage turn off");
while (digitalRead(upbutton) == LOW && digitalRead(downbutton) == LOW && digitalRead(okbutton) == LOW && digitalRead(backbutton) == LOW)
{
if (millis() > time1 + 60000)
{
loop();
}
}
time1 = millis();
while (millis() > time1 - 60000)
{
if (upbutton == HIGH)
{
int xdelay = 1000;
time1 = millis();
(VoltOff) = (VoltOff) + 1;
lcd.setCursor(0, 1);
lcd.print("Voltage-off: ");
lcd.print(VoltOff);
lcd.print("V");
delay(xdelay);
xdelay = xdelay / 1.5;
}
if (downbutton == HIGH)
{
int xdelay = 1000;
time1 = millis();
(VoltOff) = (VoltOff) - 1;
lcd.setCursor(0, 1);
lcd.print("Voltage-off: ");
lcd.print(VoltOff);
lcd.print("V");
delay(xdelay);
xdelay = xdelay / 1.5;
}
if (okbutton == HIGH)
{
loop();;
}
if (backbutton == HIGH)
{
Settings = true;
}
if (millis() > time1 + 60000)
{
loop();
}
}
}
if (backbutton == HIGH)
{
loop();
}
if (okbutton == HIGH)
{
loop();
}
}
}
}
I think you shouldn't ask on stackoverflow for someone just to do your work. People don't like unspecific questions here, that show little to no effort of own research..
That said, one thing that stands out is, that all your lcd.clear are missing brackets, they should be lcd.clear();
Try to split up your code in smaller sections and test individual components, if something doesn't work.
1.How to make this code (at the beginning of the loop) only run every half a second without rivet the rest of the code?
lcd.setCursor(0, 0);
lcd.print("Volt: ");
lcd.print(Voltage);
lcd.print("V");
2.The LCD displays (that the current coming to Arduino from the accumulator is lower than its starting power) "generator: onf" and not "generator: off":
lcd.print ("generator: off");
if (Voltage <= VoltOn && digitalRead(RELAY_PORT) == LOW)
{
digitalWrite(RELAY_PORT, HIGH);
lcd.setCursor(0, 1);
lcd.print ("generator: on");
}
if (Voltage >= VoltOff && digitalRead(RELAY_PORT) == HIGH)
{
digitalWrite(RELAY_PORT, LOW);
lcd.setCursor(0, 1);
lcd.print ("generator: off");

Running a DC motor in linear sinusoidal motion with arduino, controlling hertz and direction change

After some searching around online I am able to run a 2-wire DC motor in a sinusoidal manner. It is a deconstructed printer carriage driven with an Arduino Uno and L298N motor driver. I'm using a potentiometer to control frequency. The code works well but I need help with a few things.
Is there an easy way to control the frequency it runs at? Possibly like setting it to 1.5, 1.6, 1.7,... etc, hertz, and have the sine function run motor? I am currently measuring the hertz but I am not able to get it to run accurately at intervals.
Is there a more elegant way to control the reversing of direction? I am reversing when the sin wave reaches its minimum. But at lower frequencies it will stay at minimum for a few samples and sometimes my method doesn't work... I am currently counting the samples at certain speeds and hard coding that count to reverse.
#define enA 9
#define in1 6
#define in2 7
#define INTERVAL 1000 // time between reads
int val;
int dir;
int count;
unsigned long lastRead = 0;
int frequency = 0;
int times = 0;
int sample_count = 0;
int sensorPin = 0; // The potentiometer is connected to
// analog pin 0
void setup() {
pinMode(enA, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
// Set initial rotation direction
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
Serial.begin(9600);
}
void reverseMotor(int pwnOutput) {
/* reserse the motor direction
uses the pwm outpur from the sine function
*/
if (dir == 0) {
Serial.println("LEFT <<<<<<<<<<<<<<<<<<<<<<<<<");
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
dir = 1;
} else if (dir == 1) {
Serial.println("RIGHT >>>>>>>>>>>>>>>>>>>>>>>>");
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
dir = 0;
}
analogWrite(enA, pwnOutput);
sample_count++;
}
void runMotor(int pwnOutput) {
analogWrite(enA, pwnOutput);
sample_count++;
}
void loop() {
static uint16_t phase;
int sensorValue;
int adjusting_speed;
int reverse_fix;
sensorValue = analogRead(sensorPin);
phase = (map(sensorValue, 0, 1023, 1, 256));
uint16_t sin_wave[phase];
for (int16_t i = 0; i < (phase); i++) {
float angle = TWO_PI * i / phase;
int16_t val = sin(angle) * (1024 - 1);
int pwmOutput;
int dir;
val += 1024;
sin_wave[i] = val;
pwmOutput = map(val, 0, 2047, 100, 255); // mapping higher than
// 0 to ensure motor is
// still moving,
Serial.println(pwmOutput);
//Serial.println(phase);
//Serial.println(val);
if (pwmOutput != 100) {
runMotor(pwmOutput);
count = 0;
} else {
count++;
// THERE HAS GOT TO BE A BETTER WAY TO DO THIS
if (phase >= 1 && phase <= 32) {
reverse_fix = 1;
}
if (phase >= 33 && phase <= 54) {
reverse_fix = 2;
}
if (phase >= 55 && phase <= 72) {
reverse_fix = 3;
}
if (phase >= 73 && phase <= 91) {
reverse_fix = 4;
}
if (phase >= 92 && phase <= 109) {
reverse_fix = 5;
}
if (phase >= 110 && phase <= 127) {
reverse_fix = 6;
}
if (phase >= 128 && phase <= 156) {
reverse_fix = 7;
}
if (phase >= 157 && phase <= 174) {
reverse_fix = 8;
}
if (phase >= 175 && phase <= 193) {
reverse_fix = 9;
}
if (phase >= 194 && phase <= 207) {
reverse_fix = 10;
}
if (phase >= 208 && phase <= 233) {
reverse_fix = 11;
}
if (phase >= 234 && phase <= 256) {
reverse_fix = 12;
}
if (count >= reverse_fix) {
reverseMotor(pwmOutput);
}
}
}
if (millis() - lastRead >= INTERVAL) { // if INTERVAL has passed
/*
Counting and measuring hertz
*/
val = frequency;
times++;
float vals = val / times;
float hertz = float(sample_count) / float(phase);
lastRead = millis();
Serial.println();
Serial.println("Hz:");
Serial.println(hertz);
Serial.println();
sample_count = 0;
}
}
I am new to Arduino, so any help or advice is appreciated.

Resources