Strumenti Utente

Strumenti Sito


riservata:project_work_3a

Project Work 3A

Idee

Robot 2 DOF

E' un progetto ben documentato di jjrobots con software e modelli 3D disponibili da qui.

Mi piace perché:

  • è semplice, sono solo due motori, non ci sono barre filettate
  • è abbastanza facile stampare le parti 3D
  • abbiamo già a scuola i motori e i driver

Pensato come robot a 2 assi per orientare un puntatore laser può montare anche altri payload (webcam, “pistole”, ecc.).

BOM

La BOM è abbastanza ridotta:

descrizione numero disponibile prototipo
pezzi 3D stampati 11 manca solo il supporto payload che va creato su misura modellare supporto lego dart shooter
stepper nema17 2 da L03
driver stepper 2 a4988 da L03?
cavi motore 2 venduti col motore come collegarli al driver?
puleggia GT2 20 denti 2 da kit amazon
cuscinetti 6002RS or 6002ZZ 2 5€ da cesena cuscinetti
fascette 100x5mm 10 nessuna
cinghia 200mm 200 GT2 3 da acquistare da kit amazon
fascetta avvolgi-cavo 1 opzionale nessuna
ventose/piedini (rubber suction pad) 3 da acquistare piedini da L51 o si fa senza
arduino zero 1 usare ESP32? arduino uno
alimentatore 12V 1 da laboratorio
viti M3 6mm 6 ? 8mm e 3-4 6mm da lab51
viti M3 10mm 14 da magazzino Comandini P09
viti M3 15mm 10 da lab51
viti M3 45mm 4 ? 40mm da lab51
dadi M3 6 ? da lab51

Ho preso questo kit da amazon con due pulegge 20 denti (foro 5mm), due 60 denti e due cinghie (larghezza 6mm) lunghezza 200mm GT2. I cuscinetti li ho presi da cesena cuscinetti (i più economici 5€).

Assemblaggio

L'assemblaggio è mostrato passo per passo con delle immagini nel sito del progetto. Per non sbagliare è molto utile scaricare da thingiverse il file .STEP che contiene l'intero assemblaggio. Aprendolo con FreeCAD si possono evidenziare le singole parti e l'insieme. Quando è possibile è sempre meglio usare i file STEP, infatti:

  • FreeCAD è molto più veloce nella loro gestione
  • il file STL tratta il pezzo come un'unica superficie mentre il file STEP mette in evidenza le varie facce e i bordi e permette di modificare facilmente la parte

NB: in entrambi i casi non è possibile risalire alle azioni con cui è stata creato il pezzo.

L'assemblaggio pone questi problemi:

  • viti 6mm: ne ho poche, dove posso uso quelle da 8mm trovate nel lab51
  • il verso in cui montare il pezzo cap non è chiaro dalle foto ma si vede dal file STEP
  • i motori NEMA17 di L03 come misure sono compatibili con quelli indicati nel progetto ma poi non si riesce a fissarli con le viti da 40mm come descritto nelle istruzioni di montaggio
  • upper arm motor holder left: quello stampato non permette di montare il motore (la lunghezza delle viti da 40mm non è sufficiente e innestare il filetto del motore) e non si riesce a fissare upper arm motor right su upper right (i fori sono 2mm prima)
  • seguendo le istruzioni di montaggio se si fissa prima il secondo motore poi non si riesce a montare la cinghia; l'ho fatto e ho spezzato il perno del cuscinetto in un pezzo
  • anche la base non è adatta al nostro NEMA17 e le viti da 40mm non arrivano ad impegnare il filetto; bisognerebbe rifare il pezzo ma ho preferito scavare i fori con una punta da 5mm guadagnando i 2-3mm che mancavano

Rifaccio il pezzo upper arm motor holder left ma lo traslo in basso di 2,7mm tagliando di fatto la parte che finisce sotto il piatto. Di fatto lo accorcio di quasi 3mm sperando che si adattino sia le viti che i fori dell'altro motor holder.

Cablaggio

Il motore è collegato alla breadboard in questo modo:

strip to breadboard

In generale tutto il cablaggio è estremamente fragile e sarebbe opportuno progettare un PCB con driver, morsetti per l'alimentazione, header per i cavi dei motori. Anche un supporto stampato in PLA per alloggiare il tutto non sarebbe male.

Per il collegamento dei due motori stepper seguire questo tutorial (riportato anche nella pagina stepper). In particolare la piedinatura è questa:

Problemi

Altri problemi:

  • la comunicazione seriale va disattivata altrimenti il pilotaggio del motore non funziona correttamente
  • pensavo di alimentare la scheda Arduino a 12V e utilizzare il piedino Vin per portare i 12V al driver ma non si può fare, probabilmente perché il driver disturba gli ingressi analogici e il motore si muove anche senza agire sul joystick (aggiungere condensatori di bypass?)
  • serve un'alimentazione separata per Arduino (e quindi ingressi analogici): il test con alimentazione Arduino da USB e driver con alimentatore separato dà buoni risultati (fa ancora piccoli movimenti anche senza agire sul joystick ma sembra risolvibile magari anche solo via software)

Software

