TMC2208 Stepper driver replacement with A4988 Trouble - arduino

I am using a version of an Arduino CNC board that is found here to drive 4 wheels on a small wheeled robot. The shield came with A4988 stepper drivers and I got them to work fine, however the motors were much louder than intended so I went searching for another driver and found the TMC2208. I saw that the pin-outs were the same as long as the boards themselves aligned the enable pins on the shield.
The problem however seems to be in the code though. I am using the Accelstepper library in my code and everything works fine with the A4988 driver board. When I swapped just the boards, nothing happened in my program. I went looking on the TMCStepper library git to try and find some help. I managed to at lease get the steppers working using a version of the 'Simple' example. I tried to take out as much as possible while still being able to move the motors so that I could use it in my actual program. I still am not having any luck.
When I run this program
#include <TMCStepper.h>
#define EN_PIN 8 // Enable
#define DIR_PIN1 5 // Direction
#define STEP_PIN1 2 // Step
#define DIR_PIN2 6 // Direction
#define STEP_PIN2 3
#define DIR_PIN3 7 // Direction
#define STEP_PIN3 4
#define DIR_PIN4 13 // Direction
#define STEP_PIN4 12
#define SW_RX1 55 // TMC2208/TMC2224 SoftwareSerial receive pin
#define SW_TX1 60 // TMC2208/TMC2224 SoftwareSerial transmit pin
#define SW_RX2 56 // TMC2208/TMC2224 SoftwareSerial receive pin
#define SW_TX2 61
#define SW_RX3 57 // TMC2208/TMC2224 SoftwareSerial receive pin
#define SW_TX3 62
#define SW_RX4 58 // TMC2208/TMC2224 SoftwareSerial receive pin
#define SW_TX4 63
#define R_SENSE 0.11f // Match to your driver
TMC2208Stepper driverX(SW_RX1, SW_TX1, R_SENSE);
TMC2208Stepper driverY(SW_RX1, SW_TX1, R_SENSE);
TMC2208Stepper driverZ(SW_RX1, SW_TX1, R_SENSE);
TMC2208Stepper driverA(SW_RX1, SW_TX1, R_SENSE); // Software serial
void setup() {
pinMode(EN_PIN, OUTPUT);
pinMode(STEP_PIN1, OUTPUT);
pinMode(DIR_PIN1, OUTPUT);
pinMode(STEP_PIN2, OUTPUT);
pinMode(DIR_PIN2, OUTPUT);
pinMode(STEP_PIN3, OUTPUT);
pinMode(DIR_PIN3, OUTPUT);
pinMode(STEP_PIN4, OUTPUT);
pinMode(DIR_PIN4, OUTPUT);
digitalWrite(EN_PIN, LOW); // Enable driver in hardware
driverX.begin();
driverY.begin();
driverZ.begin();
driverA.begin(); // SPI: Init CS pins and possible SW SPI pins
// UART: Init SW UART (if selected) with default 115200 baudrate
driverX.microsteps(16); // Set microsteps to 1/16th
}
void loop() {
// Run 5000 steps and switch direction in software
for (uint16_t i = 5; i>0; i++) {
digitalWrite(STEP_PIN1, HIGH);
digitalWrite(STEP_PIN2, HIGH);
digitalWrite(STEP_PIN3, HIGH);
digitalWrite(STEP_PIN4, HIGH);
delayMicroseconds(160);
digitalWrite(STEP_PIN1, LOW);
digitalWrite(STEP_PIN2, LOW);
digitalWrite(STEP_PIN3, LOW);
digitalWrite(STEP_PIN4, LOW);
delayMicroseconds(160);
}
the motors just continuously spin, so I know that the drivers actually work.
My main code is below.
#include <AccelStepper.h>
#include <TMCStepper.h>
const int stepperCount = 4;
AccelStepper BLStepper(AccelStepper::DRIVER, 2, 5);
AccelStepper FLStepper(AccelStepper::DRIVER, 3, 6);
AccelStepper FRStepper(AccelStepper::DRIVER, 4, 7);
AccelStepper BRStepper(AccelStepper::DRIVER, 12, 13);
#define R_SENSE 0.11f
// define pins numbers
#define stepX_PIN 2
#define dirX_PIN 5
#define stepX_RX 55
#define dirX_TX 60
#define stepY_PIN 3
#define dirY_PIN 6
#define stepY_RX 56
#define dirY_TX 61
#define stepZ_PIN 4
#define dirZ_PIN 7
#define stepZ_RX 57
#define dirZ_TX 62
#define stepA_PIN 12
#define dirA_PIN 13
#define stepA_RX 58
#define dirA_TX 63
#define enPin_PIN 8
TMC2208Stepper driverX(stepX_RX, dirX_TX, R_SENSE);
TMC2208Stepper driverY(stepY_RX, dirY_TX, R_SENSE);
TMC2208Stepper driverZ(stepZ_RX, dirZ_TX, R_SENSE);
TMC2208Stepper driverA(stepA_RX, dirA_TX, R_SENSE);
//Front left wheel
//const int stepX_PIN = 2;
//const int dirX_PIN = 5;
//Front right wheel
//const int stepY_PIN = 3;
//const int dirY_PIN = 6;
//Back left wheel
//const int stepZ_PIN = 4;
//const int dirZ_PIN = 7;
//Back right wheel
//const int stepA_PIN = 12;
//const int dirA_PIN = 13;
//const int enPin_PIN = 8;
char split = ':'; //this is the character that would be used for seperating the different parts of your commands
//the syntax for commands would be: command:value1:value2
int listSize = 5; //the amount of commands in the list
String commands[] = {"hello", "add", "sub", "YMOV", "XMOV"}; //the list of every command name
void setup()
{
Serial.begin(115200); //sets the data transfer rate for the serial interface
//9600 is good for basic testing, but should be as high
//as possible for both devices
FRStepper.setMaxSpeed(300);
FRStepper.setAcceleration(200);
BRStepper.setMaxSpeed(300);
BRStepper.setAcceleration(200);
FLStepper.setMaxSpeed(300);
FLStepper.setAcceleration(200);
BLStepper.setMaxSpeed(300);
BLStepper.setAcceleration(200);
pinMode(stepX_PIN, OUTPUT);
pinMode(dirX_PIN, OUTPUT);
pinMode(stepY_PIN, OUTPUT);
pinMode(dirY_PIN, OUTPUT);
pinMode(stepZ_PIN, OUTPUT);
pinMode(dirZ_PIN, OUTPUT);
pinMode(stepA_PIN, OUTPUT);
pinMode(dirA_PIN, OUTPUT);
pinMode(enPin_PIN, OUTPUT);
digitalWrite(enPin_PIN, LOW);
digitalWrite(dirX_PIN, HIGH);
digitalWrite(dirY_PIN, HIGH);
digitalWrite(dirZ_PIN, HIGH);
digitalWrite(dirA_PIN, HIGH);
//digitalWrite(stepX_PIN, HIGH);
//digitalWrite(stepY_PIN, HIGH);
//digitalWrite(stepZ_PIN, HIGH);
//digitalWrite(stepA_PIN, HIGH);
driverX.begin();
driverY.begin();
driverZ.begin();
driverA.begin();
FRStepper.setEnablePin(enPin_PIN);
FLStepper.setEnablePin(enPin_PIN);
BRStepper.setEnablePin(enPin_PIN);
BLStepper.setEnablePin(enPin_PIN);
FRStepper.enableOutputs();
FLStepper.enableOutputs();
BRStepper.enableOutputs();
BLStepper.enableOutputs();
}
void loop()
{
CommCheck(); //checks serial buffer for data commands
runMotors();
}
void runMotors()
{
if ((FLStepper.distanceToGo() != 0) || (FRStepper.distanceToGo() != 0) || (BLStepper.distanceToGo() != 0) || (BRStepper.distanceToGo() != 0))
{
FRStepper.enableOutputs();
FLStepper.enableOutputs();
BRStepper.enableOutputs();
BLStepper.enableOutputs();
FLStepper.run();
BLStepper.run();
FRStepper.run();
BRStepper.run();
if ((FLStepper.distanceToGo() == 0) && (FRStepper.distanceToGo() == 0))
{
CommConfirm();
}
}
//if (movementComplete == true)
//{
//CommConfirm();
//}
//if (
//if ((FLStepper.distanceToGo() == 0) || (FRStepper.distanceToGo() == 0) || (BLStepper.distanceToGo() == 0) || (BRStepper.distanceToGo() == 0))
//{
//CommConfirm();
//}
}
void CommCheck()
{
if(Serial.available()) //checks to see if there is serial data has been received
{
//int len = Serial.available(); //stores the character lengh of the command that was sent
//this is used for command parsing later on
String command = Serial.readString(); //stores the command as a text string
int len = command.length();
//Serial.println(command);
Serial.flush();
//command.remove(len-2,1); //removes characters added by the pi's serial data protocol
//command.remove(0,2);
//len -= 3; //updates the string length value for parsing routine
int points[2] = {0, 0}; //offset points for where we need to split the command into its individual parts
for(int x = 0; x < len; x++) //this loop will go through the entire command to find the split points based on
{ //what the split variable declared at the top of the script is set to.
//Serial.print("Char ");
//Serial.print(x);
//Serial.print("- ");
//Serial.println(command[x]);
if(command[x] == split) //this goes through every character in the string and compares it to the split character
{
if(points[0] == 0) //if the first split point hasn't been found, set it to the current spot
{
points[0] = x;
}
else //if the first spot was already found, then set the second split point
{ //this routine is currently only set up for a command syntax that is as follows
points[1] = x; //command:datavalue1:datavalue2
}
}
}
CommParse(command, len, points[0], points[1]); //now that we know the command, command length, and split points,
} //we can then send that information out to a routine to split the data
} //into individual values.
void CommParse(String command, int len, int point1, int point2)
{
//Serial.print("Command Length: ");
//Serial.println(len);
//Serial.print("Split 1: ");
//Serial.println(point1);
//Serial.print("Split 2: ");
//Serial.println(point2);
String com = command; //copy the full command into all 3 parts
String val1 = command; //this is needed for the string manipulation
String val2 = command; //that follow
com.remove(point1, len - point1); //each of these use the string remove to delete
val1.remove(point2, len - point2); //the parts of the command that aren't needed
val1.remove(0, point1 + 1); //basically splitting the command up into its
val2.remove(0, point2 + 1); //individual pieces
val2.remove(val2.length()-1,1);
CommLookup(com, val1, val2); //these pieces are then sent to a lookup routine for processing
}
void CommLookup(String com, String val1, String val2)
{
int offset = 255; //create a variable for our lookup table's offest value
//we set this to 255 because there won't be 255 total commands
//and a valid command can be offset 0, so it's just to avoid
//any possible coding conflicts if the command sent doesn't
//match anything.
for(int x = 0; x < listSize; x++) //this goes through the list of commands and compares
{ //them against the command received
if(commands[x] == com)
{
offset = x; //if the command matches one in the table, store that command's offset
}
}
switch(offset) //this code compares the offset value and triggers the appropriate command
{
case 0: //essentially a hello world. | Syntax: hello:null:null
CommHello(); //this activates the hello world subroutine | returns Hello!
break;
case 1: //adds both values together and return the sum. | Syntax: add:value1:value2
CommAdd(val1.toInt(), val2.toInt()); //this activates the addition subroutine | returns value1 + value2
break;
case 2: //subtracts both values and return the difference | Syntax: subtract:value1:value2
CommSub(val1.toInt(), val2.toInt()); //this activates the subtraction subroutine | returns value1 - value2
break;
case 3:
yMovement(val1.toInt(), val2.toInt());
break;
case 4:
xMovement(val1.toInt(), val2.toInt());
default: //this is the default case for the command lookup and will only
Serial.println("Command not recognized"); //trigger if the command sent was not known by the arduino
break;
}
}
void CommHello() //each of these routines are what will be triggered when they are successfully processed
{
Serial.println("Hello!");
CommConfirm();
}
void CommAdd(int val1, int val2)
{
Serial.println(val1 + val2);
CommConfirm();
}
void CommSub(int val1, int val2)
{
Serial.println(val1 - val2);
CommConfirm();
}
void yMovement(int val1, int val2)
{
if (val1 < 0) {
//Serial.println("YMOVNEG");
int yMoveNew = (val1 * (-20.72));
//Serial.println(val1 * (-1));
//delay(500);
FRStepper.move(-yMoveNew);
BRStepper.move(-yMoveNew);
FLStepper.move(-yMoveNew);
BLStepper.move(-yMoveNew);
}
else {
//Serial.println(val1);
int yMoveNew = (val1 * (20.72));
//Serial.println(yMoveNew);
//Serial.println(val1);
//delay(500);
FRStepper.move(yMoveNew);
BRStepper.move(yMoveNew);
FLStepper.move(yMoveNew);
BLStepper.move(yMoveNew);
}
}
void xMovement(int val1, int val2)
{
if (val1 < 0) {
//Serial.println(val1);
int xMoveNew = (val1 * (-20.72));
//Serial.println(xMoveNew);
//Serial.println(val1 * (-1));
//delay(1000);
FLStepper.move(-xMoveNew);
BLStepper.move(xMoveNew);
FRStepper.move(xMoveNew);
BRStepper.move(-xMoveNew);
//delayMicroseconds(500);
}
else {
int xMoveNew = (val1 * (20.72));
//Serial.println(val1);
//delay(1000);
FLStepper.move(xMoveNew);
BLStepper.move(xMoveNew);
FRStepper.move(xMoveNew);
BRStepper.move(xMoveNew);
//delayMicroseconds(500);
}
}
void CommConfirm()
{
Serial.println("Done");
delay(750);
}
When I run my code, a Pi sends two values that equals step counts, however with the new drivers nothing happens. I tried also looking at and following the AccelStepper example on the git but I guess I have something wrong.
Any help would be appreciated.

Related

Reading and transferring encoder data from slave Arduino to master Arduino over SPI

My goal is to transfer a speed value from an encoder from a slave Arduino to a master Arduino via SPI. I am currently getting zeros on the master side serial print and I'm not sure what I am doing wrong. I have increased the amount of time to wait several times to see if it was a processing time issue but I had it waiting for 100mS with still no change. I know an unsigned int is 4 bytes and I am unsure if a union is the best option in this case seeing I might be overwriting my data due to the separate interrupts but I am unsure. I thought to use a struct since I'll have to move to transferring an array of floats and ints over SPI from various sensors including this encoder later. Below is my code and thank you for any help received:
Slave
#include "math.h"
#define M_PI
byte command = 0;
const int encoder_a = 2; // Green - pin 2 - Digital
const int encoder_b = 3; // White - pin 3 - Digital
long encoder = 0;
int Diameter = 6; // inches
float previous_distance = 0;
unsigned long previous_time = 0;
void setup (void)
{
Serial.begin(115200);
pinMode(MOSI, INPUT);
pinMode(SCK, INPUT);
pinMode(SS, INPUT);
pinMode(MISO, OUTPUT);
// turn on SPI in slave mode
SPCR |= _BV(SPE);
// turn on interrupts
SPCR |= _BV(SPIE);
pinMode(encoder_a, INPUT_PULLUP);
pinMode(encoder_b, INPUT_PULLUP);
attachInterrupt(0, encoderPinChangeA, CHANGE);
attachInterrupt(1, encoderPinChangeB, CHANGE);
}
// SPI interrupt routine
ISR (SPI_STC_vect)
{
union Data{
float f;
byte buff[4];}
data;
byte c = SPDR;
data.f = assembly_speed();
command = c;
switch (command)
{
// no command? then this is the command
case 0:
SPDR = 0;
break;
// incoming byte, return byte result
case 'a':
SPDR = data.buff[0];
break;
// incoming byte, return byte result
case 'b':
SPDR = data.buff[1];
break;
// incoming byte, return byte result
case 'c':
SPDR = data.buff[2];
break;
// incoming byte, return byte result
case 'd':
SPDR = data.buff[3];
break;
}
}
void loop (void)
{
// if SPI not active, clear current command
if (digitalRead (SS) == HIGH)
command = 0;
}
void encoderPinChangeA()
{
encoder += digitalRead(encoder_a) == digitalRead(encoder_b) ? -1 : 1;
}
void encoderPinChangeB()
{
encoder += digitalRead(encoder_a) != digitalRead(encoder_b) ? -1 : 1;
}
float distance_rolled()
{
float distance_traveled = (float (rotation()) / 8) * PI * Diameter;
return distance_traveled;
}
int rotation()
{
float eigth_rotation = encoder / 300;
return eigth_rotation;
}
float assembly_speed()
{
float current_distance = (float (rotation()) / 8) * PI * Diameter;
unsigned long current_time = millis();
unsigned long assemblySpeed = (((current_distance - previous_distance) /
12) * 1000) / (current_time - previous_time); // gives ft/s
previous_distance = current_distance;
previous_time = current_time;
return assemblySpeed;
}
Master
#include <SPI.h>
void setup (void)
{
pinMode(MOSI, OUTPUT);
pinMode(MISO, INPUT);
pinMode(SCK, OUTPUT);
pinMode(SS, OUTPUT);
Serial.begin (115200);
Serial.println ();
digitalWrite(SS, HIGH);
SPI.begin ();
SPI.setClockDivider(SPI_CLOCK_DIV8);
}
byte transferAndWait (const byte what)
{
byte a = SPI.transfer (what);
delayMicroseconds(10000);
return a;
}
union Data
{
float f;
byte buff[4];
}
data;
void loop (void)
{
digitalWrite(SS, LOW);
transferAndWait ('a');
data.buff[0] = transferAndWait ('b');
data.buff[1] = transferAndWait ('c');
data.buff[2] = transferAndWait ('d');
data.buff[3] = transferAndWait (0);
digitalWrite(SS, HIGH);
Serial.print("data.f = ");Serial.print(data.f);Serial.println(" Ft/s");
delay(200);
}

Arduino - deleting variables after radio send doesn't work

I have tried so hard but i just can't understand why the two lines in my Tx code :
inputString = "";
stringComplete = false;
Stop my radio is working.
If I delete this code, it just keeps sending the values over and over without being able to stop it.
Tx:
/* YourDuinoStarter Example: nRF24L01 Transmit Joystick values
- WHAT IT DOES: Reads Analog values on A0, A1 and transmits
them over a nRF24L01 Radio Link to another transceiver.
- SEE the comments after "//" on each line below
- CONNECTIONS: nRF24L01 Modules See:
http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
1 - GND
2 - VCC 3.3V !!! NOT 5V
3 - CE to Arduino pin 9
4 - CSN to Arduino pin 10
5 - SCK to Arduino pin 13
6 - MOSI to Arduino pin 11
7 - MISO to Arduino pin 12
8 - UNUSED
-
Analog Joystick or two 10K potentiometers:
GND to Arduino GND
VCC to Arduino +5V
X Pot to Arduino A0
Y Pot to Arduino A1
- V1.00 11/26/13
Based on examples at http://www.bajdi.com/
Questions: terry#yourduino.com */
/*-----( Import needed libraries )-----*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define CE_PIN 9
#define CSN_PIN 10
// NOTE: the "LL" at the end of the constant is "LongLong" type
const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe
/*-----( Declare objects )-----*/
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
/*-----( Declare Variables )-----*/
String inputString = "";
boolean stringComplete = false;
int msg[1]; // 2 element array holding Joystick readings
int msgNum = 0;
void setup() /****** SETUP: RUNS ONCE ******/
{
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(pipe);
}//--(end setup )---
void loop() /****** LOOP: RUNS CONSTANTLY ******/
{
serialEvent();
if (stringComplete) {
inputString.trim();
String on1 = "onone";
on1.trim();
String on2 = "ontwo";
on2.trim();
String off1 = "offone";
off1.trim();
String off2 = "offtwo";
off2.trim();
if (inputString.equals(on1)) {
Serial.print("1 is On");
msg[0] = 111;
radio.write(msg, 1);
inputString = "";
stringComplete = false;
} else if (inputString.equals(off1)) {
Serial.print("1 Is Off");
msg[0] = 112;
radio.write(msg, 1);
inputString = "";
stringComplete = false;
} else if (inputString.equals(on2)) {
Serial.print("2 Is On");
msg[0] = 113;
radio.write(msg, 1);
inputString = "";
stringComplete = false;
} else if (inputString.equals(off2)) {
Serial.print("2 Is Off");
msg[0] = 114;
radio.write(msg, 1);
inputString = "";
stringComplete = false;
} else {
inputString = "";
stringComplete = false;
}
}
}//--(end main loop )---
/*-----( Declare User-written Functions )-----*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
delay(100);
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}
//NONE
//*********( THE END )***********
Rx:
/* YourDuinoStarter Example: nRF24L01 Receive Joystick values
- WHAT IT DOES: Receives data from another transceiver with
2 Analog values from a Joystick or 2 Potentiometers
Displays received values on Serial Monitor
- SEE the comments after "//" on each line below
- CONNECTIONS: nRF24L01 Modules See:
http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
1 - GND
2 - VCC 3.3V !!! NOT 5V
3 - CE to Arduino pin 9
4 - CSN to Arduino pin 10
5 - SCK to Arduino pin 13
6 - MOSI to Arduino pin 11
7 - MISO to Arduino pin 12
8 - UNUSED
- V1.00 11/26/13
Based on examples at http://www.bajdi.com/
Questions: terry#yourduino.com */
/*-----( Import needed libraries )-----*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define CE_PIN 9
#define CSN_PIN 10
int ledPin = 3;
// NOTE: the "LL" at the end of the constant is "LongLong" type
const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe
/*-----( Declare objects )-----*/
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
/*-----( Declare Variables )-----*/
int msg[1]; // 2 element array holding Joystick readings
int lastMsgNum;
void setup() /****** SETUP: RUNS ONCE ******/
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
delay(1000);
Serial.println("Nrf24L01 Receiver Starting");
radio.begin();
radio.openReadingPipe(1,pipe);
radio.startListening();;
}//--(end setup )---
void loop() /****** LOOP: RUNS CONSTANTLY ******/
{
if ( radio.available() )
{
// Read the data payload until we've received everything
bool done = false;
while (!done)
{
// Fetch the data payload
done = radio.read( msg, sizeof(msg) );
Serial.print(msg[0]);
if (msg[0] == 111) {
digitalWrite(3, HIGH);
} else if (msg[0] == 112) {
digitalWrite(3, LOW);
} else if (msg[0] == 113) {
digitalWrite(5, HIGH);
} else if (msg[0] == 114) {
digitalWrite(5, LOW);
}
}
}
else
{
//Serial.println("No radio available");
}
}//--(end main loop )---
/*-----( Declare User-written Functions )-----*/
//NONE
//*********( THE END )***********
I think that you don't understand why you must initialize/set your variables.
inputString and stringComplete are global variables, so when you changed it in serialEvent() you could see it in loop() so when you read a '\n' in serialEvent(). You understand that the sender has finished transmission so you must analize it. Once you finished the corresponding action, you must initialize the global variable again to start again. Unless you have done that, you see stringComplete == true so you start to analize it again in the next cycle of loop().
Usually we call this boolean variables as 'flag', you can see it in several places of code to 'sync' it. In this case, you set true when you have finished the reception and set false when you have finished the analisys.

