I want to be able to count ticks of the encoder on the DC motor and stop the motor when I reach a certain count. Currently, the test code I am working on does not work...but I cant see why it shouldn't work...
The Code:
#include "DualTB9051FTGMotorShield.h" //Include ther library for the motor driver
DualTB9051FTGMotorShield md;
volatile unsigned int encoder = 0;
const byte encoder1 = 2;
const byte encoder2 = 3;
void setup() {
Serial.begin(115200); //Initialize the serial connection
md.init(); // Initialize the motor driver
pinMode(encoder1, INPUT); //Set the pins the encoder is connected to as inputs
pinMode(encoder2, INPUT); //Set the pins the encoder is connected to as inputs
digitalWrite(encoder1,HIGH); // internal pull up resistor
digitalWrite(encoder2,HIGH); // internal pull up resistor
attachInterrupt(0,encoderISR,CHANGE); //
md.flipM1(false); // Set motor driection
md.enableDrivers(); // Enable the motor driver
}
void loop() {
turnMotor();
}
void turnMotor(){
int deltaSteps = 128;
md.setM1Speed(400);
if(encoder >= deltaSteps){
md.setM1Speed(0);
delay(10000);
}
}
void encoderISR(){
if (bitRead(PORTD, 2) == bitRead(PORTD, 3) ) {
encoder += 1;
}
else encoder -= 1;
}
I have stripped away as much extraneous stuff as I could and tried to make sure the ISR function is streamlined but the code doesn't do anything when I upload it currently. When I test other programs with the same wiring and setup I can get the motor to turn...what am I missing?
When using a multibyte variable (in this case an int) in an ISR you must temporarily suspend interrupts when reading it to avoid the possibility that its value gets changed while you are reading it. Make a copy of the value and use the copy in the calculations in loop() - like this
That makes perfect sense. I implemented it as below but the motor still does not turn. It jerks a little once the code is uploaded but that is it...Which is so weird as I can test other code that turns the motor just fine...neither code seems able to stop the motor however.
#include "DualTB9051FTGMotorShield.h" //Include the library for the motor driver
DualTB9051FTGMotorShield md;
volatile unsigned int encoder = 0;
volatile unsigned int copyOfEncoder =0;
const byte encoder1 = 2;
const byte encoder2 = 3;
void setup() {
Serial.begin(115200); //Initialize the serial connection
pinMode(encoder1, INPUT); //Set the pins the encoder is connected to as inputs
pinMode(encoder2, INPUT); //Set the pins the encoder is connected to as inputs
digitalWrite(encoder1,HIGH); // internal pull up resistor
digitalWrite(encoder2,HIGH); // internal pull up resistor
attachInterrupt(0,encoderISR,CHANGE); //
md.init(); // Initialize the motor driver
md.flipM1(false); // Set motor driection
md.enableDrivers(); // Enable the motor driver
}
void loop() {
noInterrupts();
copyOfEncoder = encoder;
interrupts();
turnMotor();
Serial.println(encoder);
}
void turnMotor(){
int deltaSteps = 128;
md.setM1Speed(400);
if(copyOfEncoder >= deltaSteps){
md.setM1Speed(0);
delay(10000);
}
}
void encoderISR(){
if (bitRead(PORTD, 2) == bitRead(PORTD, 3) ) {
encoder += 1;
}
else encoder -= 1;
}
const int deltaSteps = 128;
void turnMotor()
{
if (encoder >= deltaSteps)
md.setM1Speed(0);
else
md.setM1Speed(400);
}
Then it won't keep trying to turn it back on again, it simply sets the speed dependent on whether its
reached the target or not. Bring constants out to top level so they are easy to spot and can be shared in
multiple places in the code. Also this way you don't call delay().
So that all works fine now thanks! Updated code below:
#include "DualTB9051FTGMotorShield.h" //Include the library for the motor driver
DualTB9051FTGMotorShield md;
volatile unsigned int encoder = 0;
volatile unsigned int copyOfEncoder =0;
const byte encoder1 = 2;
const byte encoder2 = 3;
const int deltaSteps = 8400;
void setup() {
Serial.begin(115200); //Initialize the serial connection
pinMode(encoder1, INPUT); //Set the pins the encoder is connected to as inputs
pinMode(encoder2, INPUT); //Set the pins the encoder is connected to as inputs
digitalWrite(encoder1,HIGH); // internal pull up resistor
digitalWrite(encoder2,HIGH); // internal pull up resistor
attachInterrupt(0,encoderISR,CHANGE); //
md.init(); // Initialize the motor driver
md.flipM1(false); // Set motor driection
md.enableDrivers(); // Enable the motor driver
}
void loop() {
noInterrupts();
copyOfEncoder = encoder;
interrupts();
turnMotor();
Serial.println(copyOfEncoder);
}
void turnMotor(){
if(copyOfEncoder >= deltaSteps){
md.setM1Speed(0);
}else{
md.setM1Speed(400);
}
}
void encoderISR(){
if (bitRead(PORTD, 2) == bitRead(PORTD, 3) ) {
encoder += 1;
}
else encoder -= 1;
}
I am trying to add in some SD card functionality now and its returning some intermittent failures...see code below:
#include "DualTB9051FTGMotorShield.h" //Include the library for the motor driver
DualTB9051FTGMotorShield md;
#include <SPI.h>
#include <SD.h>
File myFile;
volatile unsigned int encoder = 0;
volatile unsigned int copyOfEncoder =0;
const byte encoder1 = 2;
const byte encoder2 = 3;
const int deltaSteps = 8400;
char* fileName = "Combo.txt";
void setup() {
Serial.begin(115200); //Initialize the serial connection
pinMode(encoder1, INPUT); //Set the pins the encoder is connected to as inputs
pinMode(encoder2, INPUT); //Set the pins the encoder is connected to as inputs
digitalWrite(encoder1,HIGH); // internal pull up resistor
digitalWrite(encoder2,HIGH); // internal pull up resistor
attachInterrupt(0,encoderISR,CHANGE); //
md.init(); // Initialize the motor driver
md.flipM1(false); // Set motor driection
md.enableDrivers(); // Enable the motor driver
while (!Serial) {
; // Wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
myFile = SD.open(fileName, FILE_WRITE);
}
void loop() {
noInterrupts();
copyOfEncoder = encoder;
interrupts();
turnMotor();
Serial.println(copyOfEncoder);
}
void turnMotor(){
if(copyOfEncoder >= deltaSteps){
md.setM1Speed(0);
}else{
md.setM1Speed(400);
}
}
void encoderISR(){
if (bitRead(PORTD, 2) == bitRead(PORTD, 3) ) {
encoder += 1;
}
else encoder -= 1;
}
Can I use an SD card while using ISR without issue?