Automatizált 360° forgóasztal készítése Arduinoval

Post image

Piszkozat! Utoljára szerkesztve: 30 December 2021

Bevezetés

A mai világunkban egyre inkább hódít az internetes értékesítés, sőt, úgy tűnik a világ csakis ebbe az irányba akar tartani. Ahhoz, hogy értékesíteni tudjunk jó minőségű képeket kell készítenünk, hiszen mi vásárlók csak a képek alapján tudunk döntést hozni a digitális térben egy adott termékről. De mi lenne ha azt körbe is tudnánk forgatni?

Nem kell ehhez más mint egy kis elszántság, pár kütyü és egy telefon.

Félre értés ne essék! Egy jó minőségű képhez sok minden kell. Jó fényképezőgép vagy telefon, megfelelő fények, végtelenített háttér, drága retusáló szoftverek, stb… stb… talán egy másik cikk alkalmával foglalkozunk ezzel is, de most cél a forgatható asztal és annak vezérlése!

Hozzávalók

Kép Név Piaci ár
Arduino Nano ~ 2 000 Ft
Mini léptető motor, 5V, 4-fázis, unipoláris, áttételes (STEP MOTOR 5V - 28BYJ-48-5V) ~ 3 500 Ft
Léptető motor vezérlő (ULN2003 Four-phase Five-wire Driver Board) ~ 2 700 Ft
28 cm-es forgatható tortadísztő állvány ~ 5 000 Ft

Egyéb hozzávalók

  • USB Mini-B kábel (Arduino és a vezérlőgép között)
  • Motorra hajtás fej és arra valamilyen gumi, hogy kevésbé csússzon
  • Android telefon (+ IP Webcam alkalmazás)
  • Közös LAN hálózat (telefon + vezérlő gép)
  • Zcapture alkalmazás
  • Arduino IDE alkalmazás
  • Opcionális: Go fordító + Git verziókezelő

Mielőtt belevágnál

TL;DR Ámbár nagy figyelmet fordítok a cikk írásnál a részletekre, azonban annak tartalmára garanciát vállalni nem tudok! Ezen cikk tartalmazhat olyan részeket, melyhez kellő szakmai gyakorlat és tapasztalat is szükséges lehet, így ennek hiányában ne vágjunk bele a megvalósításba, mivel az eszköz(ök) teljes meghibásodásához és/vagy garancia vesztéshez vezethet! - Bővebben »

Arduino firmware készítése

A hatékony vezérlés érdekében olyan firmwaret készítünk, amely kellő mozgásteret ad a vezérlő gépnek. Így a vezérlő gépre hárul a feladat, hogy az asztalt vezérelje, míg az Arduino kütyünk végrehajtja a kapott utasításokat.

Külsős könyvtárak

Ezeket a nagyszerű külsős könyvtárakat használtam a megvalósításnál:

