Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Arduino Bluetooth-gestuurde gemotoriseerde cameraschuifregelaar

Componenten en benodigdheden

Arduino UNO
× 1
PCBWay Custom PCB
https://www.pcbway.com/project/shareproject/Arduino_Motorized_Camera_Slider.html
× 1
V-sleuf 20×40 lineaire rail
de gewenste lengte.
× 1
Solid V-wielset
× 4
Solid V-wielset
× 4
Drop In Tee Nuts
× 4
Drop In Tee Nuts
× 4
Excentrische Spacer
× 2
Excentrische Spacer
× 2
9 mm aluminium afstandsstuk
× 2
9 mm aluminium afstandsstuk
× 2
3 mm aluminium spacer
× 2
M5-schroeven met laag profiel, lengte 20 mm met moeren
× 4
M5-schroeven met laag profiel, lengte 10 mm
× 4
M3 Allen HEX-schroeven lengte 16 mm met moeren
× 8
8 mm zelfinstellend kussenflensbloklager
× 2
GT2 Boring 8 mm 20 Tanden Timing Aluminium Katrol
× 1
8 mm lineaire railschacht
60 mm lengte
× 1
GT2 Boring 5 mm 20 Tanden Timing Aluminium Katrol
× 1
GT2-6 mm open distributieriem
de lengte van de riem, hangt af van de lengte van de aluminium profielrail
× 1
bipolaire Nema17 stappenmotor
× 1
A4988 Stappenmotorstuurprogramma
× 1
12V 3A oplaadbare batterij
× 1
HC-05 Bluetooth-module
× 1

Benodigde gereedschappen en machines

3D-printer (algemeen)

Apps en online services

Autodesk Fusion 360
Aurodesk-Eagle
Arduino IDE

Over dit project

Projectoverzicht

Voor iemand die graag wat willekeurige hobbyvideo's maakt, is het op de een of andere manier duur om een ​​gemotoriseerde cameraschuifregelaar te kopen. Dus ik heb mijn eigen gebouwd. In deze zelfstudie zullen we elke stap doorlopen om uw eigen Bluetooth-gestuurde gemotoriseerde cameraschuifregelaar te bouwen.

Vandaag zullen we een gemotoriseerde cameraschuifregelaar bouwen die we draadloos kunnen bedienen via Bluetooth vanuit een op maat gemaakte mobiele Android-app. Ik heb de tool "MIT App-uitvinder" gebruikt om de app te maken die ons de mogelijkheid geeft om veel dingen te regelen, zoals de bewegingssnelheid van de schuifregelaar, reisafstand, acceleratie-/deceleratiesnelheid en nog veel meer. De mobiele app is zeer robuust, in de app kun je de lengte van de cameraschuifregelaar instellen die je gebruikt. wat betekent dat je vrij bent om je daadwerkelijke cameraschuifregelaar te bouwen met elke lengte tot 10 meter zonder je zorgen te maken over de app.

We hebben een NEMA17-stappenmotor als actuator gebruikt, zodat we kunnen bepalen hoeveel stappen we nodig hebben om de cameraschuifregelaar te verplaatsen. Om een ​​stappenmotor te besturen met behulp van het Arduino-bord, hebben we een vertaler nodig die de opdrachten van het Arduino-bord overneemt en vertaalt naar de taal die de stappenmotor begrijpt. Hier komt de rol van de A4988 Pololu-stappenmotor, die ons vijf verschillende microstapresoluties geeft (tot 1/16 stap) om de maximale bewegingsnauwkeurigheid en bewegingssoepelheid te bereiken.

Dit project Ontworpen met maakbaarheid in een fablab/makerspace/hackerspace in gedachten.

CAD en 3D-modellering

We hebben Fusion360 gebruikt om de cameraschuifregelaar te ontwerpen, we hebben ervoor gekozen om zeer bekende, gemakkelijk te vinden mechanische componenten te gebruiken die je gemakkelijk kunt kopen bij bijna elke online of offline winkel, waar je ook woont.

We gebruiken Openbuilds-hardware om de mechanische structuur te bouwen, de V-slot 2040 lineaire rail als richtlijn voor de camera om verder te gaan. Twee katrollen, één op de as van de stappenmotor. En de andere, op een 8 mm lineaire railas aan de andere kant van de schuif met een open distributieriem ertussen om van de roterende beweging van de stappenmotor naar lineaire beweging om te zetten.

