Étape 16 : L’attachant tous ensemble avec un Arduino
- Contrôle le moteur pas à pas pour faire tourner le mobile de fantôme
- Tourne dans un modèle sinusoïdal à leur donner un aspect plus « autonome »
- Tourne pendant 10 secondes (alignés parfaitement avec l’audio)
- Convertit les codes IR de la télécommande fournie avec le kit de télécommande IR dans les bons codes IR pour le lecteur CD Kenwood
- Fournit qu'un IR lu fonction pour capturer et afficher les données exactes de code IR de la télécommande d’origine
- Contient une liste codée en dur des codes presse bouton destiné à traduire le pousse de touche de la télécommande
- Envoie le code IR approprié basé sur la pression de touche sur la nouvelle télécommande
- Envoie les codes « Pause » et « Sauter » 10 secondes après que la touche play est Poussée
- Le code envoie également des messages de débogage la console port série dans le cas où vous êtes intéressé par les détails sous le capot, lorsque celui-ci fonctionne.
Initialement, je comptais contrôler également l’éclairage pour éteindre les lumières lorsqu’un détecteur de mouvement a été déclenché. Malheureusement, je me suis cassé le matériel j’ai utilisait et n’avait pas le temps de le remplacer alors le système va être entièrement contrôlé par la télécommande.
La liste suivante mappe les broches de Conseil Arduino Mego 2560 sur le composant respectif :
- LED d’État : PWM Pin 13
- Entrée de données de récepteur IR: PWM broche 11
- Émetteur IR à lecteur CD : Pin PWM 8
- Les signaux de commande de moteur stepper : PWM Pins 4, 5, 6 et 7
- Acheminés vers les broches appropriées selon les besoins des motifs
Deux pièces existantes du code ont été utilisés et fortement modifiés. Il s’agit de la bibliothèque IRremote fournie par Ken Shirriff et le code d’échantillon moteur pas à pas inclus dans le Kit de développement logiciel Arduino. Et enfin, Voici les codes (effet de levier et crédité des travaux antérieurs) :
/////////////////////////////////////////////////////////////////////////////////////////
/*
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;
}
}
}