How to stop pwm after generate few pulse in Arduino? - arduino

I'm trying to generate pulse from Arduino to driver motor stepper 5 phase.
The driver only needs pulse to make motor stepper work. My problem is when I'm using code like this
for(int i=0; i <= 125; i++)
{
//analogWrite(13,125);
digitalWrite(13, HIGH);
delayMicroseconds(300);
digitalWrite(13, LOW);
delayMicroseconds(300);
}
digitalWrite(13,LOW);
delay(3000);
Stepper motor can work perfectly, but after more than 10 rotation,
the angle of the motor did not return to the original place. Can we use pwm in Arduino like that? So after generating 5000 pulses using pwm, we stop the pwm?

try this code:
#include <TimerOne.h>
const byte CLOCKOUT = 11;
volatile byte counter=0;
void setup() {
Timer1.initialize(15); //Every 15 microseconds change the state of the pin in the wave function giving a period of 30 microseconds
Timer1.attachInterrupt(Onda);
pinMode (CLOCKOUT, OUTPUT);
digitalWrite(CLOCKOUT,HIGH);
}
void loop() {
if (counter>=6000){ //With 6000 changes you should achieve the amount of pulses you need
Timer1.stop(); //Here I create the dead time, which must be in HIGH
PORTB = B00001000;
counter=0;
delayMicroseconds(50);
Timer1.resume();
}
}
void Onda(){
PORTB ^= B00001000; //Change pin status
counter+=1;
}
I just cant not eliminate the jitter. If you find a solution let me know

Related

Why 2nd PIR sensor is always HIGH?

I an getting a constant HIGH from 'inputPintwo' on the serial monitor. When 'inputPin' goes HIGH the relay is triggered and works properly because 'inputPintwo' is also HIGH (all the time).
I have a Very similar setup to: 2 PIR motion sensors +Arduino
I am not using pin 0 or 1 like the above answered question. I have replaced the sensor with a different one, in case it was bad hardware. I also unplugged the sensor and it still reads HIGH. The jumper is on retriggering on both sensors.
int ledPin = 13;
int inputPin = 2;
int inputPintwo = 4;
int pirState = LOW;
int val = 0;
int valtwo = 0;
#define RELAY1 7
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT);
pinMode(inputPintwo, INPUT);
pinMode(RELAY1, OUTPUT);
Serial.begin(9600);
}
void loop(){
val = digitalRead(inputPin);
valtwo = digitalRead(inputPintwo);
if (val == HIGH && valtwo == HIGH) {
digitalWrite(ledPin, HIGH);
if (pirState == LOW) {
Serial.println("Motion detected!");
pirState = HIGH;
Serial.println("Light ON");
digitalWrite(RELAY1,1);
delay(500);
digitalWrite(RELAY1,0);
delay(500);
digitalWrite(RELAY1,1);
delay(500);
digitalWrite(RELAY1,0);
delay(500);
digitalWrite(RELAY1,1);
}
}
else {
digitalWrite(ledPin, LOW);
if (pirState == HIGH){
Serial.println("Motion ended!");
digitalWrite(RELAY1,0);
pirState = LOW;
Serial.println("Light OFF");
}
}
}
I expect both sensors to go HIGH only when motion is detected, which will cause the relay to go on and off several times, then stay on until the timer runs out on the sensors.
To identify the problem I recommend you to start with checking the hardware. You will need voltmeter/multimeter.
Double check if you are interfacing the sensor properly (check datasheet). Didn't you forget to connect e.g. the pull-down resistors?
Check power supply voltage on sensors – is the voltage within
manufacturer specifications?
Check breadboard connections if you are using one.
Check sensor output behaviour (voltage), if there is or is not a movement. Is the voltage constant or not? Constant voltage means that PIR sensor is NOT working properly. Before performing of this test disconnect output from Arduino input.
If everything seems OK or you do not have voltmeter, try to disconnect the PIR sensor and connect a wire between Arduino pin 4 and ground. Does digitalRead(inputPintwo) return LOW? If yes, you know that reading of the pin state works fine.
Below please see some recommendations related to your code:
use #define directive or static const int variable type to define Arduino pins as you do it with relay output pin RELAY1.
Example:
#define LED_PIN 13
#define INPUT_PIN 2
#define INPUT_PINTWO 4
or
static const int ledPin = 13;
static const int inputPin = 2;
static const int inputPintwo = 4;
In your case, where you are only interested in digital value (LOW/HIGH), use built pull-up resistor on the input pins. Thus the log. voltage level on the floating input pin is defined (HIGH). If you do not use pull-up resistors, voltage can be either log. 0 (LOW) or log. 1 (HIGH), what can lead to strange program/state machine behaviour
To activate pull-up resistors in the input pins, use
pinMode(inputPin, INPUT_PULLUP);
pinMode(inputPintwo, INPUT_PULLUP);

