LoM project - Simple Robot Arm Controller

Da raspibo.
Jump to navigation Jump to search

Simple Robot Arm Controller

Il programma in esempio permette di controllare un braccio robotico utilizzando tre potenziometri, uno per ogni giuntura del braccio escluso il polso, e un button switch per l'apertura e chiusura della pinza. Il programma non ha nulla di particolarmente complesso ma è un ottimo esempio per iniziare a capire il funzionamento del braccio e come programmarlo. L'unico accorgimento particolare è stato l'utilizzo di una funzione per fare una media degli angoli tra 2 iterazioni successive, questo stabilizza i dati e permette al braccio di essere più preciso nei movimenti.

Compineti

In questo esempio sono stati utilizzati i seguenti componenti:

Image: 600 pixels

  • Braccio,
  • Shield di controllo,
  • Arduino/Fishino,
  • 1 Alimentatore da 12V 1A,
  • 3 Potenziometri da 10Kohm,
  • 1 Breadbord,
  • 1 Push button switch,
  • Qualche jumper e connettori.

Schema

Di seguito in figura è illustrato lo schema completo.

Image: 800 pixels

Software

Di seguito si riporta il codice con il codice implementato.

/*
MIT License

Copyright (c) 2019 Filippo Soncini, Davide Allevi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

*/

#include <Servo.h>

// Crea oggetti servo, uno per ogni servo del braccio.
Servo base;
Servo shoulder;
Servo elbow;
Servo gripper;

// Assegno i pin dell'arduino
int pin = A0;
int pinS = A1;
int pinE = A2;

const int buttonPin = A5; 

// Inizializzo le variabili angolo di ogni servo.
int firstangleB = 0;
int firstangleS = 0;
int firstangleE = 0;

// Funzione di inizializzazione dei servo.
void initservo(){
  base.attach(11);      // collega il servo sul pin 11 all'oggetto base,
  shoulder.attach(10);  // collega il servo sul pin 10 all'oggetto shoulder,
  elbow.attach(9);      // collega il servo sul pin 9 all'oggetto elbow,
  gripper.attach(3);    // collega il servo sul pin 3 all'oggetto gripper.

  // imposto l'angoli iniziali per ogni servo.
  base.write(90);       
  shoulder.write(90);
  elbow.write(110);
  gripper.write(100);
}

// Funzione che ottiene il valorede del potenziometro scalato.
/* Parametri:
 *  int: pin          Pin dell'arduino
 *  
 *  Return:
 *  int: first        Angolo iniziale del servo collegato al pin
 */
int initangle(int pin){
  int angle = analogRead (pin);                // Legge il valore del potenziometro (valore compreso tra 0 e 1023)
  int first = map(angle, 0, 1023, 0, 180);     // Ridimensiono il valore per poterlo utilizzare sul servo (valore tra 0 e 180)
  return first;
}


// Funzione che calcola la media del valore del potenziometro della precedente iterazione con il valore attuale del potenziometro.
/* Parametri:
 *  int: pin              Pin dell'arduino.
 *  int: firstangle       Valore del potenziometro dell'iterazione precedente.
 *  
 *  Return:
 *  int: firstangle       Ritorna la media arrotondata.
 */
int anglewrite(int pin, int firstangle){
  int angle = analogRead (pin);                 // Legge il valore del potenziometro (valore compreso tra 0 e 1023)
  int mapping = map(angle, 0, 1023, 0, 180);    // Ridimensiono il valore per poterlo utilizzare sul servo (valore tra 0 e 180)
  firstangle = (mapping + firstangle) / 2;      // Calcomo la media
  return firstangle;
}

void setup() {
   
  pinMode(buttonPin, OUTPUT);       // inizializza il pin del pulsante come input
  digitalWrite(buttonPin, HIGH);   // inizializza il valore del pulsante

  // Chiamo la funzione per inizializzare.
  initservo();
  firstangleB = initangle(pin);
  firstangleS = initangle(pinS);
  firstangleE  = initangle(pinE);
}

void loop() {

  // Calcolo e aggiorno la media dei valori dei potenziometri,
  // e imposta la posizione del servo in base al valore,
  // Questo per ogni servo.  
  firstangleB = anglewrite(pin, firstangleB);
  base.write(firstangleB);
  firstangleS = anglewrite(pinS, firstangleS);
  shoulder.write(firstangleS);
  firstangleE = anglewrite(pinE, firstangleE);
  elbow.write(firstangleE);
 
  // controlla se il pulsante viene premuto.
  if (digitalRead(buttonPin) == LOW) {
    gripper.write(140);                   // Se il pulsante viene premuto la il servo si porta ad un angolo di 140 (Chiusa)
  } else {
    gripper.write(90);                    // Altrimenti porta ad un angolo di 90 (Aperta)
  }  
  
}

Sources

Una relazione più completa con guida utente sull'utilizzo del braccio File:Relazione Laboratorio di making.pdf

Specifiche della scheda di controllo File:SchedaControllo.pdf