Pit Momo V1

PitMomo è un robottino controllato da Arduino e comandato da Processing attraverso USB o Bluetooth.

I movimenti sono dati da tre servomotori (le due braccia e la testa) e due led (gli occhi).

In questo primo video si vede il controllo completo tramite Android - che invia i dati a Arduino attraverso Bluetoorh.

Cosa serve:

  • Arduino
  • Scheda Pit HC-05;
  • Led
  • Servomotori generici
  • Cavetti
  • Smartophone Android;
  • Processing installato sul PC
  • PC

Preparativi (come in PitBraccio):

  • 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)

In questo esempio si vede il robottino comandato via seriale da Processing su PC

Software lato Processing:

  • PitMomo è stato elaborato modificando l'esempio BluetoothCursors - Ketai Library for Android: http://KetaiProject.org di  Daniel Sauter
  • 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 servomotori

In questo esempio si vede il robottino comandato via seriale da Processing su PC

Software lato Arduino:

  • Sul lato Arduino è un programma molto semplice in quanto si tratta di deggere da seriale i comandi e di inviarli alle rispettive porte. I comandi vengono passati tramite seriale nel formato PitProto.
  • 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 - HEADER) 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:
      • S04 (Servo del braccio destro);
      • S05 (Servo del braccio sinistro);
      • S06 (Servo della testa);
      • L01 (Stato dell'occhio destro);
      • L03 (Stato dell'occhio sinistro);
    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ì.
 

ozio_gallery_jgallery

Circuito ed elettronica:

  • I servomotori sono alimentati separatamante in quanto la scheda Arduino non è in grado di alimentarli - al momento sto usando un alimentatore ATX di un vecchio PC che funziona come alimentatore da banco. La massa (GND) viene messa in comune mentre le alimentazioni delle varie parti sono autonome

Codice sorgente:


/*
Pit Momo V1 - Rev 20
Versione V1 - ZappocoS 2/2017
www.zappoco.altervista.org
- Scheda HC-04 con PitBt HC05
- codice PIN per accoppiamento BT 1234
- tre servomotori (libreria Servo.h)
- led cavetti ecc
-
*/
#include <Servo.h>
Servo Servo4;
Servo Servo5;
Servo Servo6;
//  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;
String StrDummy = "12345";
String CodCM;
int IntCM;
int ServoMin =  25;
char val;
int aServo4, aServo5, aServo6;
int oDexPin = 5;
int oSinPin = 6;
int oSinVal = 0;
int oDexVal = 0;
int TimeServo = 500;
void setup()
{
  pinMode(oSinPin, OUTPUT);
  pinMode(oDexPin, OUTPUT);
  Servo4.attach(9);
  Servo4.write(45);
  delay (TimeServo);
  Servo4.write(135);
  delay (TimeServo);
  Servo4.write(90);
  delay (TimeServo);
  Servo5.attach(10);
  Servo5.write(45);
  delay (TimeServo);
  Servo5.write(135);
  delay (TimeServo);
  Servo5.write(90);
  delay (TimeServo);
  Servo6.attach(11);
  Servo6.write(45);
  delay (TimeServo);
  Servo6.write(135);
  delay (TimeServo);
  Servo6.write(90);
  delay (TimeServo);
  //digitalWrite(oSinPin, HIGH);
  digitalWrite(oDexPin, HIGH);
  delay (TimeServo);
  //digitalWrite(oSinPin, LOW);
  digitalWrite(oDexPin, LOW);
  delay (TimeServo);
  digitalWrite(oSinPin, HIGH);
  //digitalWrite(oDexPin, HIGH);
  delay (TimeServo);
  digitalWrite(oSinPin, LOW);
  //digitalWrite(oDexPin, LOW);
  delay (TimeServo);
  Serial.begin (9600);
}
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();
  IntCM = DT_PitProto.toInt();
  //Servo 4
  if (ID_PitProto == "S04" && aServo4 != IntCM)
  {   
      aServo4 = IntCM;
      Servo4.write(IntCM);
  }
  //Servo 5
  if (ID_PitProto == "S05" && aServo5 != IntCM && IntCM >ServoMin)
  {   
      aServo5 = IntCM;
      Servo5.write(IntCM);
  }
  //Servo 6
  if (ID_PitProto == "S06" && aServo6 != IntCM && IntCM >ServoMin)
  {   
      aServo6 = IntCM;
      Servo6.write(IntCM);
  }
  //Led 1
  if (ID_PitProto == "L01" && oSinVal != IntCM)
  {
      if( IntCM == 1)
      {
         digitalWrite(oSinPin, HIGH);
      }
      if( IntCM == 0)
      {
         digitalWrite(oSinPin, LOW);
      }
      oSinVal  = IntCM;
      delay (30);
  }
  //Led 3
  if (ID_PitProto == "L03"  && oDexVal != IntCM)
  {
      if( IntCM == 1)
      {
         digitalWrite(oDexPin, HIGH);
      }
      if( IntCM == 0)
      {
         digitalWrite(oDexPin, LOW);
      }
      oDexVal  = IntCM;
      delay (30);
  }
}
String ItoS (int ii, int nn)
{
   String gg;
   int ll;
   gg.concat(ii);
   gg = "          " + gg;
   ll = gg.length(); 
   gg = gg.substring(ll - nn,ll);
   return gg;
}
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();
}

