Stap 16: Koppelverkoop het alle samen met een Arduino
- Hiermee bepaalt u de stappenmotor om te draaien de ghost-mobiel
- Draait in een sinusoïdale patroon om ze kijken meer "autonome"
- Hiermee roteert u gedurende 10 seconden (perfect uitgelijnd met de audio)
- Deze methode converteert IR-codes van de afstandsbediening die bij de externe IR-kit geleverd in de juiste IR-codes voor de Kenwood CD-speler
- Biedt dat een IR lezen-functie om te vangen en de exacte IR code gegevens weergeven uit de originele afstandsbediening
- Bevat een hard gecodeerde lijst van knop pers codes voor gebruik in het vertalen van de externe knop duwt
- De juiste IR code op basis van het indrukken van een toets op de nieuwe afstandsbediening stuurt
- Stuurt "Pauze" en "Skip" codes 10 seconden nadat de knop afspelen wordt geduwd
- De code stuurt ook sommige Foutopsporingsberichten naar de seriële poort console, in het geval dat u geïnteresseerd bent in de details onder de motorkap terwijl het draait.
Oorspronkelijk was ik van plan om ook controle verlichting om de verlichting uitschakelen wanneer een motiesensor was struikelde. Helaas brak ik de hardware die ik gebruikte en heb niet de tijd om het te vervangen zodat het systeem zal worden volledig gecontroleerd door de afstandsbediening.
De volgende lijst kaarten de Arduino Mego 2560 bestuur pinnen aan de respectieve component:
- Status-LED: PWM Pin 13
- IR ontvanger gegevens ingang: PWM Pin 11
- IR zender CD-speler: PWM Pin 8
- Stepper Motor besturingsseinen: PWM Pins 4, 5, 6 en 7
- Gronden doorgestuurd naar de juiste pinnen als nodig
Twee bestaande stukken code werden gebruikt en sterk veranderd. Deze omvatten de IRremote bibliotheek geboden door Ken Shirriff en de stepper motor voorbeeldcode opgenomen in de SDK van de Arduino. En eindelijk, hier is de code (die leveraged en gecrediteerd voorgaande werken):
/////////////////////////////////////////////////////////////////////////////////////////
/*
Stepper Motor Control - sinusoidal rotation
This program drives a unipolar or bipolar stepper motor.
The motor is attached to digital pins 4 - 7 of the Arduino.
The motor should revolve one direction
following a sinusoidal rate of rotation.
The program also allows the user to remotely activate and deactivate the
glowing ghost mobile of doom. It sends control signals to the mobile for 10
during which time the audio from the disk in the CD player will play 10
seconds of audio. After 10 seconds the code will send the pause and skip
command to go to the next track.
Created on Nov. 4th, 2012
(Some parts based on Stepper Motor Control program by Tom Igoe
Created 11 Mar. 2007
Modified 30 Nov. 2009)
(Some parts based on IRrecord program by Ken Shirriff
Created September, 2009)
*/
#define PAUSE_PLAY_BUTTON 0x6D92C837
#define REPEAT_BUTTON 0x6D929867
#define SKIP_BUTTON 0x6D92E817
#define POWER 0x00FFA25D
#define BUTTON_MODE 0x00FF629D
#define BUTTON_PAUSE_PLAY 0x00FF22DD
#define BUTTON_SKIP 0x00FFC23D
#define BUTTON_0 0x00FF6897
#define BUTTON_1 0x00FF30CF
#define BUTTON_2 0x00FF18E7
#define BUTTON_3 0x00FF7A85
#define BUTTON_4 0x00FF10EF
#define BUTTON_5 0x00FF38C7
#define BUTTON_6 0x00FF5AA5
#define BUTTON_7 0x00FF42BD
#define BUTTON_8 0x00FF4AB5
#define BUTTON_9 0x00FF52AD
#include <Stepper.h>
#include <IRremote.h>
int RECV_PIN = 11;
int BUTTON_PIN = 12;
int STATUS_PIN = 13;
IRrecv irrecv(RECV_PIN);
IRsend irsend;
decode_results results;
int step_enabled = LOW;
const int stepsPerRevolution = 2048; // change this to fit the number of steps per revolution for your motor
const float max_speed = 10; //sets the maximum rotational speed of the motor
const float resolution = 100; //sets the frequency by which the motor speed will change
float rotational_vel = 0; //holds the current rotational velocity scalar
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 4,5,6,7);
void setup() {
// initialize the serial port:
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
pinMode(BUTTON_PIN, INPUT);
pinMode(STATUS_PIN, OUTPUT);
}
// Storage for the recorded code
int codeType = NEC; // The type of code
unsigned long codeValue = 0x6D92C837; // The code value if not raw
int codeLen = 32; // The length of the code
int toggle = 0; // The RC5/6 toggle state
int buttonState = LOW; //virtual button press
// Stores the code for later playback
// Most of this code is just logging
void storeCode(decode_results *results)
{
codeType = results->decode_type;
int count = results->rawlen;
if (results->value == REPEAT)
{
// Don't record a NEC repeat value as that's useless.
Serial.println("repeat; ignoring.");
buttonState = LOW;
return;
}
Serial.print("storing code: ");
Serial.print(results->value, HEX);
codeValue = results->value;
codeLen = results->bits;
Serial.print("; code length: ");
Serial.println(codeLen);
buttonState = HIGH;
}
void sendCode(int repeat) {
if (repeat)
{
irsend.sendNEC(REPEAT, codeLen);
Serial.println("Sent NEC repeat");
buttonState = LOW; //turn off virtual button after sending code
}
else
{
Serial.println("Sending non-repeat code.");
switch (codeValue) {
case POWER:
irsend.sendNEC(PAUSE_PLAY_BUTTON, 32);
codeValue = PAUSE_PLAY_BUTTON;
Serial.print("Sent pause play code: ");
Serial.println(PAUSE_PLAY_BUTTON, HEX);
buttonState = LOW; //turn off virtual button after sending code
break;
case BUTTON_PAUSE_PLAY:
irsend.sendNEC(PAUSE_PLAY_BUTTON, 32);
Serial.print("Sent pause play code: ");
Serial.println(PAUSE_PLAY_BUTTON, HEX);
buttonState = LOW; //turn off virtual button after sending code
break;
case BUTTON_MODE:
irsend.sendNEC(REPEAT_BUTTON, 32);
Serial.print("Sent repeat code: ");
Serial.println(REPEAT_BUTTON, HEX);
buttonState = LOW; //turn off virtual button after sending code
break;
case BUTTON_SKIP:
irsend.sendNEC(SKIP_BUTTON, 32);
Serial.print("Sent skip code: ");
Serial.println(SKIP_BUTTON, HEX);
buttonState = LOW; //turn off virtual button after sending code
break;
}
}
}
int lastButtonState = LOW;
int i = 1;
void loop() {
if (i > resolution)
{
i = 1;
}
// If button pressed, send the code.
//buttonState = digitalRead(BUTTON_PIN);
if (lastButtonState == HIGH && buttonState == LOW) {
Serial.println("Released");
lastButtonState = LOW;
irrecv.enableIRIn(); // Re-enable receiver
}
if (buttonState) {
Serial.println("Sending IR code");
digitalWrite(STATUS_PIN, HIGH);
sendCode(lastButtonState == buttonState);
digitalWrite(STATUS_PIN, LOW);
step_enabled = HIGH;
lastButtonState = HIGH;
//delay(50); // Wait a bit between retransmissions
}
else if (irrecv.decode(&results)) {
Serial.println("Reading IR code");
digitalWrite(STATUS_PIN, HIGH);
storeCode(&results);
irrecv.resume(); // resume receiver
digitalWrite(STATUS_PIN, LOW);
}
//Serial.println("rotate the motor");
rotational_vel = abs(max_speed * sin(float(i)*3.14159/10) + 2); //program a sinusoidal velocity for the stepper motor
myStepper.setSpeed(rotational_vel);
if (abs(rotational_vel) > 0.001 && step_enabled == HIGH) //a velocity of 0 will lock up the stepper.h library.
{
Serial.println("valid stepper function entry");
if (i < resolution && step_enabled == HIGH)
{
Serial.print("iteration: ");
Serial.println(i);
Serial.print("Velocity: ");
Serial.println(rotational_vel);
myStepper.step(10 * rotational_vel);
i++;
}
else
{
step_enabled = LOW;
i = 0;
Serial.println("Pausing Playback and Skipping");
digitalWrite(STATUS_PIN, HIGH);
codeValue = BUTTON_PAUSE_PLAY;
sendCode(1 == 2);
delay(100); //Wait between transmissions
codeValue = BUTTON_SKIP;
sendCode(1 == 2);
digitalWrite(STATUS_PIN, LOW);
lastButtonState = HIGH;
}
}
}