Stop getting values from arduino after some time

I have a strange problem, I have Arduino UNO/MEGA and I need to get Gyro sensors's data and I want to see the data in the serial monitor. Seems like a simple task, I wrote a simple C program which collects data from Arduino through serial monitor I can see the data. Everything is working for few minutes and after that, it stops.
This code is supposed to calculate a distance travelled in a line using encoder (PID algorithm implemented using Gyroscope data for straight motion) after reaching desired position, machine takes a U-Turn.
It stop for a second after taking the U-Turn and then starts straight motion again. The problem I'm facing is that the gyroscope readings stop randomly while machine taking the turn. Due to this, the machine keeps rotating about that point without stopping.
#include <Wire.h>
#include <MPU6050.h>
MPU6050 mpu;
float timeStep = 0.01, yaw=0;
const int motor11=6;//LEFT MOTOR FW
const int motor12=7;//LEFT MOTOR BK
const int motor1pwm=3;
const int motor21=8;//RIGHT MOTOR FW
const int motor22=9;//RIGHT MOTOR BK
const int motor2pwm=5;
int flag1 = 0;
int thres1=120;//PWM Values
int thres2=120;
void setup()
{
Serial.begin(115200);
// Initialize MPU6050
while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
{
Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
delay(500);
}
mpu.calibrateGyro();
mpu.setThreshold(1);
pinMode(motor11, OUTPUT);
pinMode(motor12, OUTPUT);
pinMode(motor1pwm, OUTPUT);
pinMode(motor21, OUTPUT);
pinMode(motor22, OUTPUT);
pinMode(motor2pwm, OUTPUT);
}
void loop()
{
Vector norm=mpu.readNormalizeGyro();
yaw=yaw+norm.ZAxis*timeStep;
if(flag1 == 0){
straight();
}
if(flag1 == 2){
taketurn();
}
}
void straight()
{
digitalWrite(motor11, HIGH);
digitalWrite(motor12, LOW);
analogWrite(motor1pwm, thres1);
digitalWrite(motor21, HIGH);
digitalWrite(motor22, LOW);
analogWrite(motor2pwm, thres2);
delay(8000);
flag1 = 2;
}
void taketurn()
{
float setPoint = yaw - 500;
digitalWrite(motor11, HIGH);
digitalWrite(motor12, LOW);
analogWrite(motor1pwm, 120);
digitalWrite(motor21, LOW);
digitalWrite(motor22, LOW);
analogWrite(motor2pwm, 120);
while(true)
{
Vector norm = mpu.readNormalizeGyro();
yaw = yaw + norm.ZAxis * timeStep;
Serial.print("Turning Yaw= ");
Serial.println(yaw);
if(setPoint >= yaw) {
digitalWrite(motor11, LOW);
digitalWrite(motor12, LOW);
analogWrite(motor1pwm, thres2);
digitalWrite(motor21, LOW);
digitalWrite(motor22, LOW);
analogWrite(motor2pwm, thres1);
delay(2000);
break;
}
}
flag1 = 0;
}
The serial monitor just stops displaying the reading. This does not happen every time, and it is very random. I want to get proper and continuous data. Is it a logical problem or a board problem?
Normally a random crash would indicate possibly unhandled interrupts or memory overwrite, but looking at your code and it being an Arduino program, it's unlikely to be either. I don't see any divide ops either, so you are not dividing by zero. The two possible things I see is that a) you have a "while (true)" without exit, so surely that could get you into trouble, and b) perhaps your delay functions are called with a very large value unexpectedly, and the MCU is actually just delaying a long time.