/**
Pit Momo V1  rev 10
 ZappocoS 2/2017
 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>
 */
// /* Solo per Android
//required for BT enabling on startup
import android.content.Intent;
import android.os.Bundle;
// /* Solo per Android */
import ketai.net.bluetooth.*;
import ketai.ui.*;
import ketai.net.*;
import oscP5.*;
/* Solo per Arduino
import processing.serial.*;
Serial port;                 // Definisce il nome della porta seriale su cui scrivere
/* Solo per Arduino */
public boolean Android = true;  //impostare a true per utilizzare arduino via seriale
public boolean flagDeb = false;  //impostare a true per utilizzare arduino via seriale
//font
PFont Font1;
// stato dei led
boolean oLedSin = false;
boolean oldoLedSin = false;
boolean OcchiLed = false;
boolean oldOcchiLed = false;
boolean oLedDex = false;
boolean oldoLedDex = 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;
String send;
int ctrZoneX = 550;
int ctrZoneY = 400;
//Angolo brDex
float AServoOld4 = -1;//120
float AServo4Min = 30 ;
float AServo4Max = 150 ;
public float AServo4 = 90 ; // Angolo del  Servomotore 4
//Angolo brSin
float AServoOld5 = -1;
float AServo5Min = 30 ;
float AServo5Max = 150 ;
public float AServo5 = 90 ; // Angolo del Servomotore 5
//Rotazione Testa
float AServoOld6 = 120;
float aServo6Min = 30 ;
float aServo6Max = 150 ;
public float AServo6 = 90 ; // Angolo del Servomotore 6 - Testae
// Delay
float TimeDMin = 0 ;
float TimeDMax = 200 ;
public float TimeD = 10 ; // Rallentamento in millisecondi
float DlyMin = 1;
float DlyMax = 10;
// Incremento angolo
float AngleIncMin = 1;
float AngleIncMax = 10;
public float  AngleInc = 3 ;
String Servo1, Servo2, Servo3, Servo4, Servo5, Servo6;
Switch oDex  = new Switch (ctrZoneX - 200, ctrZoneY + 000, 100, 100, oLedDex,   255, 255,   0, 120 ,  120, 120);
Switch oSin  = new Switch (ctrZoneX + 100, ctrZoneY + 000, 100, 100, oLedSin,   255, 255,   0, 120 ,  120, 120);
Switch Occhi = new Switch (ctrZoneX - 150, ctrZoneY + 300, 300, 100, OcchiLed,   200,   0,   0, 120 ,  120, 120);
Slider brDex = new Slider (ctrZoneX - 450, ctrZoneY + 650,  150,  -400, AServo4Min, AServo4Max, AServo4, AngleInc,   0, 152,   0, 120 ,  120, 120);
Slider brSin = new Slider (ctrZoneX + 300, ctrZoneY + 650,  150,  -400, AServo5Min, AServo5Max, AServo5, AngleInc,   0, 152,   0, 120 ,  120, 120);
Slider Testa = new Slider (ctrZoneX - 250, ctrZoneY + 550, -500,   150, aServo6Min, aServo6Max, AServo6, AngleInc, 152, 228, 255, 120 ,  120, 120);
// /* Solo per Android
//********************************************************************
// 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);
}
// /* Solo per Android */
//********************************************************************
void setup()
{   
  //fullScreen();
  //size(displayWidth, displayHeight);
  //size(1820, 1024);
  size(1080, 1920);
  orientation(PORTRAIT);
  background(78, 93, 75);
  stroke(255);
  textSize(24);
  //Font1 = createFont("Comic Sans MS", 24);
  // setta font per le scritte 
  //textFont(Font1);
  //sceglie la porta di comunicazione
  /* Solo per Arduino
  port = new Serial(this, "COM4", 9600);
  port.bufferUntil('\n');
  /* Solo per Arduino */ 
  //start listening for BT connections
  // /* Solo per Android
  bt.start();
  // /* Solo per Android */
  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";
   //delay (3000);
   PitMomoReset ();  
}
void draw()
{
  if (isConfiguring)
  {
    ArrayList<String> names;
    background(78, 93, 75);
    //Testaed on last key pressed lets display
    //  appropriately
    if (key == 'i')
    {
        // /* Solo per Android
        info = getBluetoothInformation();
        println ("Info  --> :" + info);
        // /* Solo per Android */
    }
    else
    {
      if (key == 'p')
      {
        // /* Solo per Android
        info = "Paired Devices:\n";
        names = bt.getPairedDeviceNames();
        // /* Solo per Android */
      }
      else
      {
        // /* Solo per Android
        info = "Discovered Devices:\n";
        names = bt.getDiscoveredDeviceNames();
        // /* Solo per Android */
      }
      // /* Solo per Android
      for (int i=0; i < names.size(); i++)
      {
        info += "["+i+"] "+names.get(i).toString() + "\n";
      }
      // /* Solo per Android */
    }
    if (Android)
    {
      text(UIText + "\n\n" + info, 5, 140);
    }
    OcchiLed = Occhi.flagOn;
    if (OcchiLed !=  oldOcchiLed)
    {
      oSin.flagOn = !oSin.flagOn;
      oDex.flagOn = !oDex.flagOn;
      oldOcchiLed =  OcchiLed;
    }
    oLedSin = oSin.flagOn;
    oLedDex = oDex.flagOn;
    AServo4 = brDex.Val;
    AServo5 = brSin.Val;
    AServo6 = Testa.Val;
    //String send;
    /*
      --------------------------------
        Definizione comandi secondo protocollo PitProto
      --------------------------------
    */
    send = "ZS04" + nf(int(AServoOld4), 4);
    Servo4 = send;
    if (AServoOld4 != AServo4){
        //PitSendData (send);
        /* Solo per Arduino    
        port.write (send);
        /* Solo per Arduino */
        // /* Solo per Android
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        // /* Solo per Android */
        AServoOld4 = AServo4;
    }
    send = "ZS05" + nf(int(AServoOld5), 4);
    Servo5 = send;
    if (AServoOld5 != AServo5){
        //PitSendData (send);
        /* Solo per Arduino    
        port.write (send);
        /* Solo per Arduino */
        // /* Solo per Android
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        // /* Solo per Android */
        AServoOld5 = AServo5;
    }
    send = "ZS06" + nf(int(AServo6), 4);
    Servo6 = send;
    if (AServoOld6 != AServo6){
        //PitSendData (send);
        /* Solo per Arduino    
        port.write (send);
        /* Solo per Arduino */
        // /* Solo per Android
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        // /* Solo per Android */
        AServoOld6 = AServo6;
    }
    if (oLedSin != oldoLedSin && oLedSin == true){
        send = "ZL010001";
        //PitSendData (send);
        /* Solo per Arduino    
        port.write (send);
        /* Solo per Arduino */
        // /* Solo per Android
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        // /* Solo per Android */
        oldoLedSin = oLedSin;
    }
    if (oLedSin != oldoLedSin && oLedSin == false){
        send = "ZL010000";
        //PitSendData (send);
        /* Solo per Arduino    
        port.write (send);
        /* Solo per Arduino */
        // /* Solo per Android
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        // /* Solo per Android */
        oldoLedSin = oLedSin;
    }
    if (oLedDex != oldoLedDex && oLedDex == true){
        send = "ZL030001";
        //PitSendData (send);
        /* Solo per Arduino    
        port.write (send);
        /* Solo per Arduino */
        // /* Solo per Android
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        // /* Solo per Android */
        oldoLedDex = oLedDex;
    }
    if (oLedDex != oldoLedDex && oLedDex == false){
        send = "ZL030000";
        //PitSendData (send);
        /* Solo per Arduino    
        port.write (send);
        /* Solo per Arduino */
        // /* Solo per Android
        byte [] data = send.getBytes(); 
        bt.broadcast(data);  
        // /* Solo per Android */
        oldoLedDex = oLedDex;
    }
  }
  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();
  }
  //Solo Android
  drawUI();
  if (mousePressed == true)
  {
    brDex.mouseIn();
    brSin.mouseIn();
    Testa.mouseIn();
    oSin.mouseIn();
    oDex.mouseIn();
    Occhi.mouseIn();
  }
  oSin.update();
  oDex.update();
  Occhi.update();
  brDex.update();
  brSin.update();
  Testa.update();
  fill(255);
  //rotate (PI/2);
  textSize(30);
  text("PitMomo V.0.10 - 02/2017"   , 720, 140);
  textSize(28);
  text("www.zappoco.altervista.org" , 720, 140 +30);
  //textSize(20);
  if (flagDeb) 
    {
      fill(brDex.colorR, brDex.colorG, brDex.colorB);
      text("brDex: " + nf(int(AServoOld4),4)  + " " +Servo4 , ctrZoneX - 350 , ctrZoneY + 850);
      fill(brSin.colorR, brSin.colorG, brSin.colorB);
      text("brSin: " + nf(int(AServoOld5),4)  + " " +Servo5 , ctrZoneX + 200, ctrZoneY + 850);
      fill(Testa.colorR, Testa.colorG, Testa.colorB);
      text("Testa: " + nf(int(AServoOld6),4)  + " " +Servo6, ctrZoneX - 50, ctrZoneY + 850);
    }
}
void PitMomoReset ()
{
      oSin.flagOn = false;
      oDex.flagOn = false;
      brDex.Val = 90;
      brSin.Val = 90;
      Testa.Val = 90;
      //delay (2000);
      Occhi.flagOn = false;
      AServoOld4 = brDex.Val; 
      AServoOld5 = brSin.Val;
      AServoOld6 = Testa.Val;
}
void PitSendData (String S)
{
    /* Solo per Arduino    
    port.write (S);
    /* Solo per Arduino */
    // /* Solo per Android
    byte [] data = S.getBytes(); 
    bt.broadcast(data);  
    // /* Solo per Android */
    if (flagDeb)
    {
      println(S);
    }
}
// /* Solo per Android
//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;
}
// /* Solo per Android */​