Arduino - Function-definition is not allowed here before '{' token

I am trying to make an Arduino rfid door lock, with arduino uno, stepper motor, funduino rfid-rc522. Here is the code:
//declare variables for the motor pins
int motorPin1 = 6; // Blue - 28BYJ48 pin 1
int motorPin2 = 7; // Pink - 28BYJ48 pin 2
int motorPin3 = 8; // Yellow - 28BYJ48 pin 3
int motorPin4 = 9; // Orange - 28BYJ48 pin 4
// Red - 28BYJ48 pin 5 (VCC)
int motorSpeed = 1500
; //variable to set stepper speed
int count = 0; // count of steps made
int countsperrev = 12; // number of steps per full revolution
int lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};
#include <RFID.h>
/*
* Read a card using a mfrc522 reader on your SPI interface
* Pin layout should be as follows (on Arduino Uno):
* MOSI: Pin 11 / ICSP-4
* MISO: Pin 12 / ICSP-1
* SCK: Pin 13 / ISCP-3
* SS: Pin 10
* RST: Pin 5
*/
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <RFID.h>
#define SS_PIN 10
#define RST_PIN 5
RFID rfid(SS_PIN,RST_PIN);
int serNum[5];
#define I2C_ADDR 0x27 // <<----- Add your address here. Find it from I2C Scanner
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
int n = 1;
int a = 0;
int DA = A0;
int DO = 2;
int state = 0;
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
void setup(){
//declare the motor pins as outputs
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
Serial.begin(9600);
SPI.begin();
rfid.init();
lcd.begin (16,2); // <<----- My LCD was 16x2
// Switch on the backlight
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go home
}
void loop(){
if(rfid.isCard()){
if(rfid.readCardSerial()) {
Serial.print(rfid.serNum[0],DEC);
/*Serial.print(" ");
Serial.print(rfid.serNum[1],DEC);
Serial.print(" ");
Serial.print(rfid.serNum[2],DEC);
Serial.print(" ");
Serial.print(rfid.serNum[3],DEC);
Serial.print(" ");
Serial.print(rfid.serNum[4],DEC);
Serial.println("");
*/
if(rfid.serNum[0]==199){
if (state == 0);{
Serial.print("opennnnnn");
Serial.println("");
lcd.setCursor(3,0);
lcd.print("Door Open!");
delay(1000);
lcd.home();
while (a<200){
if(count < countsperrev )
clockwise();
else if (count == countsperrev * 2)
count = 0;
else
count++;
delay(0);
a=a+1;
}
lcd.clear();
delay(5000);
a = 0;
state = 1;
}
if (state == 1) {
Serial.print("Door already open");
lcd.print("Door already open");
}
}
else{
if (state == 1){
Serial.print("closeeee");
Serial.println("");
lcd.setCursor(2,0);
lcd.print("Door Closed!");
delay(1000);
lcd.home();
while (a<200){
if(count < countsperrev )
anticlockwise();
else if (count == countsperrev * 2)
count = 0;
else
count++;
delay(0);
a=a+1;
}
lcd.clear();
delay(5000);
a = 0;
state = 0;
}
if (state == 0) {
lcd.print("Door Already Closed");
Serial.print("Door Already Closed");
}
rfid.halt();
}
//set pins to ULN2003 high in sequence from 1 to 4
//delay "motorSpeed" between each pin setting (to determine speed)
void anticlockwise()
{
for(int i = 0; i < 8; i++)
{
setOutput(i);
delayMicroseconds(motorSpeed);
}
}
void clockwise()
{
for(int i = 7; i >= 0; i--)
{
setOutput(i);
delayMicroseconds(motorSpeed);
}
}
void setOutput(int out)
{
digitalWrite(motorPin1, bitRead(lookup[out], 0));
digitalWrite(motorPin2, bitRead(lookup[out], 1));
digitalWrite(motorPin3, bitRead(lookup[out], 2));
digitalWrite(motorPin4, bitRead(lookup[out], 3));
}
I want it to only be able to open the door once, and then it must close to be opened again, but when i added the if (state == 0) state = 1; if (state == 1) if (state == 1) if (state == 0) the arduino IDE gave me an error of:
Arduino: 1.6.5 (Windows 7), Board: "Arduino Uno"
sketch_sep07d.ino: In function 'void loop()':
sketch_sep07d:158: error: a function-definition is not allowed here before '{' token
sketch_sep07d:181: error: expected '}' at end of input
sketch_sep07d:181: error: expected '}' at end of input
sketch_sep07d:181: error: expected '}' at end of input
a function-definition is not allowed here before '{' token
This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.
I have research the syntax for functions and it appears to be correct, i dont know what is going on.
If anyone could help, please do so.
Cheers
You're missing one or more close braces inside loop(). Verify that all open braces have a corresponding close brace in the expected location.

Using arduino to control leds as a pattern

I have this code here which sends some keys to windows and also lights up an led attached under each button. I think its right so the led will toggle with the button. What I wanted to achieve ontop of this was so that if no button states hadn't changed for 30 seconds then it goes into a mode where all three leds flash rapidly 3 times then the leds randomly flashes (Like a pinball machine when its not in use). After any input then it goes back to the normal mode
/* Arduino USB Keyboard HID demo
* Cut/Copy/Paste Keys
*/
#define KEY_LEFT_CTRL 0x01
#define KEY_LEFT_SHIFT 0x02
#define KEY_RIGHT_CTRL 0x10
#define KEY_RIGHT_SHIFT 0x20
uint8_t buf[8] = {
0 }; /* Keyboard report buffer */
#define PIN_COPY 5
#define PIN_CUT 6
#define PIN_PASTE 7
#define LED_COPY 8
#define LED_CUT 9
#define LED_PASTE 10
int state = 1;
void setup()
{
Serial.begin(9600);
pinMode(PIN_COPY, INPUT);
pinMode(PIN_CUT, INPUT);
pinMode(PIN_PASTE, INPUT);
// Enable internal pull-ups
digitalWrite(PIN_COPY, 1);
digitalWrite(PIN_CUT, 1);
digitalWrite(PIN_PASTE, 1);
delay(200);
}
void loop()
{
state = digitalRead(PIN_CUT);
if (state != 1) {
buf[0] = KEY_LEFT_CTRL; // Ctrl
buf[2] = 27; // Letter X
// buf[2] = 123; // Cut key: Less portable
Serial.write(buf, 8); // Ssend keypress
digitalWrite(LED_CUT, HIGH);
releaseKey();
}
state = digitalRead(PIN_COPY);
if (state != 1) {
buf[0] = KEY_LEFT_CTRL; // Ctrl
buf[2] = 6; // Letter C
// buf[2] = 124; // Copy key: Less portable
Serial.write(buf, 8); // Send keypress
digitalWrite(LED_COPY, HIGH);
releaseKey();
}
state = digitalRead(PIN_PASTE);
if (state != 1) {
buf[0] = KEY_LEFT_CTRL; // Ctrl
buf[2] = 25; // Letter V
// buf[2] = 125; // Paste key: Less portable
Serial.write(buf, 8); // Send keypress
digitalWrite(LED_PASTE, HIGH);
releaseKey();
}
}
void releaseKey()
{
buf[0] = 0;
buf[2] = 0;
Serial.write(buf, 8); // Release key
delay(500);
digitalWrite(LED_COPY, LOW);
digitalWrite(LED_CUT, LOW);
digitalWrite(LED_PASTE, LOW);
}
For refrence this is the article I was using http://mitchtech.net/arduino-usb-hid-keyboard/
i recomend you to look for Finite State Machine in Google.
Here is one link to implement it in C++
http://www.drdobbs.com/cpp/state-machine-design-in-c/184401236
here is other link to implement it in Arduino
http://playground.arduino.cc/Code/SMlib
it's exactly what you need to do what you want.
i hope this help you!

Arduino RF Data Transmission

I have 3 ultrasonic sensor connected to 1 Arduino Uno device. I want to send their data to another Arduino Uno with RF transmitter. I want to send the sensor's id number (1,2,3) and the data (0 or 1).
I want to transmit the data from printDistance method but the message that transmitter sends is char *msg. Do I have to send only char values?
#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round
//Sonar 1
int echoPin1 =2;
int initPin1 =3;
int distance1 =0;
//Sonar 2
int echoPin2 =6;
int initPin2 =7;
int distance2 =0;
//Sonar 3
//int echoPin3 =8;
//int initPin3 =9;
//int distance3 =0;
void setup() {
// Initialise the IO and ISR
vw_set_ptt_inverted(true); // Required for RF Link module
vw_setup(2000);
vw_set_tx_pin(8);
pinMode(initPin1, OUTPUT);
pinMode(echoPin1, INPUT);
pinMode(initPin2, OUTPUT);
pinMode(echoPin2, INPUT);
// pinMode(initPin3, OUTPUT);
// pinMode(echoPin3, INPUT);
// pinMode(initPin4, OUTPUT);
// pinMode(echoPin4, INPUT);
delay(2000);
Serial.begin(9600);
Serial.println(" ");
}
void loop() {
const char *msg; // this is your message to send
vw_send((uint8_t *)msg, strlen(msg));
vw_wait_tx(); // Wait for message to finish
delay(200);
distance1 = getDistance(initPin1, echoPin1);
printDistance(1, distance2);
delay(10);
distance2 = getDistance(initPin2, echoPin2);
printDistance(2, distance2);
delay(10);
//distance3 = getDistance(initPin3, echoPin3);
//printDistance(3, distance3);
//delay(10);
// distance4 = getDistance(initPin4, echoPin4);s
// printDistance(4, distance4);
Serial.println(" ");
delay(5000);
// Serial.println(" ");
}
int getDistance (int initPin, int echoPin){
digitalWrite(initPin, HIGH);
delayMicroseconds(10);
digitalWrite(initPin, LOW);
delayMicroseconds(5);
unsigned long pulseTime = pulseIn(echoPin, HIGH);
int distance = pulseTime/58;
return distance;
}
void printDistance(int id, int dist){
Serial.print('<');
Serial.print( id );
Serial.print( '>' );
if (dist >= 30 || dist <= 0 ){
Serial.print("0");
}else {
Serial.print("1");
}
Serial.print('<');
Serial.print( '/' );
Serial.print( id );
Serial.print( '>' );
// Serial.println(" ");
}
uint8_t vw_send(uint8_t* buf, uint8_t len) sends an array of bytes, with maximum length 77. In C, the type for a byte is called char. In AVR, this has an alias uint8_t as well.
So you send an array of bytes, and it is up to you to decide how the chars in the array are interpreted. For example, you could use sprintf() to write numbers as ascii encoded strings. Then on the receiving end, you would have to use atoi() to get the number back out of the string.
You could also choose to simply fill the array with the actual number values. With this option, you have to break up ints into separate bytes, and combine them back together on the receiving end. In your particular case, the data already fits into bytes, so you don't have to do that.
Beware that vw_send((uint8_t *)msg, strlen(msg)); won't work correctly with this second method. strlen() will count up to the first byte that holds a 0, effectively truncating the array. You would only use this call when using the sprintf() approach.
It looks like you are sending the data for all three sensors at the same time, and that the data for each is either 0 or 1. Why not send a 3-byte message of 0s and 1s?
uint8_t msg[3];
msg[0] = 0;
msg[1] = 1;
msg[2] = 0; // fill these in as you like
vw_send(msg, 3);
I couldn't add code to comment.
I changed the code as this;
void printDistance(int id, int dist){
uint8_t msg[1];
if (dist >= 30 || dist <= 0 ){
msg[0] = 0;
vw_send(msg, 1);
//vw_wait_tx();
}else {
msg[0] = 1;
vw_send(msg, 1);
//vw_wait_tx();
}

Resources