Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Curseur de caméra motorisé Arduino contrôlé par Bluetooth

Composants et fournitures

Arduino UNO
× 1
PCBWay Custom PCB
https://www.pcbway.com/project/shareproject/Arduino_Motorized_Camera_Slider.html
× 1
Rail linéaire V-Slot 20×40
la longueur que vous voulez.
× 1
Kit de roues Solid V
× 4
Kit de roues Solid V
× 4
Drop In Tee Nuts
× 4
Drop In Tee Nuts
× 4
Espaceur excentrique
× 2
Espaceur excentrique
× 2
Entretoise en aluminium de 9 mm
× 2
Entretoise en aluminium de 9 mm
× 2
Entretoise en aluminium de 3 mm
× 2
Vis M5 à profil bas longueur 20mm avec écrous
× 4
Vis à profil bas M5 longueur 10mm
× 4
Vis Allen M3 HEX longueur 16mm avec écrous
× 8
Roulement de bloc à bride à coussin auto-alignant de 8 mm
× 2
GT2 Alésage 8mm 20 Dents Distribution Aluminium Poulie
× 1
Arbre de rail linéaire de 8 mm
60mm longueur
× 1
GT2 Alésage 5mm 20 Dents Distribution Aluminium Poulie
× 1
Courroie de distribution ouverte GT2-6mm
la longueur de la courroie dépend de la longueur du rail profilé en aluminium
× 1
Moteur pas à pas bipolaire Nema17
× 1
A4988 Pilote de moteur pas à pas
× 1
Batterie rechargeable 12V 3A
× 1
Module Bluetooth HC-05
× 1

Outils et machines nécessaires

Imprimante 3D (générique)

Applications et services en ligne

Autodesk Fusion 360
Aurodesk-Eagle
Arduino IDE

À propos de ce projet

Présentation du projet

Pour quelqu'un qui aime tourner des vidéos d'amateurs au hasard, il est assez coûteux d'acheter un curseur de caméra motorisé. Alors, j'ai construit le mien. Dans ce didacticiel, nous passerons en revue chaque étape pour créer votre propre curseur de caméra motorisé contrôlé par Bluetooth.

Aujourd'hui, nous allons construire un curseur de caméra motorisé que nous pouvons contrôler sans fil via Bluetooth à partir d'une application mobile Android personnalisée. J'ai utilisé l'outil "MIT App Inventor" pour créer l'application qui nous permet de contrôler beaucoup de choses comme la vitesse de déplacement du curseur, la distance de déplacement, le taux d'accélération/décélération et bien plus encore. L'application mobile est très robuste, à l'intérieur de l'application, vous pouvez définir la longueur du curseur de votre caméra que vous utilisez. ce qui signifie que vous êtes libre de créer votre curseur de caméra réel avec n'importe quelle longueur jusqu'à 10 mètres sans vous soucier de l'application.

Nous avons utilisé un moteur pas à pas NEMA17 comme actionneur afin de pouvoir contrôler le nombre d'étapes dont nous avons besoin pour déplacer le curseur de la caméra. Pour contrôler un moteur pas à pas à l'aide de la carte Arduino, nous avons besoin d'un traducteur qui prend les commandes de la carte Arduino et les traduit dans la langue que le moteur pas à pas comprend. Voici le rôle de pilote de moteur pas à pas Pololu A4988, qui nous donne cinq résolutions de micropas différentes (jusqu'à 1/16 de pas) pour obtenir une précision de mouvement et une fluidité de mouvement maximales.

Ce projet a été conçu en pensant à la fabrication dans un fablab/makerspace/hackerspace.

CAO et modélisation 3D

Nous avons utilisé Fusion360 pour concevoir le curseur de la caméra, nous avons choisi d'utiliser des composants mécaniques très connus et faciles à trouver que vous pouvez acheter facilement dans presque n'importe quel magasin en ligne ou hors ligne, peu importe où vous habitez.

Nous utilisons du matériel Openbuilds pour construire la structure mécanique, le rail linéaire V-slot 2040 comme guide pour que la caméra se déplace. Deux poulies, une sur l'arbre du moteur pas à pas. Et l'autre, sur un arbre de rail linéaire de 8 mm sur le côté opposé du curseur avec une courroie de distribution ouverte entre eux pour convertir le mouvement rotatif du moteur pas à pas en mouvement linéaire.

L'arbre de rail linéaire de 8 mm est installé entre deux paliers à bride à coussinet à alignement automatique qui sont installés sur les plaques supérieure et inférieure à l'aide de quatre vis M5.

Nous utilisons quatre roues solides Delrin V-Slot qu'elles descendent dans la rainure en V du rail V-Slot pour rendre le mouvement de la caméra extrêmement fluide. Le milieu de la plaque de l'appareil photo a un trou de 1/4 pouce de diamètre pour une vis de trépied standard afin que vous puissiez monter facilement votre appareil photo.

Enfin, un boîtier pour l'électronique, Toutes les pièces du curseur de la caméra sont fixées ensemble par des vis et des écrous m3 * 16mm.

Fabrication numérique (impression 3D)

Tout le corps du curseur de la caméra est imprimé en 3D avec une hauteur de couche de 0,2, 20 % de remplissage, à l'exception des jambes gauche et droite du curseur de la caméra, sont imprimés avec une hauteur de 0,2 couche, 50 % de remplissage.

vous pouvez télécharger les fichiers STL depuis L'univers de la chose.

Assemblage du kit de roue en V

Le processus d'assemblage est très facile mec, allez ! Dans la première étape, nous devons assembler les quatre roues en V solides. Le kit de roue en V solide est livré avec une roue en caoutchouc, deux roulements, deux cales de précision et un contre-écrou.