Név Készítő Licensz
AccelStepper Mike McCauley GPLv3
CommandParser Anthony Zhang (Uberi) Nem találtam licenszet! :-(

Kód

Vágjunk bele a közepébe és nézzük meg a kódot. Magyarázat lentebb!


#include <CommandParser.h>
#include <AccelStepper.h>

// Config

#define MOTOR_PIN_1 8   // -> IN1 -> ULN2003 driver
#define MOTOR_PIN_2 9   // -> IN2 -> ULN2003 driver
#define MOTOR_PIN_3 10  // -> IN3 -> ULN2003 driver
#define MOTOR_PIN_4 11  // -> IN4 -> ULN2003 driver

#define MOTOR_INTERFACE_TYPE 8

AccelStepper stepper = AccelStepper(
	MOTOR_INTERFACE_TYPE,
	MOTOR_PIN_1,
	MOTOR_PIN_3,
	MOTOR_PIN_2,
	MOTOR_PIN_4
);

typedef CommandParser<10, 5, 10, 15, 64> commandParser;
commandParser parser;

// Commands

// SPEED <uint>
void cmd_SetStepperDeviceSpeed(commandParser::Argument *args, char *response) {
	stepper.setSpeed((uint32_t) args[0].asUInt64);
	Serial.println("SPEED " + String((uint32_t) args[0].asUInt64));
	strlcpy(response, "OK", commandParser::MAX_RESPONSE_SIZE);
}

// ACCEL <uint>
void cmd_SetStepperDeviceAcceleration(commandParser::Argument *args, char *response) {
	stepper.setAcceleration((uint32_t) args[0].asUInt64);
	Serial.println("ACCEL " + String((uint32_t) args[0].asUInt64));
	strlcpy(response, "OK", commandParser::MAX_RESPONSE_SIZE);
}

// MOVE <uint>
void cmd_MoveStepperDeviceToNewPosition(commandParser::Argument *args, char *response) {
	Serial.println("MOVING");
	stepper.runToNewPosition((int32_t) args[0].asUInt64);
	Serial.println("POSITION " + String((int32_t) args[0].asUInt64));
	strlcpy(response, "OK", commandParser::MAX_RESPONSE_SIZE);
}

// STATUS
void cmd_Status(commandParser::Argument *args, char *response) {
	Serial.println("SPEED " + String(stepper.speed()));
	Serial.println("POSITION " + String(stepper.currentPosition()));  
	strlcpy(response, "OK", commandParser::MAX_RESPONSE_SIZE);
}

// RESET
void cmd_Reset(commandParser::Argument *args, char *response) {
	strlcpy(response, "OK", commandParser::MAX_RESPONSE_SIZE);
	asm volatile ("jmp 0");
}


void setup() {
	// Serial init
	Serial.begin(9600);
	while (!Serial);

	Serial.println("");
	Serial.println("INIT");

	stepper.setMaxSpeed(2500);
	stepper.setAcceleration(2500);

	// Register commands  
	parser.registerCommand("/SPEED", "u", &cmd_SetStepperDeviceSpeed);
	Serial.println("Register command: /SPEED u");

	parser.registerCommand("/ACCEL", "u", &cmd_SetStepperDeviceAcceleration);
	Serial.println("Register command: /ACCEL u");

	parser.registerCommand("/MOVE", "i", &cmd_MoveStepperDeviceToNewPosition);  
	Serial.println("Register command: /MOVE i");

	parser.registerCommand("/STATUS", "", &cmd_Status);
	Serial.println("Register command: /STATUS");  

	parser.registerCommand("/RESET", "", &cmd_Reset);
	Serial.println("Register command: /RESET");

	// Print commands
	Serial.println("REVISION 4");
	Serial.println("INIT COMPLETE");
}

void loop() {
	// Command handler
	if (Serial.available()) {
		char line[256];
		size_t lineLength = Serial.readBytesUntil('\n', line, 255);
		line[lineLength] = '\0';

		char response[commandParser::MAX_RESPONSE_SIZE];
		parser.processCommand(line, response);
		Serial.println(response);
	}
}

Magyarázat

Mit csinál ez a kód?

  • Konfigurálhatjuk tetszés szerint, hogy az Arduino mely digitális lábait használjuk.

Bekötés az alapértelmezett étékek szerint:

Arduino ULN2003
MOTOR_PIN_1 D8 ➡️ IN1
MOTOR_PIN_2 D9 ➡️ IN2
MOTOR_PIN_3 D10 ➡️ IN3
MOTOR_PIN_4 D11 ➡️ IN4

Megjegyzés: A bekötésnél Én a motort USB portról hajtom meg, azaz a motor az 5V-ot az Arduino 5V-os lábáról kapja. Azonban ezt nagyobb motoroknál ne csináld így! Külön tápegységről hajtsd meg a motort és közösítsd az Arduino GND lábát és a vezérlő GND-jét a motort meghajtó tápegység GND-jével.

  • Az USB-n keresztül soros portot nyitunk, így utasításokat tudunk adni az Arduinonak.
Parancs Leírás
/SPEED 1500 Beállítja a motor maximális sebességét
/ACCEL 1500 Beállítja a motor indításakori gyorsulást (másnéven: lágyindítás)
/MOVE 10000 A megadott pozícióra áll a motor.
Mivel áttételt használunk nagy számokkal dolgozunk.
/STATUS Lekérdezi az aktuális pozíciót
/RESET Teljesen újraindítja az Arduino-t

További blogposztok