De 8 mm lineaire railas is geïnstalleerd tussen twee zelfinstellende kussenflensbloklagers die op de boven- en onderplaat zijn geïnstalleerd met vier M5-schroeven.

We gebruiken vier Delrin V-Slot massieve wielen die ze naar beneden rijden in de V-groef van de V-Slot rail om de camerabeweging extreem soepel te laten verlopen. Het midden van de cameraplaat heeft een gat met een diameter van 1/4 inch voor een standaard statiefschroef, zodat u uw camera gemakkelijk kunt monteren.

Ten slotte een behuizing voor de elektronica. Alle onderdelen van de cameraschuif zijn aan elkaar bevestigd met m3 * 16 mm-schroeven en moeren.

Digitale fabricage (3D-printen)

De hele body van de cameraschuifregelaar is 3D-geprint met een hoogte van 0,2 laag, 20% vulling, behalve de linker- en rechterpoot van de camera, zijn bedrukt met een hoogte van 0,2 laag, 50% vulling.

u kunt de STL-bestanden downloaden van Thingiverse.

Montage V-wielset

Het montageproces is heel eenvoudig man, kom op! In de eerste stap moeten we de vier Solid V-Wheels monteren. De solide V-wielset wordt geleverd met een rubberen wiel, twee lagers, twee percisie-shims en een borgmoer.

Plaats het lager vanaf één kant van het rubberen wiel en draai het wiel om, plaats vervolgens een precisie-shim in het rubberen wiel, plaats als laatste het tweede lager vanaf de tweede zijde.

Cameraschuif Mechanische montage

Eerst moeten we de cameraplaat en de vier solide V-Wheels monteren. met behulp van de 9 mm aluminium spacer, de precisie-shim en de borgmoer.

We gaan de vorige stap herhalen met de andere drie wielen. in de twee rechterwielen gaan we de 9 mm spacer gebruiken. En voor de andere twee linkerwielen gaan we de excentrische spacer gebruiken met een spacer van 3 mm in plaats van de spacer van 9 mm.

Plaats nu de camerahouderplaat in het V-sleufprofiel. Als u merkt dat de plaat los zit en wiebelt, kunt u de excentrische moer vastdraaien totdat u een stevige plaat krijgt.

Laten we twee drop-in T-moeren in elk uiteinde van het V-sleufprofiel plaatsen. we moeten het V-sleufprofiel verbinden met de rechter- en linkerpoot van de cameraschuifregelaar.

Pak de twee cameraschuifpoten en duw ze in het V-sleufprofiel.

breng vier M5X10mm-schroeven mee en bevestig de twee poten met het V-sleufprofiel.

We moeten de NEMA 17 stappenmotor op zijn plaat installeren. dan gaan we met behulp van vier M3X16mm-schroeven de motor op zijn plaats bevestigen.

Steek op het linkerbeen twee moeren in de bovenste moeren van het linkerbeen.

Breng de NEMA 17 motorplaat aan en bevestig deze op de bovenkant van het linkerbeen. en met behulp van twee M3X16mm-schroeven gaan we de plaat op het linkerbeen bevestigen.

Om de rotatiebeweging van de stappenmotor om te zetten in lineaire beweging, moeten we een GT2 Bore 5 mm poelie op de motoras installeren. en draai met de inbussleutel de stelschroef van de poelie vast om hem op zijn plaats te houden.

Laten we naar de rechterpoot van de cameraschuif gaan, plaats vier M3-moeren in de plaats van de pootmoeren.

Plaats vervolgens het rechterbeen met twee platen op de bovenkant van het rechterbeen van de cameraschuif.

Gebruik vier M3X16mm-schroeven om de twee platen op de rechterpoot van de cameraschuif vast te zetten om ze op hun plaats te houden.

Breng een van de 8 mm flensbloklagers mee en installeer deze op de pootplaat rechtsboven. met twee M5X20mm-schroeven en twee M5-moeren.

We moeten de vorige stap herhalen met het tweede 8 mm flenslagerblok om het op de bodemplaat van het rechterbeen van de cameraschuif te bevestigen.

Steek de 8 mm lineaire railas in het 8 mm flenslagerblok vanaf de onderkant, en duw deze naar boven. Steek vervolgens de poelie met een boring van 8 mm in de lineaire railas en zet deze vast door de stelschroef van de poelie vast te draaien.