Insérez le roulement d'un côté de la roue en caoutchouc et retournez la roue, puis insérez une cale de précision à l'intérieur de la roue en caoutchouc, insérez enfin le deuxième roulement du côté de la deuxième face.

Assemblage mécanique du curseur de la caméra

Tout d'abord, nous devons assembler la plaque de la caméra et les quatre roues en V solides. à l'aide de l'entretoise en aluminium de 9 mm, de la cale de précision et du contre-écrou.

Nous allons répéter l'étape précédente avec les trois autres roues. dans les deux roues droites, nous allons utiliser l'entretoise de 9 mm. Et les deux autres roues gauches, nous allons utiliser l'entretoise excentrique avec une entretoise de 3 mm au lieu de l'entretoise de 9 mm.

Maintenant, insérez la plaque de support de caméra dans le profil de la fente en V. Si vous constatez que la plaque est lâche et bouge, vous pouvez serrer l'écrou excentrique jusqu'à obtenir une plaque solide.

Insérons deux écrous en T à poser à chaque extrémité du profil de la fente en V. nous devons connecter le profil de la fente en V avec les jambes droite et gauche du curseur de la caméra.

Prenez les deux pieds coulissants de la caméra et poussez-les dans le profil de la fente en V.

apportez quatre vis M5X10mm, et fixez les deux pieds avec le profilé V-slot.

Nous devons installer le moteur pas à pas NEMA 17 sur sa plaque. puis, à l'aide de quatre vis M3X16mm, nous allons fixer le moteur en place.

Sur la jambe gauche, insérez deux écrous à l'intérieur de l'emplacement des écrous supérieurs de la jambe gauche.

Apportez la plaque moteur NEMA 17 et fixez-la sur le dessus de la jambe gauche. et, à l'aide de deux vis M3X16mm, nous allons fixer la plaque sur la jambe gauche.

Pour pouvoir convertir le mouvement de rotation du moteur pas à pas en mouvement linéaire, nous devons installer une poulie GT2 Bore 5mm sur l'arbre du moteur. et à l'aide de la clé Allen, serrez la vis de réglage de la poulie pour la maintenir en place.

Allons à la jambe droite du curseur de la caméra, insérons quatre écrous M3 dans l'emplacement des écrous de jambe.

Ensuite, placez les roulements de la jambe droite deux plaques sur le dessus de la jambe droite du curseur de la caméra.

À l'aide de quatre vis M3X16 mm, fixez les deux plaques sur le pied droit du curseur de la caméra pour les maintenir en place.

Apportez l'un des roulements du bloc à bride de 8 mm et installez-le sur la plaque du pied supérieur droit. à l'aide de deux vis M5X20mm et de deux écrous M5.

Nous devons répéter l'étape précédente avec le deuxième bloc de palier à bride de 8 mm pour le fixer sur la plaque inférieure de la jambe droite du curseur de la caméra.

Insérez l'arbre de rail linéaire de 8 mm dans le bloc de palier à bride de 8 mm à partir de son côté inférieur, et poussez-le vers le haut. Ensuite, insérez la poulie d'alésage de 8 mm dans l'arbre du rail linéaire et fixez-la en serrant la vis de réglage de la poulie.

Point de contrôle, maintenant nous avons assemblé tout le mécanisme du curseur de la caméra, sauf une chose. la courroie de distribution. Allons-y.

faire tourner la courroie de distribution de 6 mm sur la poulie d'alésage de 5 mm du moteur NEMA17. Aussi, sur la jambe droite, une poulie d'alésage de 8 mm. Enfin, serrez la ceinture avec la plaque de la caméra.

Il est temps d'assembler le tableau de commande. insérez le shield Cairo Camera Slider Arduino sur le dessus de la carte Arduino.

Insérez la carte Arduino et le shield Cairo Camera Slider à l'intérieur du boîtier de la carte de contrôle.

insérez deux écrous M3 à l'intérieur de l'emplacement des écrous de la jambe gauche.

installez le boîtier de la carte de commande sur le pied gauche du curseur de la caméra Cairo avec des vis M3X16mm.

fermez la face supérieure du boîtier avec deux vis et écrous M3, et le tour est joué !

Contrôle de test de moteur pas à pas

Après avoir assemblé toutes les pièces ensemble, nous devons le tester pour nous assurer que tout est correctement installé à sa place. Maintenant, nous devons connecter le moteur pas à pas à la carte Arduino via le pilote de moteur pas à pas A4988 et écrire du code pour exécuter cette chose.

Pilote de moteur pas à pas A4988

Pour contrôler n'importe quel moteur pas à pas à l'aide de la carte Arduino ou de tout microcontrôleur, vous aurez besoin d'un pilote de moteur pas à pas qui fonctionne comme un traducteur, prend les commandes de la carte Arduino et les traduit dans la langue que le moteur comprend.

il existe de nombreux pilotes de moteurs pas à pas, mais nous utiliserons le pilote A4988 . Ce pilote nous permet de contrôler un moteur bipolaire jusqu'à 2A de courant de sortie par bobine, il est très simple de s'interfacer avec la carte Arduino, vous n'avez besoin que de deux broches numériques pour contrôler complètement le pas et la direction de votre moteur, vous permet de contrôler la sortie de courant maximale facilement avec un potentiomètre intégré et vous offre une résolution de micro-pas jusqu'à 1/16 micro-pas.

VMOT, GND : Ce sont les broches de connexion d'alimentation pour le moteur pas à pas lui-même, cela peut être 8V-35V. Dans notre cas, nous connectons une source d'alimentation 12V 3A sur ces broches avec un condensateur de découplage de 100 uf pour protéger la carte A4998 de toute pointe de puissance.