How do I program digital pins on arduino uno?

I'm trying to make a microcontroller with an arduino. I am supplying with +5volt from the arduino, sending it to an NC button (so i can manually decide when to output a certain timed pulse). After the button it goes to a pin that I have set as an inPin (pin8). Then I want the program to make pin 7 HIGH(with a delay), and then it goes to a transistor.
This is the code I tried making (I know almost nothing about coding):
int ledPin = 7;
int inPin = 8;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(inPin, INPUT);
}
void loop()
{
if (inPin=HIGH) {
digitalWrite(ledPin, HIGH);
}
delay (500);
digitalWrite(ledPin, LOW);
}
For some reason the outPin is HIGH all the time. I remembered to hook up a resistor to GND so the digital pin would stay LOW when supposed to be LOW.
Thanks in advance!
if(inPin=HIGH) is a mistake, first of all use "==" instead of "=". ALso you need to READ input pin state: int invalue = digitalRead(inPin);
Also, all pins by default coonfigured as inputs, so you don't need use pinMode(inPin, INPUT);
After those changes your code will look like:
int ledPin = 7;
int inPin = 8;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop()
{
if (digitalRead(inPin)==HIGH) digitalWrite(ledPin, HIGH);
delay (500);
digitalWrite(ledPin, LOW);
}

Arduino IR Sensors Not Calling Functions

With this code written in the Arduino IDE I used to be able to call functions based on which Infrared sensor detected an object(right, left, or both). I altered the code a little bit lately but I've continued to make sure it wasn't missing any key components which made it work in the first place. I'm not sure if it's an error in my program or hardware but now, no matter what sensor detects an object, my robot just turns slightly to the left.
//Include Servo Library
#include <Servo.h>
//Define Pins for the Sensors and LEDs
#define LsensorPin 8
#define RsensorPin 5
#define LeftTransPin 7
#define RightTransPin 6
I'm using continuous rotation servos so using 0's and 180's is how I would control them at full speed. I checked the numbers over and over but they don't seem to be the problem.
//Constants for driving servo
const int RForward = 0;
const int RBackward = 180;
const int LForward = RBackward;
const int LBackward = RForward;
const int RNeutral = 90;
const int LNeutral = 90; //0 Speed
//Name the Servos for Left and Right Motor
Servo LMotor;
Servo RMotor;
The following 2 functions, when called, transmit an infrared signal through the transmitters. I do not think this is related to the problem because the sensors still detect objects, but my robot just doesn't respond the way I want it to.
//Take Reading from Left IR Sensor
void LeftIRled(){
for(int i=0;i<=384;i++){
digitalWrite(LeftTransPin, HIGH);
delayMicroseconds(13);
digitalWrite(LeftTransPin, LOW);
delayMicroseconds(13);
}
}
//Take Reading from Right IR Sensor
void RightIRled(){
for(int i=0;i<=384;i++){
digitalWrite(RightTransPin, HIGH);
delayMicroseconds(13);
digitalWrite(RightTransPin, LOW);
delayMicroseconds(13);
}
}
These functions control the direction in which the robot moves. I've checked it many times but this could possibly be one of the problems. They basically just control the spin of each individual servo with the previously declared variables.
//Controlling Servo Directions with Functions
void Forward(){
RMotor.write(RForward);
LMotor.write(LForward);
}
void Backup(){
RMotor.write(RBackward);
LMotor.write(LBackward);
}
void Stop(){
RMotor.write(RNeutral);
LMotor.write(LNeutral);
}
void Left(){
RMotor.write(RForward);
LMotor.write(LNeutral);
}
void Right(){
RMotor.write(RNeutral);
LMotor.write(LForward);
}
//Declare INPUT and OUTPUT for each Pin connected
//to Arduino Uno and set them to LOW
void setup(){
pinMode(LeftTransPin, OUTPUT);
digitalWrite(LeftTransPin, LOW);
pinMode(RightTransPin, OUTPUT);
digitalWrite(RightTransPin, LOW);
//drive forward
LMotor.attach(9);
RMotor.attach(10);
Forward();
}
Although I can't pinpoint the problem I believe it has something to do with the loop function. It is here that I transmit the infrared signal, receive it, and then call various functions which control the movement of the robot.
void loop(){
/*Drive forward until you reach an obstacle on either the
right side, left side, or both together(something in front of
you). If the left sensor goes low, he turns right, if the right
sensor goes low, he turns left. if both turn on at the same time
he stops, backs up, and turns right till he is out of danger
*/
int lstate;
int rstate;
LeftIRled();
lstate = digitalRead(LsensorPin);
delay(50);
RightIRled();
rstate = digitalRead(RsensorPin);
delay(50);
if (lstate == LOW && rstate == LOW)
{
Stop();
delay(100);
Backup();
delay(1000);
Stop();
delay(100);
Right();
delay(500);
}
else if (lstate == LOW)
{
Stop();
delay(100);
Backup();
delay(1000);
Right();
delay(500);
}
else if (rstate == LOW)
{
Stop();
delay(100);
Backup();
delay(1000);
Left();
delay(500);
}
else
{
Forward();
}
}
Any help or advice is greatly appreciated!