/*  UI-related functions */
void mousePressed()
{
  //keyboard button -- toggle virtual keyboard
  if (mouseY <= 100 && mouseX > 0 && mouseX < width/3)
    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;
    }
  }
}
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();
  }
}
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);
  textSize(40);
  text("Keyboard", 5, 30); 
  text("Bluetooth", width/3+5, 30); 
  text("Interact", width/3*2+5, 30); 
  textSize(2e0);
  popStyle();
}
void onKetaiListSelection(KetaiList klist)
{
  String selection = klist.getSelection();
  bt.connectToDeviceByName(selection);
  //dispose of list for now
  klist = null;
}​

/**
 * 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);
      }
      rectMode(CORNER);
      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;
  long time0;
  Switch (float x, float y, float a , float b, boolean fOn, int cR, int cG, int cB,int bR, int bG, int bB) {
    //    00-------------10
    //    |               |
    //    |      [1]      |
    //    |               |
    //    01-------------11
    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);
    }
    rectMode(CORNER);
    rect(x0, y0, dx, dy);
  }
  void mouseIn () {
    if (mouseX > x0 && mouseX < x0 + dx && mouseY > y0 && mouseY < y0 + dy)
    {
    if (millis() - time0 >= 200)
      {
        // println ("IN flagOn :" + flagOn + " " + millis());                
        time0 = millis();
        flagOn = !flagOn;
        // println ("IN flagOn :" + flagOn + " " + millis());
      }
    }
    else
    {
        // println ("Out flagOn :" + flagOn);
    }
  } 
}
class Joy01 { 
  float x0, y0;
  float dx, dy;
  float x1,  y1,  x2,  y2, x3, y3, dx1, dy1;
  boolean flagUp;
  boolean flagIn;
  int bColorR, bColorG, bColorB;
  int colorR, colorG, colorB;
  float minimoValX, massimValX, ValX, dValX;
  float minimoValY, massimValY, ValY, dValY;
  Joy01 (float x, float y, float a , float b, float minVX, float maxVX, float minVY, float maxVY, float VX, float dVX, float VY, float dVY, int cR, int cG, int cB,int bR, int bG, int bB)
  {
    //    00-----   ---  -----10
    //    |                    |
    //    |  [1]    [5]   [2]  |
    //    |                    |
    //           22              
    //    |  [7]    [9]   [8]  |
    //                 33      
    //    |                    |
    //    |  [3]    [6]   [4]  |
    //    |                    |
    //    01-----   ---  -----11
    x0 = x;
    y0 = y; 
    dx = abs(a);
    dy = abs(b);
    x1 = x0 + dx;
    y1 = y0 + dy;
    x2 = x0 + 0.4 * dx;
    y2 = y0 + 0.4 * dy;
    x3 = x0 + 0.6 * dx;
    y3 = y0 + 0.6 * dy;
    dx1 = dx/10;
    dy1 = dy/10;
    minimoValX = minVX;
    massimValX = maxVX;
    minimoValY = minVY;
    massimValY = maxVY;
    flagUp  = b > 0; // se maggiore di 0 riempie VAL
    if (dVX == 0)
    {
      dValX = (massimValX - minimoValX)/10;
    }
    else
    {
      dValX = dVX;
    }
    ValX = VX;
    if (dVY == 0)
    {
      dValY = (massimValY - minimoValY)/10;
    }
    else
    {
      dValY = dVY;
    }
    ValY = VY;
    limit ();
    bColorR = bR;
    bColorG = bG;
    bColorB = bB;
    colorR = cR;
    colorG = cG;
    colorB = cB;
  } 
  void limit ()
  {
    if (ValX <= minimoValX)
    {
      ValX = minimoValX;
    }
    if (ValX >= massimValX)
    {
      ValX = massimValX; 
    }
    if (ValY <= minimoValY)
    {
      ValY = minimoValY;
    }
    if (ValY >= massimValY)
    {
      ValY = massimValY; 
    }
  }
  void update () {
    stroke(255, 255,255);
    if (flagUp)
    {
      fill(bColorR,bColorG,bColorB);
    }
    else{
      fill(colorR,colorG,colorB);
    }
    rect(x0, y0, dx, dy);
    if (flagUp)
    {
      fill(colorR,colorG,colorB);
    }
    else{
      fill(bColorR,bColorG,bColorB);
    }
    //x1 = x0 + 9*dx/10 * (ValX - minimoValX) / (massimValX - minimoValX);
    //y1 = y0 + 9*dy/10 * (-ValY + massimValY) / (massimValY - minimoValY);  
    //rect(x1, y1, dx1, dy1);
    rect(x0 + 9*dx/10 * (ValX - minimoValX) / (massimValX - minimoValX), y0 + 9*dy/10 * (-ValY + massimValY) / (massimValY - minimoValY), dx1, dy1);
    line (x2 , y0, x2, y1);  
    line (x3 , y0, x3, y1);
    line (x0 , y2 , x1, y2);  
    line (x0 , y3 , x1, y3);  
  }
  void mouseIn () {
      int mX, mY;
      mX = mouseX;
      mY = mouseY;
      // // println ("( millis ):  " + mX + " " + mY +" " + millis());
      // cerca il quadrante
      if (mX > x0 && mX < x1 && mY > y0 && mY < y1)
      {
        flagIn = true;
        if (mX > x0 && mX < x2 && mY > y0 && mY < y2)
        {
          ValX = ValX - dValX;// * (mX - x0) / dx / 2;
          ValY = ValY + dValY;// * (mY - y0) / dy / 2;
          // println ("[ J1 ]");
        }
        // - X + Y
        else if (mX > x0 && mX < x2 && mY > y3 && mY < y1)
        {
          ValX = ValX - dValX;// * (mX - x0) / dx / 2;
          ValY = ValY - dValY;// * (-mY + y2) / dy / 2;
          // println ("[ J3 ]");
        }
        // + X - Y
        else if (mX > x3 && mX < x1 && mY > y0 && mY < y2)
        {
          ValX = ValX + dValX;//  * (- mX + x2) / dx / 2;
          ValY = ValY + dValY;//  * (mY - y0) / dy / 2;
          // println ("[ J2 ]");
          // println ("( + ):  " + minimoValX + " " + ValX + " " + massimValX);
          // println ("( - ):  " + minimoValY + " " + ValY + " " + massimValY);
        }
        // + X + Y
        else if (mX > x3 && mX < x1 && mY > y3 && mY < y1)
        {
          ValX = ValX + dValX;//  * (- mX + x2) / dx / 2;;
          ValY = ValY - dValY;// * (-mY + y2) / dy / 2;
          // println ("[ J4 ]");          
          // println ("( + ):  " + minimoValX + " " + ValX + " " + massimValX);
          // println ("( + ):  " + minimoValY + " " + ValY + " " + massimValY);
        }
        // - Y
        else if (mX > x2 && mX < x3 && mY > y0 && mY < y2)
        {
          ValY = ValY + dValY;
          // println ("[ J5 ]");          
          // println ("( 0 ):  " + minimoValX + " " + ValX + " " + massimValX);
          // println ("( + ):  " + minimoValY + " " + ValY + " " + massimValY);
        }
        // + Y
        else if (mX > x2 && mX < x3 && mY > y3 && mY < y1)
        {
          ValY = ValY - dValY;
          // println ("[ J6 ]");          
          // println ("( 0 ):  " + minimoValX + " " + ValX + " " + massimValX);
          // println ("( - ):  " + minimoValY + " " + ValY + " " + massimValY);
        }
        // - X
        else if (mX > x0 && mX < x2 && mY > y2 && mY < y3)
        {
          ValX = ValX - dValX;
          // println ("[ J7 ]");          
          // println ("( + ):  " + minimoValX + " " + ValX + " " + massimValX);
          // println ("( 0 ):  " + minimoValY + " " + ValY + " " + massimValY);
        }
        // + X
        else if (mX > x3 && mX < x1 && mY > y2 && mY < y3)
        {
          ValX = ValX + dValX;
          // println ("[ J8 ]");
          // println ("( + ):  " + minimoValX + " " + ValX + " " + massimValX);
          // println ("( 0 ):  " + minimoValY + " " + ValY + " " + massimValY);
        }
        else if (mX > x2 && mX < x3 && mY > y2 && mY < y3)
        {
          ValX = (massimValX + minimoValX)/2;
          ValY = (massimValY + minimoValY)/2;
          // println ("[ J9 ]");            
          // println ("( + ):  " + minimoValX + " " + ValX + " " + massimValX);
          // println ("( 0 ):  " + minimoValY + " " + ValY + " " + massimValY);
        }
        limit ();
      }
      else
      {
        flagIn = false;
        // println ("J_none");
      }
      // println ("v:  " + ValX + " " + ValY);
      // return (flagIn); 
  } 
}
class Slider { 
  float x0, y0;
  float dx, dy;
  float x1, y1, x2, y2, x3, y3, dx1, dy1, dx2, dy2, sDV;
  boolean flagUp;
  boolean flagBar;
  boolean flagIn;
  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)
  {
    //    00-----10
    //    |       |
    //    |  [1]  |
    //    |       |
    //    02     22            
    //    |  [2]  |
    //    33     30       
    //    |       |
    //    |  [3]  |
    //    |       |
    //    01-----11
    //    00------20-------33--------10
    //    |                           |
    //    |  [1]       [2]       [3]  |
    //    |                           |
    //    01------22-------30--------11
    x0 = x;
    y0 = y; 
    dx = abs(a);
    dy = abs(b);
    x1 = x0 + dx;
    y1 = y0 + dy;
    // barra orizzontale o verticale
    if (dx >= dy)
    {  
      x2 = x0 + 0.4 * dx;
      y2 = y1;
      x3 = x0 + 0.6 * dx;
      y3 = y0;
      sDV = 1;
    }
    else
    {
      x2 = x1;
      y2 = y0 + 0.4 * dy;
      x3 = x0;
      y3 = y0 + 0.6 * dy;
      sDV = -1;
    }
    flagBar = a > 0; // se maggiore riempie la barra
    flagUp  = b > 0; // se maggiore di 0 riempie VAL
    dx1 = dx/10;
    dy1 = dy/10;
    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 (flagBar)  // riempie la barra
       {
         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;
           }
       }
     else
       {
         if (dx >= dy) //orizzontale
           {
             x1 = x0 + (dx - dx/15) * (Val - minimoVal) / (massimVal - minimoVal);;
             dx1 = dx/15;
             y1 = y0;
             dy1 = dy;  
           }
         else        //verticale
           {
             y1  = y0 + dy - dy/15 - (dy - dy/15) * (Val - minimoVal) / (massimVal - minimoVal);
             dy1 = dy/15;
             x1 = x0;
             dx1 = dx;  
           }
       }
     */
      stroke(255, 255,255);
      if (flagUp)
      {
        fill(bColorR,bColorG,bColorB);
      }
      else{
        fill(colorR,colorG,colorB);
      }
      rect(x0, y0, dx, dy);
      if (flagUp)
      {
        fill(colorR,colorG,colorB);
      }
      else{
        fill(bColorR,bColorG,bColorB);
      }
      if (flagBar)  // riempie la barra
      {
        if (dx >= dy)
        {
          dx1 = dx * (Val - minimoVal) / (massimVal - minimoVal);
          dy1 = y0 - y1;
        }
        else  // riempie la barra
        {
          dx1 = x1 - x0;
          dy1 = -dy * (Val - minimoVal) / (massimVal - minimoVal);
        }
        rect(x0, y1, dx1, dy1);
      }
      else
      {
        if (dx >= dy)
        {
            rect(x0 + 9*dx/10 * (Val - minimoVal) / (massimVal - minimoVal), y0, dx1, dy);          
        }
        else
        {
            rect(x0, y0 + 9*dy/10 * (-Val + massimVal) / (massimVal - minimoVal), dx, dy1);
        }
      }
      //rect(x0 + 9*dx/10 * (Val - minimoVal) / (massimVal - minimoVal), y0 + 9*dy/10 * (-Val + massimVal) / (massimVal - minimoVal), dx1, dy1);      
      //rect(x1, y1, dx1, dy1);
  }
  void mouseIn () {
      int mX, mY;
      mX = mouseX;
      mY = mouseY;
      // // println ("( millis ):  " + mX + " " + mY +" " + millis());
      // cerca il quadrante
      if (mX > x0 && mX < x1 && mY > y0 && mY < y1)
      {
        flagIn = true;
        if (mX > x0 && mX < x2 && mY > y0 && mY < y2)
        {
          Val = Val - dVal * sDV;
          // println ("( + ):  " + minimoVal + " " + Val + " " + massimVal);
          // println ("[ S1 ]");
        }
        else if (mX > x3 && mX < x1 && mY > y3 && mY < y1)
        {
          Val = Val + dVal * sDV;
          // println ("( - ):  " + minimoVal + " " + Val + " " + massimVal);
          // println ("[ S2 ]");
        }
        limit ();
      }
      else
      {
        flagIn = false;
        // println ("Slider_none");
      }
  } 
} 
 

ZappocoS - 19 febbraio 2017