2B, 2A : les broches de sortie de la première bobine du moteur pas à pas pouvant délivrer jusqu'à 2A.

1A, 1B : les broches de sortie pour la deuxième bobine du moteur pas à pas qui peut également fournir jusqu'à 2A.

VDD, GND : Utilisé pour piloter les circuits logiques internes, il peut être de 3V à 5,5V. Il est totalement isolé de la broche VMOT.

FR : Signifie "Activer", c'est une broche d'entrée LOW (0V) active, ce qui signifie que lorsque cette broche tire sur LOW (0V), la puce A4988 est activée. Et lorsqu'elle est tirée à HAUT (5V), la puce A4988 est désactivée. Par défaut, cette broche est tirée LOW (0V). Ainsi, la puce est toujours activée sauf si vous la tirez HAUT (5 V).

MS1, MS2, MS3 : Grâce à ces broches, vous pouvez sélectionner la résolution de votre moteur de micropas (taille de pas). L'A4988 vous offre cinq résolutions de micropas différentes (pas complet, demi-pas, quart de pas, huitième pas, seizième pas) . En appliquant les niveaux logiques appropriés à ces trois broches, nous pouvons régler les moteurs sur l'une des cinq résolutions.

Par défaut, les MS1, MS2, MS3 les broches ont des résistances pull-down internes. Ainsi, si vous laissez ces trois broches de sélection de micropas déconnectées, vous obtenez un mode pas à pas complet.

RST, SLP : Le « Réinitialiser » La broche est une broche d'entrée LOW (0V) active, ce qui signifie que lorsqu'elle tire sur LOW (0 V), toutes les entrées de pas sont ignorées, elle réinitialise également le traducteur lui-même jusqu'à ce que vous la tiriez sur HIGH (5 V). Le « Sommeil » broche également une broche LOW active, la tirant LOW, met le conducteur en mode veille minimisant la consommation d'énergie. Par défaut, le « Sommeil » la broche est tirée HAUT (5 V).

STP, DIR : La « Etape » La broche est chargée de contrôler le nombre de pas que le moteur tourne, chaque impulsion vers le « Pas » pin correspond pour un micropas dans la direction sélectionnée par la « Direction » broche, plus les impulsions sont rapides, plus le moteur tournera vite. En appliquant la valeur logique HIGH(5V) sur la « Direction » la broche fait tourner le moteur dans le sens des aiguilles d'une montre, en appliquant LOW (0V) il fait tourner le moteur dans le sens inverse des aiguilles d'une montre(cela peut différer de l'un à l'autre selon le câblage de votre moteur avec le pilote).

Moteur pas à pas NEMA17

Les moteurs pas à pas sont des moteurs à courant continu qui peuvent tourner par incréments précis, ils sont utilisés dans de nombreuses applications comme les imprimantes 3D pour aligner la tête d'impression et les machines CNC pour contrôler le mouvement de l'outil de coupe et c'est parce qu'ils sont très précis et précis.

Contrairement aux moteurs à courant continu, les moteurs pas à pas sont contrôlés en appliquant des impulsions électriques à courant continu à leurs bobines internes. Chaque impulsion fait avancer l'arbre d'un pas ou d'une fraction de pas que l'on appelle « Microstepping ». Ainsi, vous pouvez contrôler avec précision le nombre de pas ou même les fractions de pas que vous souhaitez que l'arbre du moteur déplace. Un autre grand avantage de l'utilisation de moteurs pas à pas est qu'il peut se déplacer de manière très précise et précise à des vitesses très lentes sans même caler.

Le type de moteur que nous utilisons dans ce projet est le moteur pas à pas bipolaire NEMA 17 . Le moteur pas à pas bipolaire a deux bobines internes et il a généralement quatre fils, deux fils par bobine. contrairement au moteur pas à pas bipolaire qui a cinq fils. Le « pas d'angle » du moteur est de 1,8 ° qui indique de combien l'arbre avance à chaque pas complet, le moteur fonctionne sur 9V mais si vous voulez en tirer le maximum de puissance, utilisez une source d'alimentation 12V.

Ainsi, en connectant le moteur pas à pas au pilote de moteur pas à pas A4988, nous pouvons contrôler le nombre de pas dont le moteur a besoin pour se déplacer et dans quelle direction. De plus, nous pouvons définir le mode « micropas », qu'il s'agisse d'un pas complet, d'un demi-pas, d'un quart de pas, ….. Jetons un coup d'œil au schéma de câblage.

Schéma de câblage

Comme nous l'avons indiqué précédemment, nous devons effectuer une petite vérification pour nous assurer que tout ce que nous avons assemblé auparavant est à sa place et se déplace correctement. Maintenant, nous allons câbler tout le matériel ensemble, le moteur pas à pas NEMA 17 avec le pilote de moteur pas à pas A4988 au cerveau, la carte Arduino. Et en utilisant une batterie Lithium-Ion 12V 3A pour alimenter les moteurs avec la puissance dont il a besoin.

Code Arduino

Installation de la bibliothèque AccelStepper

L'installation est assez simple, nous devons ouvrir Arduino IDE. Depuis le menu "Esquisse". Sélectionnez Inclure la bibliothèque -> Gérer les bibliothèques…

Une nouvelle fenêtre devrait apparaître, recherchez « AccelStepper » et installez la bibliothèque réalisée par « Mike McCauley ». Facile à droite !

Après avoir installé la bibliothèque AccelStepper, vous devriez la voir dans le menu des exemples.

Je veux m'assurer que la bibliothèque AccelStepper est correctement installée et que la connexion de mon moteur pas à pas avec le pilote de moteur A4988 est correcte et que ma gestion de l'alimentation est correcte. Alors, écrivons quelques lignes de code pour faire avancer et reculer notre moteur pas à pas.

// Bounce stepper test program
// Make a single stepper bounce from one limit to another
// Copyright (C) 2020 makesomestuff.org

#include
#define stepPin 2
#define dirPin 3 // Define a stepper and the pins it will use

AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin); //create an object. the pin "2" is the step pin, "3" is the direction pin.

void setup()
{
// Change these to suit your stepper if you want
stepper.setMaxSpeed(100);
stepper.setAcceleration(20);
stepper.moveTo(500);
}

void loop()
{
// If at the end of travel go to the other end
if (stepper.distanceToGo() ==0)
stepper.moveTo(-stepper.currentPosition());
stepper.run();
}

The code logic is pretty straightforward, we initialized an object from the AccelStepper library, we defined two constants (stepPin, dirPin) that two digital pins is used by the A4988 stepper motor driver to control the movement of the motor itself.

#include 

#define stepPin 2
#define dirPin 3 // Define a stepper and the pins it will use

AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin); //create an object. the pin "2" is the step pin, "3" is the direction pin.

Inside the void setup function, we set the Max. speed of the stepper motor to 100 steps/sec. Also, we set the acceleration/deceleration rate to 20 steps/sec. lastly, we used the moveTo() function to tell the motor to move 500 steps.

void setup()
{
// Change these to suit your stepper if you want
stepper.setMaxSpeed(100);
stepper.setAcceleration(20);
stepper.moveTo(500);
}

Inside the void loop function, we are checking if the motor reached it’s position or not. If it reached the position, it will bounce back. and if it didn’t reach it’s position yet, it will keep running.

void loop()
{
// If at the end of travel go to the other end
if (stepper.distanceToGo() ==0)
stepper.moveTo(-stepper.currentPosition());
stepper.run();
}

Camera Slider Full Wireless Control

We have done great things so far. Let’s continue! The next step after testing everything, is to work on the mobile app that we will use to control the camera slider movement and send the orders to it. Also, we need to work on the Arduino code that will receive the data from the mobile app and according to these data it will take some actions like moving the motor, changing speed, acceleration, and so on…

Building The Mobile App

To build the mobile app, I used the MIT App inventor tool that allows you to create mobile apps that run on any Android smartphone. The tool is pretty simple since you only drag and drop some pre-made code blocks to build the logic of your program, also you use some premade blocks to build the app user interface. You can access the source of the mobile app from the link down below. Feel free to edit and share, it’s open-source. Mobile App Source

The image down below, a brief explanation for each button function and how it works.

That mobile app will communicate with the Cairo camera slider wirelessly over the Bluetooth communication. So, the next step is to connect a Bluetooth module to the last circuit we built before and upload some lines of code to the Arduino board to be able to establish the communication between the mobile app and the Cairo camera slider.

Wiring Diagram

It’s the time to connect all things together, previously we connected the stepper motor, stepper motor driver, Arduino UNO, and the battery together and tested the circuit and it worked fine. Now, and after building the mobile app, we need to connect the HC-05 Bluetooth module to our circuit.

To make it wireless we will use the HC-05 Bluetooth module which has wide use, it can set as slave or master as well (unlike the HC-06 module which can work only as a slave) which means that you can make a Bluetooth connection between two different Arduino boards. the HC-05 Bluetooth module is an SPP (Serial Port Protocol) module, which means that it communicates with the Arduino board via the Serial communication. You only need to connect the Tx and the Rx pins between the HC-05 module and the Arduino UNO board.

  • Tx(Arduino) --> Rx(HC-05)
  • Rx(Arduino) --> Tx(HC-05)
  • 5V(Arduino) --> VCC(HC-05)
  • GNND(Arduino) --> GND(HC-05)

Schematic and PCB Fabrication

Man! I don’t like breadboarding a big circuit like this. So, I designed a super pretty Arduino UNO shield PCB board that keeps all my components in place without worrying about the jumper wires or even the connections. All you need to do is to place your component on the Arduino shield PCB, insert the HC-05 Bluetooth module, A4988 stepper motor driver, and the battery in their places. and install the shield on top of the Arduino board. that’s it!

I fabricated my PCB at PCBWay the quality was very good, in a few days the package arrived in Egypt safely. and I paid just 5$ for the fabrication which is amazing. The coolest thing that I was able to check the order fabrication and processing status online on my account panel and track everything happening to my baby board like I was there inside the factory.

you can download the PCB design source files or even ordering the Cairo Camera Slider Arduino Shield PCB from the PCBWay website. PCB Source Files &Ordering




Arduino Code And Bluetooth Communication

/*
TODO::Update the arduino program to Make the user able to choose the motor driver micro stepping mode. find and equation that helps to automatically adjust the the "steps" variable value.
TODO::update the mobile app to ask the user on the beginning only about the [homing position(done), microstepping mode].
TODO::Update the arduino program to make the code only iterates around the "homing position" &"microstepping mode" only once on the void setup() function.

DATA::left arrow button sends --> 1.
DATA::right arrow button sends --> 2.
DATA::stop button sends --> 3.

DATA::rail length (1cm - 1000cm) --> (201 - 1200).

DATA::motor acceleration spinner Very High --> 14.
DATA::motor acceleration spinner High --> 11
DATA::motor acceleration spinner Medium --> 12
DATA::motor acceleration spinner Low --> 13
DATA::motor acceleration spinner Very Low --> 15

DATA::motor speed slider (1 step/sec. - 4000 step/sec.) --> (5001 - 9000).

DATA::delay start checkbox is true --> 7.
DATA::delay start checkbox is false --> 8.

DATA::left end homing --> 16.
DATA::right end homing --> 17.

DATA::Smooth movement Type --> 18.
DATA::Very Smooth movement Type --> 19.

1301 --> 2300
*/