Arduino HC-SR04 NewPing Code Not Working

I was getting to know this ultrasonic detector with a simple code. All I was looking for was an output (my LED) to light up whenever the detector sensed an object within so many centimetres.
However the LED remains lit and the serial monitor just keeps spitting out the value '0.00cm'
I would appreciate any help, thanks.
(I do apologise if there is a very simple error I have overlooked)
#include <NewPing.h>
int TriggerPIN = 2;
int EchoPIN = 3;
int LEDPIN = 7;
void setup()
{
Serial.begin(9600);
//That started the distance monitor
pinMode(LEDPIN, OUTPUT);
pinMode(TriggerPIN, OUTPUT);
pinMode(EchoPIN, INPUT);
}
void loop()
{
float Distance, Duration;
digitalWrite(TriggerPIN, LOW);//These three blink the distance LED
delayMicroseconds(2);
digitalWrite(TriggerPIN, HIGH);
delayMicroseconds(10);
digitalWrite(TriggerPIN, LOW);
Duration = pulseIn(EchoPIN, HIGH); //Listening and waiting for wave
Distance = (Duration*0.034/2);//Converting the reported number to CM
if (Distance > 50)
{
digitalWrite(LEDPIN,LOW);
}
else
{
digitalWrite(LEDPIN,HIGH);
}
Serial.print(Distance);Serial.print("cm");
Serial.println(" ");
delay(200);
}
A couple of things to try:
Change the serial print to display 'Duration', to see if the problem lies in the centimetre conversion.
If this is not the problem:
(Assuming you are using the NewPing 1.7 library, as found here. )
The NewPing library has a built in 'Ping' function, along with distance conversion.
Try replacing the start of your code with this:
#include <NewPing.h>
#define TRIGGER_PIN 2
#define ECHO_PIN 3
#define MAX_DISTANCE 200 // Maximum distance to ping for (cm). Up to ~450cm
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
You do not need to then set the Trigger and Echo pins as outputs in your setup.
In your main loop, use these methods to get time and distance in microsecs and centimetres:
unsigned int pingTime = sonar.ping(); //Gets the ping time in microseconds.
Serial.print(sonar.convert_cm(pingTime)); // Convert ping time in cm, serial out.
I hope this helps.

Resources