Checkpoint, nu hebben we alle cameraschuifmechanismen gemonteerd, behalve één ding. de distributieriem. Laten we het doen.

draai de 6 mm distributieriem op de NEMA17 motor 5 mm boring poelie. Ook op het rechterbeen een katrol met een boring van 8 mm. Span ten slotte de riem aan met de cameraplaat.

Het is tijd om de besturingskaart te monteren. plaats het Arduino-schild van de Cairo Camera Slider op de bovenkant van het Arduino-bord.

Plaats het Arduino-bord en het Cairo Camera Slider-schild in de behuizing van de besturingskaart.

steek twee M3-moeren in de plaats van de moeren van het linkerbeen.

installeer de behuizing van de besturingskaart op de linkerpoot van de Cairo Camera Slider met M3X16mm-schroeven.

sluit de bovenkant van de behuizing met twee M3-schroeven en moeren, en dat is alles!

Stappenmotor testbesturing

Nadat we alle onderdelen in elkaar hebben gezet, moeten we het testen om er zeker van te zijn dat alles correct op zijn plaats is geïnstalleerd. Nu moeten we de stappenmotor verbinden met het Arduino-bord via de A4988-stappenmotordriver en wat code schrijven om dat ding uit te voeren.

A4988 stappenmotor driver

Om een ​​stappenmotor te besturen met behulp van het Arduino-bord of een microcontroller, heb je een stappenmotorstuurprogramma nodig dat als vertaler werkt, opdrachten van het Arduino-bord overneemt en deze vertaalt naar de taal die de motor begrijpt.

er zijn veel stappenmotordrivers, maar we zullen de A4988-driver gebruiken . Met deze driver kunnen we één bipolaire motor besturen met een uitgangsstroom tot 2A per spoel, het is heel eenvoudig om te communiceren met het Arduino-bord. Je hebt slechts twee digitale pinnen nodig om de stap en richting van je motor volledig te regelen, zodat je de maximale stroomoutput kunt regelen gemakkelijk met een ingebouwde potentiometer, en geeft u een resolutie van microstappen tot 1/16 microstap.

VMOT, GND: Het zijn de stroomaansluitingspinnen voor de stappenmotor zelf, het kan 8V-35V zijn. In ons geval sluiten we een 12V 3A-voedingsbron op die pinnen aan met een ontkoppelingscondensator van 100 uf om het A4998-bord te beschermen tegen eventuele stroompieken.

2B, 2A: de uitgangspinnen voor de eerste spoel van de stappenmotor die tot 2A kan leveren.

1A, 1B: de uitgangspinnen voor de tweede spoel van de stappenmotor die ook tot 2A kan leveren.

VDD, GND: Gebruikt voor het aansturen van de interne logische schakelingen, kan 3V tot 5,5V zijn. Het is volledig geïsoleerd van de VMOT-pin.

NL: Staat voor "Inschakelen", het is een actieve LOW (0V) invoerpin, wat betekent dat wanneer deze pin LAAG (0V) wordt getrokken, de A4988-chip is ingeschakeld. En wanneer HIGH (5V) wordt getrokken, is de A4988-chip uitgeschakeld. Standaard staat deze pin op LAAG (0V). De chip is dus altijd ingeschakeld, tenzij je hem HOOG (5V) trekt.

MS1, MS2, MS3: Via deze pinnen kunt u uw motormicrostepping-resolutie (stapgrootte) selecteren. De A4988 geeft je vijf verschillende microstap resoluties (volledige stap, halve stap, kwart stap, achtste stap, zestiende stap) . Door de juiste logische niveaus toe te passen op deze drie pinnen, kunnen we de motoren instellen op een van de vijf stappen resoluties.

Standaard is de MS1, MS2, MS3 pinnen hebben interne pull-down weerstanden. Dus als u deze drie microstap-selectiepinnen los laat, krijgt u de volledige stapmodus.

RST, SLP: De “Reset” pin is een actieve LAGE (0V) invoerpin, wat betekent dat wanneer deze LAAG (0V) wordt getrokken, alle stapinvoer wordt genegeerd, het ook de vertaler zelf reset totdat u hem HOOG (5V) trekt. De “Slaap” pin ook een actieve LOW-pin, door deze LOW te trekken, wordt de bestuurder in de slaapstand gezet en wordt het stroomverbruik geminimaliseerd. Standaard is de “Slaap” pin is HOOG (5V) getrokken.