#include
#include

#define stepPin 2
#define dirPin 3

bool homingPositionFlag =false;
int startupSetupFlag =0;
bool delayedStart =false;

int incomingData =0;
int movementDistance =50;
long steps =0; //50cm rail by default @1/8 microstepping.
int microStepResolution =0; //4 or 16
long railLength =0;
int sliderSpeed =10;

AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin); //create an object. the pin "2" is the step pin, "3" is the direction pin.

void setup() {
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
Serial.begin(9600);

stepper.setMaxSpeed(10.00); //The fastest motor speed that can be reliably supported is about 4000 steps per second at a clock frequency of 16 MHz on Arduino such as Uno
stepper.setAcceleration(500.00); //1600 (40%) (Medium Acceleration rate)

while (startupSetupFlag <3) {
if (Serial.available()> 1) {
unsigned int dataOne =Serial.read();
unsigned int dataOne1 =Serial.read();
unsigned int incomingData =(dataOne1 * 256) + dataOne;

//**************************************************************Motor Homing Part**************************************************
if (incomingData ==16) { //left end homing position.
stepper.setCurrentPosition(steps);
homingPositionFlag =false;
startupSetupFlag++;
} else if (incomingData ==17) { //right end homing position.
stepper.setCurrentPosition(-(steps));
homingPositionFlag =true;
startupSetupFlag++;
}
//**************************************************************microstep resolution Part**************************************************
if (incomingData ==18) {
microStepResolution =4; //50cm rail length @1/4 microstep resolution.
startupSetupFlag++;
} else if (incomingData ==19) {
microStepResolution =16; //50cm rail length @1/16 microstep resolution.
startupSetupFlag++;
}

if (incomingData>=1301 &&incomingData <=2300) {
railLength =incomingData - 1300; //from raw data to cm.
if (microStepResolution ==4) {
steps =((6100L * railLength) / 50L);
startupSetupFlag++;
}
else if (microStepResolution ==16) {
steps =((25000L * railLength) / 50L);
startupSetupFlag++;
}
}
}
//Serial.println(startupSetupFlag);
}
/*
* *********** *********** **********For Debugging Purposes* *********** *********** **********
Serial.print("rail length:");
Serial.print(railLength);
Serial.print(" number of steps:");
Serial.print(steps);
Serial.print(" Homing position:");
Serial.print(stepper.currentPosition());
Serial.print(" microstep resolution:");
Serial.println(microStepResolution);*/
}

void loop() {

if (Serial.available()> 1) {

unsigned int dataOne =Serial.read();
unsigned int dataOne1 =Serial.read();
unsigned int incomingData =(dataOne1 * 256) + dataOne;
//Serial.print("raw data:");
//Serial.println(incomingData);

//**************************************************************Motor Control Part**************************************************
if (incomingData ==1 &&stepper.isRunning() ==false &&stepper.currentPosition() !=6050 &&homingPositionFlag ==true) {
if (delayedStart ==true) { //use millis to delay 15 seconds.
delay(15000); //wait 15 seconds.
}
stepper.setCurrentPosition(0);
stepper.moveTo(steps); //from end to end (@ 1/4 step).
homingPositionFlag =false;

/*Serial.print("rail length:");
Serial.print(railLength);
Serial.print(" number of steps:");
Serial.print(steps);
Serial.print(" Homing position:");
Serial.print(stepper.currentPosition());
Serial.print(" microstep resolution:");
Serial.println(microStepResolution);*/
}

else if (incomingData ==2 &&stepper.isRunning() ==false &&stepper.currentPosition() !=-6050 &&homingPositionFlag ==false) {
if (delayedStart ==true) { //use millis to delay 15 seconds.
delay(15000); //wait 15 seconds.
}
stepper.setCurrentPosition(0);
stepper.moveTo(-(steps)); //from end to end (@ 1/4 step).
homingPositionFlag =true;

/*Serial.print("rail length:");
Serial.print(railLength);
Serial.print(" number of steps:");
Serial.print(steps);
Serial.print(" Homing position:");
Serial.print(stepper.currentPosition());
Serial.print(" microstep resolution:");
Serial.println(microStepResolution);*/
}

else if (incomingData ==3 &&stepper.isRunning() ==true) {
homing();
}

//**************************************************************Set Max. Speed Part**************************************************
else if (incomingData>=5001 &&incomingData <=9000) {
sliderSpeed =incomingData - 5000;
stepper.setMaxSpeed(sliderSpeed);
}

//**************************************************************Set Delayed Start Part**************************************************
else if (incomingData ==7) { //delayed start (15 seconds) is checked "true"
delayedStart =true;
}
else if (incomingData ==8) { //delayed start (15 seconds) is not checked "false"
delayedStart =false;
}

//**************************************************************Set movement distance Part**************************************************
else if (incomingData>=201 &&incomingData <=1200) { //convertin from rail length into number of steps. (upto 10 meters)
movementDistance =incomingData - 200; //from raw data to cm.
if (microStepResolution ==4) {
steps =((6100L * movementDistance) / 50L);
}
else if (microStepResolution ==16) {
steps =((25000L * movementDistance) / 50L);
}
/*Serial.print("rail length:");
Serial.print(movementDistance);
Serial.print(" number of steps:");
Serial.println(steps);*/
}

//**************************************************************Set Acceleration Part**************************************************
else if (incomingData ==11 &&stepper.isRunning() ==false) { //HIGH
stepper.setAcceleration(3000);
}

else if (incomingData ==12 &&stepper.isRunning() ==false) { //Medium
stepper.setAcceleration(1000);
}

else if (incomingData ==13 &&stepper.isRunning() ==false) { //Low
stepper.setAcceleration(500);
}

else if (incomingData ==14 &&stepper.isRunning() ==false) { //Very High
stepper.setAcceleration(4000);
}

else if (incomingData ==15 &&stepper.isRunning() ==false) { //Very Low
stepper.setAcceleration(10);
}
}
stepper.run();
}

