Skip to content

Instantly share code, notes, and snippets.

@kmpm
Created August 20, 2011 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmpm/1159297 to your computer and use it in GitHub Desktop.
Save kmpm/1159297 to your computer and use it in GitHub Desktop.
Spjällstyrning
//Om du ändrar kortet så byt pinnarna
#define TRIGGER_PIN 5
#define BUTTON1_PIN 4
#define LED1_PIN 3
#define LED2_PIN 2 //används inte just nu
#define CTRL_ENABLE1_PIN 6 //aktiverar motordrivaren
#define CTRL_INPUT1_PIN 7 //rikning1 för motor
#define CTRL_INPUT2_PIN 8 //rikting2 för motor
//Beroende på motor och hur konstruktionen ser ut så ändra dessa
#define RUNNING_SPEED 150 //1-255 PWM Utgång till motor.
#define RUNNING_TIME 700 //Tid motorn ska gå i ms för att stänga spjäll
#define RESET_SPEED 60 //hastighet vid retur. Lite lägre för att hinna stanna
#define RESET_TIME 8000 //max tid , i ms, som motorn ska gå vid retur
#define BREAK_TIME 1000 //tid i ms som motorbroms skall vara aktivt vid stopp
#define RUN_DIRECTION 1 //1 eller 0 som bestämmer riktning motorn ska gå.
#define RESET_DIRECTION 0 //1 eller 0 som bestämmer returriktning. !=RUN_DIRECTION
#define TRIGGER_ON 1
#define TRIGGER_OFF 0
#define WAIT_TIME 30 //tid i sekunder som ska gå innan spjället stängs.
//var försiktig med att ändra allt nedanför
#define BLINK_INTERVAL 700 //hur snabbt dioden blinkar
//diverse variabler som används av programmet
int currentDirection=RUN_DIRECTION; //aktuell riktning
bool motorInit=false; //om motorn är initializerad
bool motorInInit=false; //om initieringen håller på
bool alarm=false;
bool isWaiting=false;
unsigned long currentMillis; //aktuell tid i ms
unsigned long waitToMillis;
unsigned long currentSecond;
unsigned long nextSecond;
unsigned long waitToSeconds;
int periodLimit = 1;
//diverse variabler som håller reda på LED blinket
struct toggle_t {
unsigned long shiftAt;
int ledState;
int count;
int ledPin;
int blinkInterval;
bool isOn;
} toggle1;
//diverse variabler som håller reda på motor
struct motor_t {
int direction;
bool running;
unsigned long runUntil;
bool stopOnTrigger;
bool returnToTrigger;
} motor;
//setup görs 1 gång efter reset
void setup() {
Serial.begin(38400); //9600 bit/s på seriebussen
Serial.print("boot..."); //skriv ut texten boot på serieporten
//Sätter utgångspinnarna
pinMode(CTRL_INPUT1_PIN, OUTPUT);
pinMode(CTRL_INPUT2_PIN, OUTPUT);
pinMode(CTRL_ENABLE1_PIN, OUTPUT);
pinMode(LED1_PIN, OUTPUT);
pinMode(LED2_PIN, OUTPUT);
//sätter ingångspinnarna
pinMode(TRIGGER_PIN, INPUT);
pinMode(BUTTON1_PIN, INPUT);
//sätter diverse startvariabler
motorInit=false;
motorInInit=false;
alarm=false;
toggle1.ledPin = LED1_PIN;
toggle1.ledState=LOW;
toggle1.blinkInterval = BLINK_INTERVAL;
toggle1.count=0;
toggle1.isOn=false;
motor.direction=RUN_DIRECTION;
motor.running=false;
motor.runUntil=0;
motor.stopOnTrigger=false;
motor.returnToTrigger=false;
//vänta 1 sekund. så att man hinner med
delay(1000);
Serial.println("OK");
}
//loop körs varje cykel
void loop() {
//vi använder aktuell tid massor... buffra det
currentMillis = millis();
blink(); //blinka
motorLoop(); //kolla om vi ska göra nått med motorn
}
//initMotor - Logik för att initiera allt..
void initMotor(){
int trig = digitalRead(TRIGGER_PIN);
if (trig==TRIGGER_ON){
//trigger är på.. vi är redan framme
Serial.println("init klart");
motorInit=true;
return;
}
if(!motorInInit){
//kör motorn mot återställning och vänta på trigger
//kör i en max tid dock.. om nått skulle vara fel
Serial.println("Start init");
motor.direction=RESET_DIRECTION;
motor.runUntil=currentMillis + RESET_TIME;
motor.stopOnTrigger=true;
motorStart();
motorInInit=true;
}
else{
//vi kör init
if(!motor.running){
//något har stoppat motorn
//om det är triggern så är det OK.
//annars är det ett fel
if(trig==TRIGGER_OFF){
//inte bra... varna användaren
if (!alarm){
Serial.println("Fel i init");
alarm=true;
}
}
}
}
}
//motorLoop kontrollerar motorn
void motorLoop(){
//körs motorn?
if(motor.running){
//Ska den stoppas av timer
if(motor.runUntil>0 && currentMillis> motor.runUntil){
Serial.println("timer stopp");
motorStop();
}
//eller av trigger
if(motor.stopOnTrigger && digitalRead(TRIGGER_PIN)==TRIGGER_ON){
Serial.println("trigger stopp");
motorStop();
}
}
if(motorInit){
//om motorn är initierad så hamnar vi här
if(digitalRead(BUTTON1_PIN)==LOW && !motor.running && !isWaiting){
Serial.println("starta sekvens");
isWaiting=true;
nextSecond = currentMillis + 1000;
waitToSeconds = WAIT_TIME;
currentSecond=0;
toggle1.isOn=true;
}
if(isWaiting && currentMillis > nextSecond){
currentSecond++;
nextSecond = currentMillis+1000;
Serial.print(currentSecond, DEC);
Serial.println(" sekund(er)");
}
if(isWaiting && currentSecond > waitToSeconds){
isWaiting=false;
toggle1.isOn=false;
digitalWrite(toggle1.ledPin, LOW);
motor.runUntil=currentMillis + RUNNING_TIME;
motor.direction = RUN_DIRECTION;
motor.returnToTrigger=true;
motorStart();
}
}
else{
//motorn är inte initierad ännu. gör det
initMotor();
}
}
//startar motor i rätt riktning
void motorStart(){
if(motor.running){
//kör vi redan motorn och försöker köra igen
//så är det en bugg i programmet
//stoppa motorn först i fall det är riktningsbyte
//detta begränsar strömmen vid hög belastning
Serial.println("stoppar före start");
motorStop();
}
int speed = RUNNING_SPEED;
if(motor.direction==RESET_DIRECTION){
speed = RESET_SPEED;
}
Serial.print("motorStart-> Riktning:");
Serial.print(motor.direction, DEC);
Serial.print(" Hastighet:");
Serial.println(speed, DEC);
motorDirection(motor.direction); //sätt riktning
analogWrite(CTRL_ENABLE1_PIN, speed); //kör motor med PWM
motor.running=true;
}
void motorStop(){
//använder chipets 'Fast Stop' möjligheter
//bromsar i BREAK_TIME antal ms.
Serial.println("motorStop");
digitalWrite(CTRL_ENABLE1_PIN, 0); //stäng av drivningen
digitalWrite(CTRL_INPUT1_PIN, HIGH); //båda riktningspinnarna högt
digitalWrite(CTRL_INPUT2_PIN, HIGH); //den här också
digitalWrite(CTRL_ENABLE1_PIN, HIGH); //aktivera drivningen
delay(BREAK_TIME); //vänta i rätt tid
digitalWrite(CTRL_ENABLE1_PIN, 0); //stoppa drivningen
motorDirection(currentDirection); //ställ tillbaka riktningen
motor.running=false;
motor.runUntil=0;
motor.stopOnTrigger=false;
if (motor.returnToTrigger){
//Vi ska vända riktningen och gå tillbaka
Serial.println("Tillbaka till trigger");
motor.stopOnTrigger=true;
motor.direction=RESET_DIRECTION;
motor.runUntil=currentMillis + RESET_TIME;//kör i max tid
motor.returnToTrigger=false;
motorStart();
}
}
void motorDirection(int dir){
//sätter pinnarna som kontrollerar motorriktningen
//håller även reda på aktuell riktning
//med hjälp av variabeln 'currentDirection'
currentDirection = dir;
if(dir==1){
digitalWrite(CTRL_INPUT1_PIN, HIGH);
digitalWrite(CTRL_INPUT2_PIN, LOW);
}
else{
digitalWrite(CTRL_INPUT1_PIN, LOW);
digitalWrite(CTRL_INPUT2_PIN, HIGH);
}
}
void blink(){
//blika led
if(!toggle1.isOn) return;
if(currentMillis > toggle1.shiftAt){
toggle1.shiftAt = currentMillis + toggle1.blinkInterval;
if(toggle1.ledState == LOW)
toggle1.ledState = HIGH;
else
toggle1.ledState = LOW;
digitalWrite(toggle1.ledPin, toggle1.ledState);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment