Pit Braccio

PitBraccio è un esempio di braccio meccanico comandato tramite Arduino via Blueetooth.

Il braccio meccanico come si vede è un po ballerino e il terzo servomotore non si riesce a montare in quanto i servi sono troppo deboli.

Poco male lo scopo è quello interfacciare Arduino e uno Smartphone Android e usare quest'ultimo come telecomando di controllo.

 

Cosa serve:

  • Arduino
  • Scheda Pit HC-05 con Modulo HC-05
  • Led
  • Servomotori
  • Cavetti
  • Smartophone Android
  • Processing
  • PC

 

Preparativi:

  • Installare Processing completo del Mode Android (vedasi l'interessantissima e completa guida "Sviluppare app con Processing" a cura dell’ing. MIRCO SEGATELLO - su Elettronica IN fine 2015 - Inizio 2016)

Software lato Processing:

  • PitBraccio è stato elaborato modificando l'esempio BluetoothCursors - Ketai Library for Android: http://KetaiProject.org di Daniel Sauter
  • Sono state implementate delle routine per disegnare il braccio meccanico che a sua volta parte dal disegno di un'asta (UI_Braccio)
  • Sono state implementate delle routine per il controllo di arduino - si è in particolare creata una piccola libreria (UI_PitButtonSliderLib) che contiene tre oggetti Pulsante (Button), interruttore (Switch) e cursore (Slider) per il controllo dei servi

Software lato Arduino:

  • PitBraccio sul lato Arduino è un programma molto semplice la cosa da vedere è la modalità di lettura dalla Seriale e la traduzione del portocollo (PitPtoto) con cui vengono passati i comandi
  • Il protocollo utilizzato rappresenta il comandi ad Arduino attraverso stringhe nella forma 1 3 4 (0 000 0000);
    1. il primo carattere di controllo (CTR) identifica che si stà passando un comando (nel nostro caso la lettera "Z" - si puo scegliere evidentemente qualsiasi carattere che normalmente non viene utilizzato nella comunicazione);
    2. i tre carattri successivi costituiscono l'ID del componenti (nel nostro caso L01, L02, L03 per i led, S01, S02, S03 per i servomotori)
    3. i quattro caratteri successivi costituicono il dato/parametro (nel nostro caso 0000 o 0001 per identificare lo stato dei led - acceso/spento, 0000 - 0180 - l'angolo cui posizionare i rispettivi servomotori);
  • Attenzione ogni volta che viene identificato il codice di controlllo (CTR) Arduino legge sempre 7 caratteri dalla seriale e quindi come si vede ad esempio per i led per passare lo stato 0/1 si usa una stringa di 4 caratteri 0000/0001. Volendo questa parte puo essere resa più funzionale ma per il nostro scopo funziona egregiamente anche così.
 

Circuito ed elettronica:

  • Come accennato in precedenza i servi a disposizione sono troppo deboli per far funzionare il braccio, sono però sufficienti a caprire il funzionamento del sistema.
  • Uno dei problemi riscontrati è legato anche all'alimentazione dei servi stessi. Nello schema sono alimentati da Arduino. Così facendo la comunicazione non risulta stabile in quanto la corrente assorbita dai servi abbassa quella che arrival ad HC-05 e questo si disconnette.
  • Per ovviare è sufficiente alimentare i servi con una batteria esterna mettendo in comune il polo negativo di Arduino e della batteria (GND -) e alimentando i servi direttamente dalla polopositivo della batteria (+) il comando ai servi arriva poi sempre da Arduino.

ozio_gallery_jgallery

Download:

 

Codice Sorgente Arduino:

/**
Pit Braccio 03
ZappocoS ZappocoJ 3-4/2016
www.zappoco.altervista.org
- Scheda HC-04 con PitBt HC05
- codice PIN per accoppiamento BT 1234
- tre servomotori (libreria Servo.h)
- led cavetti ecc
-
*/
// 
// codice PIN per accoppiamento BT 1234
//
// vengono usate due porte seriali
// -- la prima su porta USB
// -- la seconda su porta BT accoppiata con arduino tramite i pin 10 e 11
// si puo usare anche la seriale di arduino
//  ARDUINO   !  HC-05 !  CAVO
// 1 (10) TX  !   RX   !  giallo (con resistenze 1 KOhm)
// 0 (11) RX  !   TX   !  blu
//
// --------------------------------
// Protocollo comando (PitProto)
//
//          D
//  C       A
//  T  I    T
//  R  D    O
//   
//  0 000 0000
// --------------------------------
char   CT_PitProto = 'Z';
String ID_PitProto;
String DT_PitProto;
#define TXPIN 1  // - Cavo giallo collegato al RX del HC-05 BT con resistenze
                 //   NB nella schedina è il TX sul lato Arduino
#define RXPIN 0  // - Cavo blu    collegato al TX del HC-05 BT
                 //   NB nella schedina è il RX sul lato Arduino
char val; 
#include <Servo.h>
Servo servo1;
Servo servo2;
Servo servo3;
//SoftwareSerial BlueTooth(RXPIN, TXPIN);
//
String StrDummy = "12345";
String CodCM;
int IntCM;
/*
   String reportString = "SensorReading: 456";
   int colonPosition = reportString.indexOf(':');
   reportString.setCharAt(colonPosition, '='); 
 */
void setup()
{
    servo1.attach(9);
    servo2.attach(10);
    servo3.attach(11);
    //pinMode(RXPIN, INPUT);
    //pinMode(TXPIN, OUTPUT);
    pinMode(3, OUTPUT); // imposta il pin 3 come uscita
    pinMode(4, OUTPUT); // imposta il pin 4 come uscita
    pinMode(5, OUTPUT); // imposta il pin 5 come uscita
    Serial.begin(9600);
    Serial.println ("PitBraccio rev.0.22 - PitProto 0.03");
    Serial.println ("-----------------------------------");
    Serial.println ("");
    Serial.println ("");
    //BlueTooth.begin(9600);
    servo1.write(100);
    servo2.write(120);
    servo3.write(120);
}
void loop()
{
  // lettura della seriale secondo il protocollo PitProto
  // se viene inviato un carattere 'Z' --> Start
  // viene letta la stringa successiva
  // secondo il protocollo 1 3 4
  ReadPitProtoCMD();
  // vengono lettisolo caratteri alfanumerici
  if(isAlphaNumeric(val))
  {
    if (val == CT_PitProto)
    {   
      //Serial.println ( "--------- Comando servomotori ---------");
      //Serial.println ( "ID_PitProto :  " + ID_PitProto );
      //Serial.println ( "DT_PitProto :  " + DT_PitProto );
      IntCM = DT_PitProto.toInt();
      if (ID_PitProto == "S01")
      {   
          servo1.write(IntCM);
          Serial.print ( "Servo1: " );
          Serial.println ( IntCM );
      }
      if (ID_PitProto == "S02")
      {
          servo2.write(IntCM);
          Serial.print ( "Servo2: " );
          Serial.println ( IntCM );
      }
      if (ID_PitProto == "S03")
      {
          servo3.write(IntCM);
          Serial.print ( "Servo3: " );
          Serial.println ( IntCM );
      }
      if (ID_PitProto == "L01")
      {
          if( IntCM == 1)
            {
               digitalWrite(3, HIGH); // se il valore è 2 il LED sul pin 3 si spegne
               //Serial.write("Set pin 3 to LOW  --> Led 1 is off\n \r");      
            }
          if( IntCM == 0)
            {
               digitalWrite(3, LOW); // se il valore è 1 il LED sul pin 3 si accende
               //Serial.write("Set pin 3 to HIGH --> Led 1 is on\n \r");      
            }
      }
      if (ID_PitProto == "L02")
      {
          if( IntCM == 1)
            {
               digitalWrite(4, HIGH); // se il valore è 3 il LED sul pin 5 si accende
               //Serial.write("Set pin 4 to HIGH --> Led 2 is on\n \r");      
            }
          if( IntCM == 0)
            {
               digitalWrite(4, LOW); // se il valore è 4 il LED sul pin 5 si spegne
               //Serial.write("Set pin 4 to LOW  --> Led 2 is off\n \r");      
            }
      }
      if (ID_PitProto == "L03")
      {
          if( IntCM == 1)
            {
               digitalWrite(5, HIGH); // se il valore è 5 il LED sul pin 6 si accende
               //Serial.write("Set pin 5 to HIGH --> Led 3 is on\n \r");      
            }
          if( IntCM == 0)
            {
               digitalWrite(5, LOW); // se il valore è 6 il LED sul pin 6 si spegne
               //Serial.write("Set pin 5 to LOW  --> Led 3 is off\n \r");      
            }
      }
    } else
    {
      if( val == '1' )
      {
           digitalWrite(3, HIGH); // se il valore è 1 il LED sul pin 3 si accende
           Serial.write("Set pin 3 to HIGH --> Led 1 is on\n \r");      
      }
      if( val == '2' )
      {
           digitalWrite(3, LOW); // se il valore è 2 il LED sul pin 3 si spegne
           Serial.write("Set pin 3 to LOW  --> Led 1 is off\n \r");      
      }
      if( val == '3' )
      {
           digitalWrite(4, HIGH); // se il valore è 3 il LED sul pin 5 si accende
           Serial.write("Set pin 4 to HIGH --> Led 2 is on\n \r");      
      }
      if( val == '4' )
      {
           digitalWrite(4, LOW); // se il valore è 4 il LED sul pin 5 si spegne
           Serial.write("Set pin 4 to LOW  --> Led 2 is off\n \r");      
      }
      if( val == '5' )
      {
           digitalWrite(5, HIGH); // se il valore è 5 il LED sul pin 6 si accende
           Serial.write("Set pin 5 to HIGH --> Led 3 is on\n \r");      
      }
      if( val == '6' )
      {
           digitalWrite(5, LOW); // se il valore è 6 il LED sul pin 6 si spegne
           Serial.write("Set pin 5 to LOW  --> Led 3 is off\n \r");      
      }
    }
    val = '\0';
  }
}
void ReadPitProtoCMD ()
{
  if(Serial.available() > 0)
  {
    char CDummy;
    CDummy = Serial.read();
    val = CDummy;
    Serial.print (CDummy);
    if (CDummy == CT_PitProto)
    {   
      ID_PitProto = "";
      int i = 0;
      //delay (10);
      while (i <= 2)
      {
        if(Serial.available() > 0)
        {
          CDummy = Serial.read();
          //if(Serial.available() > 0)
          //{
          ID_PitProto += CDummy;
          i++;
          //}
        }
      } 
      DT_PitProto = "";
      i = 0;
      delay (10);
      while (i <= 3)
      {
        if(Serial.available() > 0)
        {
          CDummy = Serial.read();
          //if (isAlphaNumeric(CDummy))
          //{
          DT_PitProto += CDummy;
          i++;
          //}
        }
      } 
      Serial.println ( "ID_PitProto :  " + ID_PitProto );
      Serial.println ( "DT_PitProto :  " + DT_PitProto );
    } 
  }
}
void DeCodeBT (String S)
{
    String Cod000;
    Cod000 = S.substring(2,5);
    CodCM  = S.substring(0,2);
    IntCM = Cod000.toInt();
}

Codice Sorgente Processing:

/**
Pit Braccio 03
 ZappocoS ZappocoJ 3-4/2016
 www.zappoco.altervista.org
 Svilluppato partendo da BluetoothCursors esempio della libreria Ketai 
 * <p>Ketai Library for Android: http://KetaiProject.org</p>
 * <p>Updated: 2012-05-18 Daniel Sauter/j.duran</p>
 */
//required for BT enabling on startup
import android.content.Intent;
import android.os.Bundle;
import ketai.net.bluetooth.*;
import ketai.ui.*;
import ketai.net.*;
import oscP5.*;
//font
PFont Font1;
// stato dei led
boolean Led1 = false;
boolean oldLed1 = false;
boolean Led2 = false;
boolean oldLed2 = false;
boolean Led3 = false;
boolean oldLed3 = false;
boolean newKeyFlag = true;
//String who = "HC-05";
String received = "Received: ";
// ketay Bluetooth
KetaiBluetooth bt;
String info = "";
KetaiList klist;
PVector remoteMouse = new PVector();
ArrayList<String> devicesDiscovered = new ArrayList();
boolean isConfiguring = true;
String UIText;
// dati per Braccio meccanico
// Coordinate pulsanti
//int ctrZoneX = 700;
int ctrZoneY = 500;
//int ctrZoneY = 1300;
int drwZoneY = 1800;
//int drwZoneY = 1100;
//asta 1
float xAsta1 = 200;
float yAsta1 = drwZoneY;
float aAsta1 = 100;
float lAsta1 = 120;
float tAsta1 = 80;
//asta 2
float xAsta2;
float yAsta2;
float aAsta2 = 120;
float lAsta2 = 340;
float tAsta2 = 60;
//asta 3
float xAsta3;
float yAsta3;
float aAsta3 = 120;
float lAsta3 = 260;
float tAsta3 = 50;
//asta 4
float xAsta4;
float yAsta4;
float aAsta4 = 120;
float lAsta4 = 220;
float tAsta4 = 50;
float Angle1Min = 90 ;
float Angle1Max = 150 ;
public float Angle1 = 120 ;
float Angle2Min = 60 ;
float Angle2Max = 150 ;
public float Angle2 = 100 ;
float Angle3Min = 60 ;
float Angle3Max = 150 ;
public float Angle3 = 100 ;
float AngleIncMin = 1;
float AngleIncMax = 5;
String Servo1 = "Servo1";
String Servo2 = "Servo2";
String Servo3 = "Servo3";
Switch L1 = new Switch (100, ctrZoneY + 000, 220, 120, false, 255, 255,   0, 120 ,  120, 120);
Switch L2 = new Switch (400, ctrZoneY + 000, 220, 120, false,   0, 204,   0, 120 ,  120, 120);
Switch L3 = new Switch (700, ctrZoneY + 000, 220, 120, false, 102, 178, 255, 120 ,  120, 120);
Slider S1 = new Slider (100, ctrZoneY + 200, 220, 550, Angle1Min, Angle1Max, Angle1, AngleIncMax, 255, 255,   0, 120 ,  120, 120);
Slider S2 = new Slider (400, ctrZoneY + 200, 220, 550, Angle2Min, Angle2Max, Angle2, AngleIncMax,   0, 204,   0, 120 ,  120, 120);
Slider S3 = new Slider (700, ctrZoneY + 200, 220, 550, Angle3Min, Angle3Max, Angle3, AngleIncMax, 102, 178, 255, 120 ,  120, 120);
//********************************************************************
// The following code is required to enable bluetooth at startup.
//********************************************************************
void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  bt = new KetaiBluetooth(this);
}
void onActivityResult(int requestCode, int resultCode, Intent data) {
  bt.onActivityResult(requestCode, resultCode, data);
}
//********************************************************************
void setup()
{   
  orientation(PORTRAIT);
  background(78, 93, 75);
  stroke(255);
  textSize(24);
  Font1 = createFont("Comic Sans MS", 24);
  // setta font per le scritte 
  textFont(Font1);
  //start listening for BT connections
  bt.start();
  UIText =  "d - discover devices\n" +
    "b - make this device discoverable\n" +
    "c - connect to device\n     from discovered list.\n" +
    "p - list paired devices\n" +
    "i - Bluetooth info";
   aAsta2 = Angle1;
   aAsta3 = Angle2;
   aAsta4 = Angle3;
}
void draw()
{
  if (isConfiguring)
  {
    ArrayList<String> names;
    background(78, 93, 75);
    //based on last key pressed lets display
    //  appropriately
    if (key == 'i')
    {
        info = getBluetoothInformation();
        println ("Info  --> :" + info);
    }
    else
    {
      if (key == 'p')
      {
        info = "Paired Devices:\n";
        names = bt.getPairedDeviceNames();
      }
      else
      {
        info = "Discovered Devices:\n";
        names = bt.getDiscoveredDeviceNames();
      }
      for (int i=0; i < names.size(); i++)
      {
        info += "["+i+"] "+names.get(i).toString() + "\n";
      }
    }
    text(UIText + "\n\n" + info, 5, 140);
    Led1 = L1.flagOn;
    Led2 = L2.flagOn;
    Led3 = L3.flagOn;
    Angle1 = S1.Val;
    Angle2 = S2.Val;
    Angle3 = S3.Val;
    if (aAsta2 != Angle1){
        // per segno usare nfp
        String send = "ZS01" + nf(int(aAsta2), 4);
        println("Angle1:" + aAsta2 + " " + Angle1 + " " + send);  
        Servo1 = send;
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        aAsta2 = Angle1;
    }
    if (aAsta3 != Angle2){
        String send = "ZS02" + nf(int(180-aAsta3), 4);
        println("Angle2:" + aAsta3 + " " + Angle2 + " " + send);  
        Servo2 = send;
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        aAsta3 = Angle2;
    }
    if (aAsta4 != Angle3){
        String send = "ZS03" + nf(int(aAsta4), 4);
        println("Angle3:" + aAsta4 + " " + Angle3 + " " + send);  
        Servo3 = send;
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        aAsta4 = Angle3;
    }
    if (Led1 != oldLed1 && Led1 == true){
        String send = "ZL010001";
        println("Led1:" + Led1 + oldLed1 + " " + send);
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        S1.dVal = AngleIncMin;      
        //OscMessage m = new OscMessage('1');
        //bt.broadcast(m.getBytes());  
        oldLed1 = Led1;
    }
    if (Led1 != oldLed1 && Led1 == false){
        String send = "ZL010000";
        println("Led1:" + Led1 + oldLed1 + " " + send);
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        S1.dVal = AngleIncMax;
        oldLed1 = Led1;
    }
    Led2 = L2.flagOn;
    if (Led2 != oldLed2 && Led2 == true){
        String send = "ZL020001";
        println("Led2:" + Led2 + oldLed2 + " " + send);
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        S2.dVal = AngleIncMin;      
        oldLed2 = Led2;
    }
    if (Led2 != oldLed2 && Led2 == false){
        String send = "ZL020000";
        println("Led2:" + Led2 + oldLed2 + " " + send);
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        S2.dVal = AngleIncMax;      
        oldLed2 = Led2;
    }
    Led3 = L3.flagOn;
    if (Led3 != oldLed3 && Led3 == true){
        String send = "ZL030001";
        println("Led3:" + Led3 + oldLed3 + " " + send);
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        S3.dVal = AngleIncMin;      
        oldLed3 = Led3;
    }
    if (Led3 != oldLed3 && Led3 == false){
        String send = "ZL030000";
        println("Led3:" + Led3 + oldLed3 + " " + send);
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        S3.dVal = AngleIncMax;      
        oldLed3 = Led3;
    }
  }
  else
  {
    background(78, 93, 75);
    pushStyle();
    fill(255);
    ellipse(mouseX, mouseY, 20, 20);
    fill(0, 255, 0);
    stroke(0, 255, 0);
    ellipse(remoteMouse.x, remoteMouse.y, 20, 20);    
    popStyle();
  }
  drawUI();
  drawBraccio ();
  L1.update();
  L2.update();
  L3.update();
  if (mousePressed == true)
  {
    S1.mouseIn();
    S2.mouseIn();
    S3.mouseIn();
  }
  S1.update();
  S2.update();
  S3.update();
  textSize(50);
  //scrive i valori che vengono passati
  fill(S1.colorR, S1.colorG, S1.colorB);
  text(Servo1 , 100, drwZoneY + 100);
  fill(S2.colorR, S2.colorG, S2.colorB);
  text(Servo2 , 400, drwZoneY + 100);
  fill(S3.colorR, S3.colorG, S3.colorB);
  text(Servo3 , 700, drwZoneY + 100);
  fill(255);
  //rotate (PI/2);
  text("PitBraccio v0.28" , 710, 150);
  textSize(28);
  text("www.zappoco.altervista.org" , 710, 185);
  textSize(24);
  //rotate (-PI/2);
}
//Call back method to manage data received
void onBluetoothDataEvent(String who, byte[] data)
{
  if (isConfiguring)
  {
    received += new String (data);
    if (received.length() > 175)
      received = ("Message to long!");
    println (received);
    return;
  }
  //KetaiOSCMessage is the same as OscMessage
  //   but allows construction by byte array
  KetaiOSCMessage m = new KetaiOSCMessage(data);
  if (m.isValid())
  {
    //println ( "m" + m);
    if (m.checkAddrPattern("/remoteMouse/"))
    {
      if (m.checkTypetag("ii"))
      {
        remoteMouse.x = m.get(0).intValue();
        remoteMouse.y = m.get(1).intValue();
      }
    }
  }
}
String getBluetoothInformation()
{
  String btInfo = "Server Running: ";
  btInfo += bt.isStarted() + "\n";
  btInfo += "Discovering: " + bt.isDiscovering() + "\n";
  btInfo += "Device Discoverable: "+bt.isDiscoverable() + "\n";
  btInfo += "\nConnected Devices: \n";
  ArrayList<String> devices = bt.getConnectedDeviceNames();
  for (String device: devices)
  {
    btInfo+= device+"\n";
  }
  return btInfo;
}

 

Codice Sorgente Processing Routine UI:

/*  UI-related functions */
void mousePressed()
{
  //keyboard button -- toggle virtual keyboard
  if (mouseY <= 100 && mouseX > 0 && mouseX < width/3)
    // attiva la tastiera
    KetaiKeyboard.toggle(this);
  else if (mouseY <= 100 && mouseX > width/3 && mouseX < 2*(width/3)) //config button
  {
    isConfiguring=true;
  }
  else if (mouseY <= 100 && mouseX >  2*(width/3) && mouseX < width) // draw button
  {
    if (isConfiguring)
    {
      //if we're entering draw mode then clear canvas
      background(78, 93, 75);
      isConfiguring=false;
    }
  }
  L1.mouseIn();
  L2.mouseIn();
  L3.mouseIn(); 
}
void mouseDragged()
{
  if (isConfiguring)
    return;
  //send data to everyone
  //  we could send to a specific device through
  //   the writeToDevice(String _devName, byte[] data)
  //  method.
  OscMessage m = new OscMessage("/remoteMouse/");
  m.add(mouseX);
  m.add(mouseY);
  bt.broadcast(m.getBytes());
  ellipse(mouseX, mouseY, 20, 20);
}
public void keyPressed() {
  if (key =='c')
  {
    //If we have not discovered any devices, try prior paired devices
    if (bt.getDiscoveredDeviceNames().size() > 0)
      klist = new KetaiList(this, bt.getDiscoveredDeviceNames());
    else if (bt.getPairedDeviceNames().size() > 0)
      klist = new KetaiList(this, bt.getPairedDeviceNames());
  }
  else if (key == 'd')
  {
    bt.discoverDevices();
  }
  else if (key == 'x')
    bt.stop();
  else if (key == 'b')
  {
    bt.makeDiscoverable();
  }
  else if (key == 's')
  {
    bt.start();
  }
  /*else 
  {
      if (key == ' ')
      {
        newKeyFlag = false;
      }
      else
      {
        newKeyFlag = true;
      }
      println ("newKeyFlag: " + newKeyFlag);
  }
  */
}
void drawUI()
{
  //Draw top shelf UI buttons
  pushStyle();
  fill(0);
  stroke(255);
  rect(0, 0, width/3, 100);
  if (isConfiguring)
  {
    noStroke();
    fill(78, 93, 75);
  }
  else
    fill(0);
  rect(width/3, 0, width/3, 100);
  if (!isConfiguring)
  {  
    noStroke();
    fill(78, 93, 75);
  }
  else
  {
    fill(0);
    stroke(255);
  }
  rect((width/3)*2, 0, width/3, 100);
  fill(255);
  text("Keyboard", 5, 40); 
  text("Bluetooth", width/3+5, 40); 
  text("Interact", width/3*2+5, 40); 
  popStyle();
}
void onKetaiListSelection(KetaiList klist)
{
  String selection = klist.getSelection();
  bt.connectToDeviceByName(selection);
  //dispose of list for now
  klist = null;
}

 

Codice Sorgente Processing Routine UI_Braccio:

 

/* 
  Routine per disegnare un'asta e poi il braccio meccanico
  ZappocoS - ZappocoJ - 24 marzo 2016
  www.zappoco.altervista.org
*/
/*
   Disegna una asta
   x y coordinate del punto di partenza
   a   angolo dell'asta rispetto all'orrizzontale 
   l   lunghezza dell'asta
   t   spessore  dell'asta
*/
void drawAsta (float x, float y, float a, float l, float t, int cR, int cG, int cB){
  //int cR, cG, cB;
  //
  // variabili locali
  //
  float aRad, c, s;
  float X1, Y1;
  float X2, Y2;
  float X3, Y3;
  float X4, Y4;
  float dx, dy;
  float r = 0;
  r = t/2;
  aRad = -a * PI / 180 ;
  c = cos(aRad);
  s = sin(aRad);
  dx = r * s;
  dy = r * c;
  // coordinate punto 1
  X1 = x - dx;
  Y1 = y + dy;
  // coordinate punto 3
  X3 = X1 + l * c;
  Y3 = Y1 + l * s;
  // coordinate punto 2
  X2 = x + dx;
  Y2 = y - dy;
  // coordinate punto 4
  X4 = X2 + l * c;
  Y4 = Y2 + l * s;
  line(X1, Y1, X3, Y3);
  line(X2, Y2, X4, Y4);
  noFill();
  arc (x , y, t, t, aRad - PI/2 + PI, aRad + PI/2 + PI);
  //ellipse  (x, y, t, t);
  fill(cR,cG,cB);
  ellipse  (x, y, 1.3 * r, 1.3 * r);
  noFill();
  arc (x + l * c, y + l * s, t, t, aRad - PI/2, aRad + PI/2);
  fill(255);
}
/*
   Routine che disegna il braccio meccanico
*/
void drawBraccio (){
  //Braccio meccanico  Asta 1
  drawAsta (xAsta1, yAsta1, aAsta1, lAsta1, tAsta1, 100,100, 100);
  //Braccio meccanico Asta 2
  xAsta2 = xAsta1 + lAsta1  * cos(-aAsta1 * PI / 180 );
  yAsta2 = yAsta1 + lAsta1  * sin(-aAsta1 * PI / 180 );
  aAsta2 =  Angle1;
  float aDummy;
  aDummy = (aAsta2 - 180 + aAsta1);
  drawAsta (xAsta2, yAsta2, aDummy, lAsta2, tAsta2, S1.colorR,S1.colorG, S1.colorB);
  //Braccio meccanico Asta 3
  xAsta3 = xAsta2 + lAsta2  * cos(-aDummy * PI / 180 );
  yAsta3 = yAsta2 + lAsta2  * sin(-aDummy * PI / 180 );
  aAsta3 =  Angle2;
  aDummy = (aAsta3 - 180 + aDummy);
  drawAsta (xAsta3, yAsta3, aDummy, lAsta3, tAsta3, S2.colorR,S2.colorG, S2.colorB);
  //Braccio meccanico Asta 4
  xAsta4 = xAsta3 + lAsta3  * cos(-aDummy * PI / 180 );
  yAsta4 = yAsta3 + lAsta3  * sin(-aDummy * PI / 180 );
  aAsta4 =  Angle3;
  aDummy = (aAsta4 - 180 + aDummy);
  drawAsta (xAsta4, yAsta4, aDummy, lAsta4, tAsta4, S3.colorR,S3.colorG, S3.colorB);
}

 

Codice Sorgente Processing Routine UI_PitButtonSliderLib:

/**
 * ZappocoS libreria slider e button 
 * 
 * 31/01/2014 
 */
class Button { 
  float x0, y0;
  float dx, dy;
  int dTime;
  int bColorR, bColorG, bColorB;
  int colorR, colorG, colorB;
  boolean flagOn;
  long time0;
  Button (float x, float y, float a , float b, int dT, int cR, int cG, int cB,int bR, int bG, int bB) {
    x0 = x;
    y0 = y; 
    dx = a;
    dy = b; 
    dTime = dT;
    //flagOn = fOn;
    colorR = cR;
    colorG = cG;
    colorB = cB;
    bColorR = bR;
    bColorG = bG;
    bColorB = bB;
  } 
  void update() {
    if (millis() - time0 - dTime >= 0)
      { 
        fill(colorR,colorG,colorB);
      }
      else
      {
        fill(bColorR,bColorG,bColorB);
      }
      rect(x0, y0, dx, dy);
  }
  void mouseIn () {
      if (mouseX > x0 && mouseX < x0 + dx && 
          mouseY > y0 && mouseY < y0 + dy)
          {
            time0 = millis();
            //println ("In On :" );
            //update ();
            //fill(bColorR,bColorG,bColorB);
            //rect(x0, y0, dx, dy);
            //delay (dTime);
            //println ("In Off :" );
          }
      else
        {
        }
  } 
} 
class Switch { 
  float x0, y0;
  float dx, dy;
  int bColorR, bColorG, bColorB;
  int colorR, colorG, colorB;
  boolean flagOn;
  Switch (float x, float y, float a , float b, boolean fOn, int cR, int cG, int cB,int bR, int bG, int bB) {
    x0 = x;
    y0 = y; 
    dx = a;
    dy = b; 
    flagOn = fOn;
    colorR = cR;
    colorG = cG;
    colorB = cB;
    bColorR = bR;
    bColorG = bG;
    bColorB = bB;
  } 
  void update() {
    if (flagOn == true)
    { 
      fill(colorR,colorG,colorB);
    }
    else
    {
      fill(bColorR,bColorG,bColorB);
    }
    rect(x0, y0, dx, dy);
  }
  void mouseIn () {
      if (mouseX > x0 && mouseX < x0 + dx && 
          mouseY > y0 && mouseY < y0 + dy)
          {
            //println ("IN flagOn :" + flagOn);
            flagOn = !flagOn;
            //println ("IN flagOn :" + flagOn);
          }
      else
        {
            //println ("Out flagOn :" + flagOn);
        }
  } 
}
class Slider { 
  float x0, y0;
  float dx, dy;
  float x1, y1, x2, y2;
  float dx1, dy1, dx2, dy2;
  int bColorR, bColorG, bColorB;
  int colorR, colorG, colorB;
  float minimoVal, massimVal, Val, dVal;
  Slider (float x, float y, float a , float b, float minV, float maxV, float V, float dV, int cR, int cG, int cB,int bR, int bG, int bB) {
    x0 = x;
    y0 = y; 
    dx = a;
    dy = b; 
    minimoVal = minV;
    massimVal = maxV;
    if (dV == 0)
      {
        dVal = (massimVal - minimoVal)/10;
      }
    else
      {
        dVal = dV;
      }
    Val = V;
    limit ();
    bColorR = bR;
    bColorG = bG;
    bColorB = bB;
    colorR = cR;
    colorG = cG;
    colorB = cB;
  } 
  void limit () {
      if (Val <= minimoVal)
        {
          Val = minimoVal;
        }
    if (Val >= massimVal)
        {
          Val = massimVal; 
        }
  }
  void update() {
     if (dx >= dy)
       {
         x1 = x0;
         dx1 = dx * (Val - minimoVal) / (massimVal - minimoVal);
         x2 = x1 + dx1;
         dx2 = dx - dx1;
         y1 = y0;
         y2 = y0;
         dy1 = dy;  
         dy2 = dy;
       }
     else
       {
         y2  = y0;
         dy2 = dy - dy * (Val - minimoVal) / (massimVal - minimoVal);
         y1  = y0 + dy2;
         dy1 = dy - dy2;
         x1 = x0;
         x2 = x0;
         dx1 = dx;  
         dx2 = dx;
       }
      stroke(255, 255,255);     
      fill(colorR,colorG,colorB);     
      rect(x1, y1, dx1, dy1);
      fill(bColorR,bColorG,bColorB);
      rect(x2, y2, dx2, dy2);
  }
  void mouseIn () {
      int mX, mY;
      mX = mouseX;
      mY = mouseY;
      println ("( millis ):  " + mX + " " + mY +" " + millis());
      if (dx >= dy)
         {
           dx1 = 0.45 * dx;
           dx2 = 0.45 * dx;
           x1 = x0;
           x2 = x0 + dx - dx2;
           y1 = y0;
           y2 = y0;
           dy2 = dy;  
           dy1 = dy;
         }
      else
         {
           dy1 = 0.45 * dy;           
           dy2 = 0.45 * dy;
           y1 = y0 + dy  - dy1;
           y2 = y0;
           x1 = x0;
           x2 = x0;
           dx2 = dx;  
           dx1 = dx;
         }
      if (mX > x2 && mX < x2 + dx2 && 
          mY > y2 && mY < y2 + dy2)
          {
            Val = Val + dVal;
            limit ();
            //print ("( + ):  " + minimoVal + " " + Val + " " + massimVal);
          }
      else if (mX > x1 && mX < x1 + dx1 && 
          mY > y1 && mY < y1 + dy1)
          {
            Val = Val - dVal;
            limit ();
            //print ("( - ): " + minimoVal + " " + Val + " " + massimVal);
          }
      else
        {
            //println ("none");
        }
  } 
} 

 

ZappocoS - 16 aprile 2016