void homing() {
if (stepper.currentPosition()> 0) {
homingPositionFlag =true;
} else {
homingPositionFlag =false;
}
stepper.moveTo(0);
}

Code Logic

We’re using the amazing AccelStepper Arduino library that provides an object-oriented interface for 2, 3, 4 pins stepper motors to control it’s movement precisely.

#define stepPin 2
#define dirPin 3

bool homingPositionFlag =false;

int startupSetupFlag =0;
bool delayedStart =false;

int incomingData =0;
int movementDistance =50;

long steps =0; //50cm rail by default @1/8 microstepping.
int microStepResolution =0; //4 or 16

long railLength =0;
int sliderSpeed =10;

AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin); //create an object. the pin "2" is the step pin, "3" is the direction pin.

when you open the mobile app and get connected to the Cairo camera slider it will ask you about the micro-stepping mode that you set the A4988 motor driver to work at. it’s very important to choose the correct micro-stepping mode. The Cairo camera slider only supports the 1/4 and 1/16 micro-step resolution. If you chose a wrong micro-step mode it will affect the distance calculations causing the camera carriage to hit the slider limits. So, be careful!

  • 1/4 --> Smooth.
  • 1/16 --> Very Smooth.
//**************************************************************microstep resolution Part**************************************************
if (incomingData ==18) {
microStepResolution =4; //50cm rail length @1/4 microstep resolution.
startupSetupFlag++;

} else if (incomingData ==19) {
microStepResolution =16; //50cm rail length @1/16 microstep resolution.
startupSetupFlag++;
}

It sets the camera slider homing if it’s left or right side homing. the homing position, once you click on right or left side homing a specific piece of data will get sent from the mobile app to the Arduino board according to the homing position that you have chosen.