STP, DIR: De “Stap” pin is verantwoordelijk voor het regelen van het aantal stappen dat de motor draait, elke puls naar de “Stap” pin komt overeen met één microstap in de richting geselecteerd door de “Direction” pin, hoe sneller de pulsen, hoe sneller de motor zal draaien. Door logische waarde HOOG (5V) toe te passen op de “Richting” pin zorgt ervoor dat de motor met de klok mee draait, door LOW (0V) toe te passen, draait de motor tegen de klok in(het kan van de ene naar de andere verschillen, afhankelijk van uw motorbedrading met de driver).

NEMA17 Stappenmotor

Stappenmotoren zijn gelijkstroommotoren die in nauwkeurige stappen kunnen draaien, ze worden gebruikt in veel toepassingen zoals 3D-printers om de printkop uit te lijnen en CNC-machines om de beweging van het snijgereedschap te regelen en dit komt omdat ze zeer nauwkeurig en precies zijn.

In tegenstelling tot DC-motoren worden stappenmotoren bestuurd door elektrische DC-pulsen op hun interne spoelen aan te brengen. Elke puls zorgt ervoor dat de as één stap of een fractie van een stap vooruit gaat, wat "microstepping" wordt genoemd. U kunt dus precies bepalen hoeveel stappen of zelfs fractiestappen u de motoras wilt laten bewegen. Een ander groot voordeel van het gebruik van stappenmotoren is dat het zeer nauwkeurig en nauwkeurig kan bewegen bij zeer lage snelheden zonder zelfs maar te stoppen.

Het type motor dat we in dit project gebruiken is de NEMA 17 Bipolaire stappenmotor . De bipolaire stappenmotor heeft twee interne spoelen en heeft meestal vier draden, twee draden per spoel. in tegenstelling tot de bipolaire stappenmotor die vijf draden heeft. De "Staphoek" van de motor is 1.8° die aangeeft hoeveel de as in elke volledige stap vooruitgaat, de motor werkt op 9V, maar als je het maximale vermogen wilt krijgen, gebruik dan een 12V-stroombron.

Dus door de stappenmotor te verbinden met de A4988 stappenmotordriver, kunnen we bepalen hoeveel stappen we nodig hebben om de motor te bewegen en in welke richting. We kunnen ook de "microstep" -modus instellen, is het volledige stap, halve stap, kwart stap, ... Laten we eens kijken naar het bedradingsschema.

Bedradingsschema

Zoals we eerder zeiden, moeten we een kleine controle uitvoeren om er zeker van te zijn dat alles wat we eerder hebben geassembleerd goed op zijn plaats zit en goed beweegt. Nu gaan we alle hardware met elkaar verbinden, de NEMA 17-stappenmotor met de A4988-stappenmotorstuurprogramma voor de hersenen, het Arduino-bord. En met een 12V 3A lithium-ionbatterij om de motoren te voeden met het benodigde vermogen.

Arduino-code

AccelStepper Bibliotheek installeren

De installatie is vrij eenvoudig, we moeten Arduino IDE openen. Vanuit het menu "Schets". Selecteer Bibliotheek opnemen -> Bibliotheken beheren...

Een nieuw venster zou moeten verschijnen, zoek naar "AccelStepper" en installeer de bibliotheek gemaakt door "Mike McCauley". Makkelijk toch!

Nadat u de AccelStepper-bibliotheek hebt geïnstalleerd, zou u deze in het voorbeeldenmenu moeten zien.

Ik wil ervoor zorgen dat de AccelStepper-bibliotheek correct is geïnstalleerd en dat mijn stappenmotorverbinding met de A4988-motordriver goed is en dat mijn energiebeheer in orde is. Laten we dus wat regels code schrijven om onze stappenmotor vooruit en achteruit te laten lopen.

// 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);}

Aangepaste onderdelen en behuizingen

Cairo Camera Slider STLs
CAD file on thingiverse.com

Schema's


Productieproces

  1. Camera
  2. Cameralens
  3. BrickPi Bookreader
  4. Arduino Spybot
  5. FlickMote
  6. Zelfgemaakte tv B-Gone
  7. Hoofdklok
  8. Vind mij
  9. Arduino Power
  10. Tech-TicTacToe
  11. Camera legt beelden vast van het interieur van vaste objecten