// basato sugli esempi della libreria AccelStepper (multiple steppers e proportional)
// joystick analogico comanda la velocità ma c'è una posizione limite che non viene superata
// il pulsante del joystick abilita/disabilita il driver (LED13 acceso se abilitato)
// il pulsante è gestito con un interrupt sul fronte di discesa
// il rimbalzo del pulsante è gestito trascurando commutazioni che si ripetono prima di 200ms
// i rapporti di riduzione sono: 64:20 per l'altezza , e 80:20 per la rotazione 
// 200 passi/giro diventano 640 passi/giro per altezza e 800 passi/giro per la rotazione
// NB il driver disturba molto l'ingresso analogico -> SERVONO ALIMENTAZIONI SEPARATE
// NB la seriale disturba il pilotaggio del motore -> DISATTIVARE LA SERIALE
 
// libreria per gestire i motori stepper con due driver A4988
#include <AccelStepper.h>
 
// istanza con opzione DRIVER, pin 9 STEP e pin 8 DIR per rotazione
AccelStepper stepper1(AccelStepper::DRIVER, 9, 8);
// istanza con opzione DRIVER, pin 11 STEP e pin 10 DIR per altezza
AccelStepper stepper2(AccelStepper::DRIVER, 11, 10);
 
// piedini
int pinPulsante = 2;
int pinEnable = 7;
 
// segnali analogici: X su A0 e Y su A1
 
// variabili aggiornate dall'interrupt service routine (ISR)
volatile int enable = 1; // di default disabilitato perché attivo basso
volatile unsigned long last_interrupt_time = 0; // ultimo interrupt
volatile unsigned long interrupt_time = 0; // interrupt corrente
 
// input dal joystick
int analogX;       // comanda la rotazione (0 = estremo sinistro)
int analogY;       // comanda l'altezza (0 = estremo superiore)
int offset = 512;  // posizione di riposo del joystick
 
// controllo motori
int velX = 0;    // velocità in passi/s per stepper1
int velY = 0;    // velocità in passi/s per stepper2
int posX = 120;  // posizione limite per stepper1 (+-60° circa)
int posY = 70;  // posizione limite per stepper2 (+-45° circa)
 
void setup() {
  // pullup interno per il pulsante joystick
  pinMode(pinPulsante, INPUT_PULLUP);
  // pin ENABLE del driver
  pinMode(pinEnable, OUTPUT);
  // disabilito driver
  digitalWrite(pinEnable, enable);
  // interrupt quando è premuto il pulsante abilitazione
  attachInterrupt(digitalPinToInterrupt(pinPulsante), toggle, FALLING);
  // impostazioni driver
  stepper1.setMaxSpeed(500);  // 1 giri/s stepper -> 0.3 giri/s laser
  stepper2.setMaxSpeed(500);
  // debug seriale 
  // NB il driver non funziona correttamente se attivata
  // Serial.begin(9600);
}
 
void loop() {
  // lettura posizione jostick
  analogX = analogRead(A0);
  analogY = analogRead(A1);
  // calcolo velocità
  velX = ((analogX - offset) / 10) * 8;  // dividendo si elimina l'ultima cifra che è incerta
  velY = ((analogY - offset) / 10) * 8;  // moltiplicando si ottiene un valore tra 0 e 204 passi/s
  // Serial.print(analogX);
  // Serial.print(" ");
  // Serial.print(analogY);
  // Serial.print(" ");
  // Serial.print(velX);
  // Serial.print(" ");
  // Serial.print(velY);
  // Serial.print(" ");
  // Serial.print(enable);
  // Serial.print(" ");
  // Serial.print(stepper1.speed());
  // Serial.println();
 
  // segnalazione dell'abilitazione col LED 13
  if (enable) {
    digitalWrite(13, LOW);
  } else {
    digitalWrite(13, HIGH);
  }
 
  // movimento stepper1
  if (velX > 0) {
    stepper1.moveTo(posX); // posizione da raggiungere
    stepper1.setSpeed(velX); // velocità con cui raggiungerla
    stepper1.runSpeedToPosition(); // muove il motore fino a destinazione
  } else if (velX < 0) {
    stepper1.moveTo(-posX);
    stepper1.setSpeed(velX);
    stepper1.runSpeedToPosition();
  } else {
    stepper1.moveTo(posX); // probabilmente bastava mettere un blocco di codice vuoto
    stepper1.setSpeed(0);
    stepper1.runSpeedToPosition(); 
  }
 
  // movimento stepper2
  if (velY > 0) {
    stepper2.moveTo(posY);
    stepper2.setSpeed(velY);
    stepper2.runSpeedToPosition();
  } else if (velY < 0) {
    stepper2.moveTo(-posY);
    stepper2.setSpeed(velY);
    stepper2.runSpeedToPosition();
  } else {
    stepper2.moveTo(posY);
    stepper2.setSpeed(0);
    stepper2.runSpeedToPosition();
  }
 
}
 
// ISR pressione pulsante
void toggle() {
  // serve un debounce o commuta a caso per i rimbalzi
  // così commuta solo ogni 200 ms
  interrupt_time = millis();                         // leggo il tempo dell'interrupt
  if (interrupt_time - last_interrupt_time > 200) {  // se sono passati 200ms
    enable = !enable;                                // commuto enable
    digitalWrite(pinEnable, enable);                 // imposto il piedino corrispondente
  }
  last_interrupt_time = interrupt_time;  // aggiorno il tempo dell'ultimo interrupt
}
Questo sito Web utilizza i cookie. Utilizzando il sito Web, l'utente accetta la memorizzazione dei cookie sul proprio computer. Inoltre riconosci di aver letto e compreso la nostra Informativa sulla privacy. Se non sei d'accordo, lascia il sito.Maggiori informazioni sui cookie
riservata/project_work_3a.txt · Ultima modifica: da admin