void setup() {
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
Serial.begin(9600);

stepper.setMaxSpeed(10.00); //The fastest motor speed that can be reliably supported is about 4000 steps per second at a clock frequency of 16 MHz on Arduino such as Uno
stepper.setAcceleration(500.00); //1600 (40%) (Medium Acceleration rate)

while (startupSetupFlag <3) {
if (Serial.available()> 1) {
unsigned int dataOne =Serial.read();
unsigned int dataOne1 =Serial.read();
unsigned int incomingData =(dataOne1 * 256) + dataOne;

//**************************************************************Motor Homing Part**************************************************
if (incomingData ==16) { //left end homing position.
stepper.setCurrentPosition(steps);
homingPositionFlag =false;
startupSetupFlag++;
}
else if (incomingData ==17) { //right end homing position.
stepper.setCurrentPosition(-(steps));
homingPositionFlag =true;
startupSetupFlag++;
}

now it sets how many steps should the stepper motor moves without hitting the camera carriage with the camera slider right or left legs. it reads and saves the rail length according to the value that the user enters in the mobile app. So, depending on the micro-step resolution that the user selected before, and the rail length I can calculate the number of steps that the motor should rotate to reach the limits of the slider rail without hitting the right or left legs.

if (incomingData>=1301 &&incomingData <=2300) {
railLength =incomingData - 1300; //from raw data to cm.
if (microStepResolution ==4) {
steps =((6100L * railLength) / 50L);
startupSetupFlag++;
}
else if (microStepResolution ==16) {
steps =((25000L * railLength) / 50L);
startupSetupFlag++;
}
}
}
//Serial.println(startupSetupFlag);
}

inside the loop function, it reads the mobile app incoming data and according to these data it takes different actions, like moving the stepper motor clockwise, moving anti-clockwise, stop and return back to the starting point, and changing the traveling speed, so on…

void loop() {

if (Serial.available()> 1) {

unsigned int dataOne =Serial.read();
unsigned int dataOne1 =Serial.read();
unsigned int incomingData =(dataOne1 * 256) + dataOne;
//Serial.print("raw data:");
//Serial.println(incomingData);

//**************************************************************Motor Control Part**************************************************
if (incomingData ==1 &&stepper.isRunning() ==false &&stepper.currentPosition() !=6050 &&homingPositionFlag ==true) {
if (delayedStart ==true) { //use millis to delay 15 seconds.
delay(15000); //wait 15 seconds.
}
stepper.setCurrentPosition(0);
stepper.moveTo(steps); //from end to end (@ 1/4 step).
homingPositionFlag =false;

/*Serial.print("rail length:");
Serial.print(railLength);
Serial.print(" number of steps:");
Serial.print(steps);
Serial.print(" Homing position:");
Serial.print(stepper.currentPosition());
Serial.print(" microstep resolution:");
Serial.println(microStepResolution);*/
}

else if (incomingData ==2 &&stepper.isRunning() ==false &&stepper.currentPosition() !=-6050 &&homingPositionFlag ==false) {
if (delayedStart ==true) { //use millis to delay 15 seconds.
delay(15000); //wait 15 seconds.
}
stepper.setCurrentPosition(0);
stepper.moveTo(-(steps)); //from end to end (@ 1/4 step).
homingPositionFlag =true;

/*Serial.print("rail length:");
Serial.print(railLength);
Serial.print(" number of steps:");
Serial.print(steps);
Serial.print(" Homing position:");
Serial.print(stepper.currentPosition());
Serial.print(" microstep resolution:");
Serial.println(microStepResolution);*/
}

else if (incomingData ==3 &&stepper.isRunning() ==true) {
homing();
}

//**************************************************************Set Max. Speed Part**************************************************
else if (incomingData>=5001 &&incomingData <=9000) {
sliderSpeed =incomingData - 5000;
stepper.setMaxSpeed(sliderSpeed);
}

//**************************************************************Set Delayed Start Part**************************************************
else if (incomingData ==7) { //delayed start (15 seconds) is checked "true"
delayedStart =true;
}
else if (incomingData ==8) { //delayed start (15 seconds) is not checked "false"
delayedStart =false;
}

//**************************************************************Set movement distance Part**************************************************
else if (incomingData>=201 &&incomingData <=1200) { //convertin from rail length into number of steps. (upto 10 meters)
movementDistance =incomingData - 200; //from raw data to cm.
if (microStepResolution ==4) {
steps =((6100L * movementDistance) / 50L);
}
else if (microStepResolution ==16) {
steps =((25000L * movementDistance) / 50L);
}
/*Serial.print("rail length:");
Serial.print(movementDistance);
Serial.print(" number of steps:");
Serial.println(steps);*/
}

//**************************************************************Set Acceleration Part**************************************************
else if (incomingData ==11 &&stepper.isRunning() ==false) { //HIGH
stepper.setAcceleration(3000);
}

else if (incomingData ==12 &&stepper.isRunning() ==false) { //Medium
stepper.setAcceleration(1000);
}

else if (incomingData ==13 &&stepper.isRunning() ==false) { //Low
stepper.setAcceleration(500);
}

else if (incomingData ==14 &&stepper.isRunning() ==false) { //Very High
stepper.setAcceleration(4000);
}

else if (incomingData ==15 &&stepper.isRunning() ==false) { //Very Low
stepper.setAcceleration(10);
}
}
stepper.run();
}

void homing() {
if (stepper.currentPosition()> 0) {
homingPositionFlag =true;
} else {
homingPositionFlag =false;
}
stepper.moveTo(0);
}

Cairo Camera Slider User Guide &troubleshooting

After connecting the 12V power source to the Arduino UNO board that distributes power to the Cairo camera slider Arduino shield as well, turn on the Bluetooth on your mobile, search for new devices, pair with the HC-05 device, and open the mobile app then press on the “Press here to connect with Cairo camera slider” button. It will show up the menu of the paired Bluetooth devices, select the HC-05 Bluetooth device.

After connecting successfully with the Control board, the mobile app will ask you some questions to set up some parameters. First question will ask you about the micro-step resolution of the stepper motor driver if it’s smooth(1/4 micro-step), or very smooth(1/16 micro-step). select the mode According to the micro-stepping resolution mode that you set the A4988 driver at. If you selected a wrong mode The Cairo camera slider will not work correctly.

Then, it will ask you about the aluminum rail length that you are using in your camera slider. Enter the distance in CM. in my case I’m using a 50cm rail length.

Lastly, it will ask you about the camera carriage homing position, It’s very important to place the camera carriage on one of the two rail ends, the right end or the left end. In my case, the camera carriage is on the left end. So, I selected the left end homing.

If you started the Cairo camera slider and the camera carriage is on the middle of the rail or not on one of the two rail ends it will cause the carriage to hit the limits when it moves.

After you finish the set-up process, It will show you the parameters that you have set. And once you click OK, you will be ready to play around with your lovely Cairo camera slider.

Cairo Camera Slider In-Action


Code

  • Cairo Camera Slider Final Code
Cairo Camera Slider Final CodeArduino
/* TODO::Update the arduino program to Make the user able to choose the motor driver micro stepping mode. find and equation that helps to automatically adjust the the "steps" variable value. TODO::update the mobile app to ask the user on the beginning only about the [homing position(done), microstepping mode]. TODO::Update the arduino program to make the code only iterates around the "homing position" &"microstepping mode" only once on the void setup() function. DATA::left arrow button sends --> 1. DATA::right arrow button sends --> 2. DATA::stop button sends --> 3. DATA::rail length (1cm - 1000cm) --> (201 - 1200). DATA::motor acceleration spinner Very High --> 14. DATA::motor acceleration spinner High --> 11 DATA::motor acceleration spinner Medium --> 12 DATA::motor acceleration spinner Low --> 13 DATA::motor acceleration spinner Very Low --> 15 DATA::motor speed slider (1 step/sec. - 4000 step/sec.) --> (5001 - 9000). DATA::delay start checkbox is true --> 7. DATA::delay start checkbox is false --> 8. DATA::left end homing --> 16. DATA::right end homing --> 17. DATA::Smooth movement Type --> 18. DATA::Very Smooth movement Type --> 19. 1301 --> 2300*/#include #include #define stepPin 2#define dirPin 3bool homingPositionFlag =false;int startupSetupFlag =0;bool delayedStart =false;int incomingData =0;int movementDistance =50;long steps =0; //50cm rail by default @1/8 microstepping.int microStepResolution =0; //4 or 16long railLength =0;int sliderSpeed =10;AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin); //create an object. the pin "2" is the step pin, "3" is the direction pin.void setup() { pinMode(stepPin, OUTPUT); pinMode(dirPin, OUTPUT); Serial.begin(9600); stepper.setMaxSpeed(10.00); //The fastest motor speed that can be reliably supported is about 4000 steps per second at a clock frequency of 16 MHz on Arduino such as Uno stepper.setAcceleration(500.00); //1600 (40%) (Medium Acceleration rate) while (startupSetupFlag <3) { if (Serial.available()> 1) { unsigned int dataOne =Serial.read(); unsigned int dataOne1 =Serial.read(); unsigned int incomingData =(dataOne1 * 256) + dataOne; //**************************************************************Motor Homing Part************************************************** if (incomingData ==16) { //left end homing position. stepper.setCurrentPosition(steps); homingPositionFlag =false; startupSetupFlag++; } else if (incomingData ==17) { //right end homing position. stepper.setCurrentPosition(-(steps)); homingPositionFlag =true; startupSetupFlag++; } //**************************************************************microstep resolution Part************************************************** if (incomingData ==18) { microStepResolution =4; //50cm rail length @1/4 microstep resolution. startupSetupFlag++; } else if (incomingData ==19) { microStepResolution =16; //50cm rail length @1/16 microstep resolution. startupSetupFlag++; } if (incomingData>=1301 &&incomingData <=2300) { railLength =incomingData - 1300; //from raw data to cm. if (microStepResolution ==4) { steps =((6100L * railLength) / 50L); startupSetupFlag++; } else if (microStepResolution ==16) { steps =((25000L * railLength) / 50L); startupSetupFlag++; } } } //Serial.println(startupSetupFlag); } /* * *********** *********** **********For Debugging Purposes* *********** *********** ********** Serial.print("rail length:"); Serial.print(railLength); Serial.print(" number of steps:"); Serial.print(steps); Serial.print(" Homing position:"); Serial.print(stepper.currentPosition()); Serial.print(" microstep resolution:"); Serial.println(microStepResolution);*/}void loop() { if (Serial.available()> 1) { unsigned int dataOne =Serial.read(); unsigned int dataOne1 =Serial.read(); unsigned int incomingData =(dataOne1 * 256) + dataOne; //Serial.print("raw data:"); //Serial.println(incomingData); //**************************************************************Motor Control Part************************************************** if (incomingData ==1 &&stepper.isRunning() ==false &&stepper.currentPosition() !=6050 &&homingPositionFlag ==true) { if (delayedStart ==true) { //use millis to delay 15 seconds. delay(15000); //wait 15 seconds. } stepper.setCurrentPosition(0); stepper.moveTo(steps); //from end to end (@ 1/4 step). homingPositionFlag =false; /*Serial.print("rail length:"); Serial.print(railLength); Serial.print(" number of steps:"); Serial.print(steps); Serial.print(" Homing position:"); Serial.print(stepper.currentPosition()); Serial.print(" microstep resolution:"); Serial.println(microStepResolution);*/ } else if (incomingData ==2 &&stepper.isRunning() ==false &&stepper.currentPosition() !=-6050 &&homingPositionFlag ==false) { if (delayedStart ==true) { //use millis to delay 15 seconds. delay(15000); //wait 15 seconds. } stepper.setCurrentPosition(0); stepper.moveTo(-(steps)); //from end to end (@ 1/4 step). homingPositionFlag =true; /*Serial.print("rail length:"); Serial.print(railLength); Serial.print(" number of steps:"); Serial.print(steps); Serial.print(" Homing position:"); Serial.print(stepper.currentPosition()); Serial.print(" microstep resolution:"); Serial.println(microStepResolution);*/ } else if (incomingData ==3 &&stepper.isRunning() ==true) { homing(); } //**************************************************************Set Max. Speed Part************************************************** else if (incomingData>=5001 &&incomingData <=9000) { sliderSpeed =incomingData - 5000; stepper.setMaxSpeed(sliderSpeed); } //**************************************************************Set Delayed Start Part************************************************** else if (incomingData ==7) { //delayed start (15 seconds) is checked "true" delayedStart =true; } else if (incomingData ==8) { //delayed start (15 seconds) is not checked "false" delayedStart =false; } //**************************************************************Set movement distance Part************************************************** else if (incomingData>=201 &&incomingData <=1200) { //convertin from rail length into number of steps. (upto 10 meters) movementDistance =incomingData - 200; //from raw data to cm. if (microStepResolution ==4) { steps =((6100L * movementDistance) / 50L); } else if (microStepResolution ==16) { steps =((25000L * movementDistance) / 50L); } /*Serial.print("rail length:"); Serial.print(movementDistance); Serial.print(" number of steps:"); Serial.println(steps);*/ } //**************************************************************Set Acceleration Part************************************************** else if (incomingData ==11 &&stepper.isRunning() ==false) { //HIGH stepper.setAcceleration(3000); } else if (incomingData ==12 &&stepper.isRunning() ==false) { //Medium stepper.setAcceleration(1000); } else if (incomingData ==13 &&stepper.isRunning() ==false) { //Low stepper.setAcceleration(500); } else if (incomingData ==14 &&stepper.isRunning() ==false) { //Very High stepper.setAcceleration(4000); } else if (incomingData ==15 &&stepper.isRunning() ==false) { //Very Low stepper.setAcceleration(10); } } stepper.run();}void homing() { if (stepper.currentPosition()> 0) { homingPositionFlag =true; } else { homingPositionFlag =false; } stepper.moveTo(0);}

Pièces et boîtiers personnalisés

Cairo Camera Slider STLs
Fichier CAO sur thingverse.com

Schémas


Processus de fabrication

  1. Appareil photo
  2. Objectif de la caméra
  3. Lecteur de livres BrickPi
  4. Arduino Spybot
  5. FlickMote
  6. Téléviseur maison B-Gone
  7. horloge maîtresse
  8. Trouvez-moi
  9. La caméra capture des images de l'intérieur d'objets solides