Radar com Ping e Processing



Neste post estou mostrando minha adaptação do trabalho do Luckylarry para uso com o sensor ping ao invés do SRF-05.



Ao Lado  o sensor da Seeedstudio que é uma versão do sensor ping da Parallax, este sensor funciona baseado na emissão e captação de sinais sonoros.

O pricípio de funcionamento é a relação de tempo entre a emissão e a captação do som, baseado no fato de que o som tem uma velocidade constante é possível calcular a distância quando o intervalo entre a emissão e a captação é conhecido.



A montagem do sistema utiliza as seguintes portas do arduino:

 - Digital 7 para o sensor ping
 - Digital 9 (pmw) para o servo

Os dados recebidos no arduino na porta 7 são pulsos eletrícos que são convertidos em medidas de distância por uma formula simples e enviados para a porta serial para processamento do Processing.

A fórmula de conversão é baseada no fato de que  velocidade do som é de 340 m/s ou 29 microssegundos por centímetro, logo se o sinal do sensor (pulsos em microssegundos) for dividido por 29 e depois novamente dividido por 2 ( o som é emitido e volta por isso temos que dividir por 2) teremos a distância em centimetros: microseconds / 29 / 2.









Foram necessárias poucas mudanças no código do arduino, o do processing é igual.

---------------------------------------------------------------------------------------------------------

Código Arduino:

/*
ARDUINO - RADAR COM PING E PROCESSING
ADAPTADO POR CLÁUDIO MIKLOS - WWW.MIKLOS.BLOG.BR - PARA USO COM SENSOR PING
CERDITOS ORIGINAIS:
luckylarry.co.uk
Radar Screen Visualisation for SRF-05
Sends sensor readings for every degree moved by the servo
values sent to serial port to be picked up by Processing
*/

#include <Servo.h>             // include the standard servo library
Servo leftRightServo;         // set a variable to map the servo
int leftRightPos = 0;         // set a variable to store the servo position
const int numReadings = 10;   // set a variable for the number of readings to take
int index = 0;                // the index of the current reading
int total = 0;                // the total of all readings
int average = 0;              // the average
int pingPin = 7;              // the PING pin
unsigned long duration = 0;  // variable for reading the pulse
unsigned long distance = 0;   // variable for storing distance
 
/* setup the pins, servo and serial port */
void setup() {
  leftRightServo.attach(9);
  Serial.begin(9600);
}
 
/* begin rotating the servo and getting sensor values */
void loop() {
  for(leftRightPos = 0; leftRightPos < 180; leftRightPos++) {  // going left to right.
    leftRightServo.write(leftRightPos);
      for (index = 0; index<=numReadings;index++) {            // take x number of readings from the sensor and average them
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);
        distance = duration / 29 / 2;                            // convert to centimetres
        total = total + distance;                              // update total
        delay(10);
      }
    average = total/numReadings;                               // create average reading
 
    if (index >= numReadings)  {                               // reset the counts when at the last item of the array
      index = 0;
      total = 0;
    }
    Serial.print("X");                                         // print leading X to mark the following value as degrees
    Serial.print(leftRightPos);                                // current servo position
    Serial.print("V");                                         // preceeding character to separate values
    Serial.println(average);                                   // average of sensor readings
  }
  /*
  start going right to left after we got to 180 degrees
  same code as above
  */
  for(leftRightPos = 180; leftRightPos > 0; leftRightPos--) {  // going right to left
    leftRightServo.write(leftRightPos);
    for (index = 0; index<=numReadings;index++) {
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);
        distance = duration / 29 / 2;                            // convert to centimetres
        total = total + distance;                              // update total
      delay(10);
    }
    average = total/numReadings;
    if (index >= numReadings)  {
      index = 0;
      total = 0;
    }
    Serial.print("X");
    Serial.print(leftRightPos);
    Serial.print("V");
    Serial.println(average);

   }

}

------------------------------------------------------------------------
Código Processing
/*
ARDUINO - RADAR COM PING E PROCESSING
ADAPTADO POR CLÁUDIO MIKLOS - WWW.MIKLOS.BLOG.BR - PARA USO COM SENSOR PING
CERDITOS ORIGINAIS:
luckylarry.co.uk
Radar Screen Visualisation for SRF-05
Maps out an area of what the SRF-05 sees from a top down view.
Takes and displays 2 readings, one left to right and one right to left.
Displays an average of the 2 readings
Displays motion alert if there is a large difference between the 2 values.
*/
import processing.serial.*;     // import serial library
Serial arduinoport;                  // declare a serial port
float x, y;                       // variable to store x and y co-ordinates for vertices   
int radius = 350;               // set the radius of objects
int w = 300;                    // set an arbitary width value
int degree = 0;                 // servo position in degrees
int value = 0;                  // value from sensor
int motion = 0;                 // value to store which way the servo is panning
int[] newValue = new int[181];  // create an array to store each new sensor value for each servo position
int[] oldValue = new int[181];  // create an array to store the previous values.
PFont myFont;                   // setup fonts in Processing
int radarDist = 0;              // set value to configure Radar distance labels
int firstRun = 0;               // value to ignore triggering motion on the first 2 servo sweeps

/* create background and serial buffer */
void setup(){
// setup the background size, colour and font.
size(750, 450);
background (0); // 0 = black
myFont = createFont("verdana", 12);
textFont(myFont);
// setup the serial port and buffer
arduinoport = new Serial(this, Serial.list()[0], 9600);

}

/* draw the screen */
void draw(){
fill(0);                              // set the following shapes to be black
noStroke();                           // set the following shapes to have no outline
ellipse(radius, radius, 750, 750);    // draw a circle with a width/ height = 750 with its center position (x and y) set by the radius
rectMode(CENTER);                     // set the following rectangle to be drawn around its center
rect(350,402,800,100);                // draw rectangle (x, y, width, height)
if (degree >= 179) {                  // if at the far right then set motion = 1/ true we're about to go right to left
motion = 1;                         // this changes the animation to run right to left
}
if (degree <= 1) {                    // if servo at 0 degrees then we're about to go left to right
motion = 0;                         // this sets the animation to run left to right
}
/* setup the radar sweep */
/* 
We use trigonmetry to create points around a circle.
So the radius plus the cosine of the servo position converted to radians
Since radians 0 start at 90 degrees we add 180 to make it start from the left
Adding +1 (i) each time through the loops to move 1 degree matching the one degree of servo movement
cos is for the x left to right value and sin calculates the y value
since its a circle we plot our lines and vertices around the start point for everything will always be the center.
*/
strokeWeight(7);                      // set the thickness of the lines
if (motion == 0) {                    // if going left to right
for (int i = 0; i <= 20; i++) {     // draw 20 lines with fading colour each 1 degree further round than the last
stroke(0, (10*i), 0);             // set the stroke colour (Red, Green, Blue) base it on the the value of i
line(radius, radius, radius + cos(radians(degree+(180+i)))*w, radius + sin(radians(degree+(180+i)))*w); // line(start x, start y, end x, end y)
}
} else {                              // if going right to left
for (int i = 20; i >= 0; i--) {     // draw 20 lines with fading colour
stroke(0,200-(10*i), 0);          // using standard RGB values, each between 0 and 255
line(radius, radius, radius + cos(radians(degree+(180+i)))*w, radius + sin(radians(degree+(180+i)))*w);
}
}
/* Setup the shapes made from the sensor values */
noStroke();                           // no outline
/* first sweep */
fill(0,50,0);                         // set the fill colour of the shape (Red, Green, Blue)
beginShape();                         // start drawing shape
for (int i = 0; i < 180; i++) {     // for each degree in the array
x = radius + cos(radians((180+i)))*((oldValue[i])); // create x coordinate
y = radius + sin(radians((180+i)))*((oldValue[i])); // create y coordinate
vertex(x, y);                     // plot vertices
}
endShape();                           // end shape
/* second sweep */
fill(0,110,0);
beginShape();
for (int i = 0; i < 180; i++) {
x = radius + cos(radians((180+i)))*(newValue[i]);
y = radius + sin(radians((180+i)))*(newValue[i]);
vertex(x, y);
}
endShape();
/* average */
fill(0,170,0);
beginShape();
for (int i = 0; i < 180; i++) {
x = radius + cos(radians((180+i)))*((newValue[i]+oldValue[i])/2); // create average
y = radius + sin(radians((180+i)))*((newValue[i]+oldValue[i])/2);
vertex(x, y);
}
endShape();
/* if after first 2 sweeps, highlight motion with red circle*/
if (firstRun >= 360) {
stroke(150,0,0);
strokeWeight(1);
noFill();
for (int i = 0; i < 180; i++) {
if (oldValue[i] - newValue[i] > 35 || newValue[i] - oldValue[i] > 35) {
x = radius + cos(radians((180+i)))*(newValue[i]);
y = radius + sin(radians((180+i)))*(newValue[i]);
ellipse(x, y, 10, 10); 
}
}
}
/* set the radar distance rings and out put their values, 50, 100, 150 etc.. */
for (int i = 0; i <=6; i++){
noFill();
strokeWeight(1);
stroke(0, 255-(30*i), 0);
ellipse(radius, radius, (100*i), (100*i)); 
fill(0, 100, 0);
noStroke();
text(Integer.toString(radarDist+50), 380, (305-radarDist), 50, 50);
radarDist+=50;
}
radarDist = 0;
/* draw the grid lines on the radar every 30 degrees and write their values 180, 210, 240 etc.. */
for (int i = 0; i <= 6; i++) {
strokeWeight(1);
stroke(0, 55, 0);
line(radius, radius, radius + cos(radians(180+(30*i)))*w, radius + sin(radians(180+(30*i)))*w);
fill(0, 55, 0);
noStroke();
if (180+(30*i) >= 300) {
text(Integer.toString(180+(30*i)), (radius+10) + cos(radians(180+(30*i)))*(w+10), (radius+10) + sin(radians(180+(30*i)))*(w+10), 25,50);
} else {
text(Integer.toString(180+(30*i)), radius + cos(radians(180+(30*i)))*w, radius + sin(radians(180+(30*i)))*w, 60,40);
}
}
/* Write information text and values. */
noStroke();
fill(0);
rect(350,402,800,100);
fill(0, 100, 0);
text("Degrees: "+Integer.toString(degree), 100, 380, 100, 50);         // use Integet.toString to convert numeric to string as text() only outputs strings
text("Distance: "+Integer.toString(value), 100, 400, 100, 50);         // text(string, x, y, width, height)
text("Radar screen code at luckylarry.co.uk", 540, 380, 250, 50);
fill(0);
rect(70,60,150,100);
fill(0, 100, 0); 
text("Screen Key:", 100, 50, 150, 50);
fill(0,50,0);
rect(30,53,10,10);
text("First sweep", 115, 70, 150, 50);
fill(0,110,0);
rect(30,73,10,10);
text("Second sweep", 115, 90, 150, 50);
fill(0,170,0);
rect(30,93,10,10);
text("Average", 115, 110, 150, 50);
noFill();
stroke(150,0,0);
strokeWeight(1);
ellipse(29, 113, 10, 10); 
fill(150,0,0);
text("Motion", 115, 130, 150, 50);
}

/* get values from serial port */
void serialEvent (Serial arduinoport) {
String xString = arduinoport.readStringUntil('\n');  // read the serial port until a new line
if (xString != null) {  // if theres data in between the new lines
xString = trim(xString); // get rid of any whitespace just in case
String getX = xString.substring(1, xString.indexOf("V")); // get the value of the servo position
String getV = xString.substring(xString.indexOf("V")+1, xString.length()); // get the value of the sensor reading
degree = Integer.parseInt(getX); // set the values to variables
value = Integer.parseInt(getV);
oldValue[degree] = newValue[degree]; // store the values in the arrays.
newValue[degree] = value;  
/* sets a counter to allow for the first 2 sweeps of the servo */
firstRun++;
if (firstRun > 360) {
firstRun = 360; // keep the value at 360 
}
}
}

Most Useless Machine - Caixa Teimosa



Neste post estou apresentando um projeto simples e ao mesmo tempo muito divertido, uma caixa que se desliga sozinha. Este projeto ensina alguns princípios básicos como o uso de chave DPDT e microswitches e especialmente os conceitos de montagem mecânica que são sempre o mais interessante quando se quer uma atividade que prenda a atenção das crianças (no meu caso, minha filha de 11 anos que criou a pintura com cara de monstro para a caixa).

Existem centenas de vídeos e páginas com este projeto e até mesmo kits prontos para montar como é o caso deste da solarbotics.

Os materiais para montagem são:

1. Uma caixa de qualquer material rígido e fácil de furar, comprei uma de madeira em uma loja de artesanato por R$ 4,00;
2. Um microswitch e um switch DPDT que podem ser encontrado em qualquer loja de componentes eletrônicos;
3. Um motor, eu utilizei um de 33 rpm com alimentação de 6 volts, testei alguns mais rápidos mas a caixa saiu de controle :-);
4. Um poco de arame e criatividade para montar e adaptar o braço mecanico;
5. Uma fonte de alimentação, no meu caso foi uma bateria de 6 v chumbo ácido que eu tinha aqui mas pode ser com pilhas ou outra fonte.

O esquema de montagem é o seguinte:



Segue um vídeo com o funcionamento interno:



Quando liga-se o switch, o braço move-se na direção para desligá-lo, quando o braço desliga o switch a direção do motor é invertida.
Quando o braço chega ao fim do curso, aciona o microswitch que desliga todo o sistema. Divirta-se!

Som na Caixa!

Estou pesquisando uma forma de incluir som quando o botão da caixa é ligado.

seguem alguns links para minha pesquisa com o chip LM386:

http://josepino.com/audio/mini_amplifier_lm386

http://www.instructables.com/id/Audio-Amplifier

http://www.instructables.com/id/Know-Your-IC-LM386/step4/Project-layout/



Ethernet Shield enviando dados para web



Neste post estou usando o ethernet shield do arduino para enviar as leituras de temperatura de um sensor LM35 para o site  ThingSpeak e exibir estas leituras em forma de gráfico no blog. O site ThingSpeak permite que o usuário envie diversos tipos de dados e acesse estes dados de diversas formas com uma api para inclusão em outros meios como web, twitter ou o que mais você quiser.

No exemplo abaixo estou enviando estas leituras para um pequeno gráfico que pode ser visto em todas as páginas deste blog, esta mesma idéia pode ser usada para enviar outros tipos de leituras e existem ainda formas de fazer com que esta função tenha duas vias para controlar equipamentos e fazer automação doméstica.

Na imagem acima o sensor está conectado na porta analógica 0 e alimentado por 5V a partir da própria placa Ethernet. As leituras analógicas são convertidas para apresentar a temperatura em graus centígrados antes do envio.

(imagem estática de exemplo)

O código para exibição no blog é simples e pode ser encontrado no endereço https://www.thingspeak.com/channels/261 que é o endereço do canal destes dados no site ThingSpeak.

----------------------------------------------------------------------------------------------------


/*

 ThingSpeak Client to Update Channel Feeds
 
 The ThingSpeak Client sketch is designed for the Arduino + Ethernet Shield.
 This sketch updates a channel feed with an analog input reading via the
 ThingSpeak API (http://community.thingspeak.com/documentation/)
 using HTTP POST.
 
 Getting Started with ThingSpeak:
 
    * Sign Up for New User Account - https://www.thingspeak.com/users/new
    * Create a New Channel by selecting Channels and then Create New Channel
    * Enter the Write API Key in this sketch under "ThingSpeak Settings"
 
 Created: January 25, 2011 by Hans Scharler (http://www.iamshadowlord.com)
 
 Additional Credits: Example sketches from Tom Igoe and David A. Mellis
 
*/

#include <SPI.h>
#include <Ethernet.h>

int pin = 0; // analog pin
int tempc = 0,tempf=0; // temperature variables
int samples[8]; // variables to make a better precision
int maxi = -100,mini = 100; // to start max/min temperature
int i;

// Local Network Settings
byte mac[]     = { 0xD4, 0x28, 0xB2, 0xFF, 0xA0, 0xA1 }; // Must be unique on local network
byte ip[]      = { 192, 168,   1,  13 };                // Must be unique on local network
byte gateway[] = { 192, 168,   1,   1 };
byte subnet[]  = { 255, 255, 255,   0 };

// ThingSpeak Settings
byte server[]  = { 184, 106, 153, 149 }; // IP Address for the ThingSpeak API
String writeAPIKey = "sua chave vai aqui";    // Write API Key for a ThingSpeak Channel
const int updateInterval = 10000;        // Time interval in milliseconds to update ThingSpeak   
Client client(server, 80);

// Variable Setup
long lastConnectionTime = 0; 
boolean lastConnected = false;
int resetCounter = 0;

void setup()
{
  Ethernet.begin(mac, ip, gateway, subnet);
  Serial.begin(9600);
  delay(1000);
}

void loop()
{
  
  tempc = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;

  String analogPin0 = String(tempc);
  
  // Print Update Response to Serial Monitor
  if (client.available())
  {
    char c = client.read();
    Serial.print(c);
  }
  
  // Disconnect from ThingSpeak
  if (!client.connected() && lastConnected)
  {
    Serial.println();
    Serial.println("...disconnected.");
    Serial.println();
    
    client.stop();
  }
  
  // Update ThingSpeak
  if(!client.connected() && (millis() - lastConnectionTime > updateInterval))
  {
    updateThingSpeak("field1="+analogPin0);
  }
  
  lastConnected = client.connected();
}

void updateThingSpeak(String tsData)
{
  if (client.connect())
  { 
    Serial.println("Connected to ThingSpeak...");
    Serial.println();
        
    client.print("POST /update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("X-THINGSPEAKAPIKEY: "+writeAPIKey+"\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(tsData.length());
    client.print("\n\n");

    client.print(tsData);
    
    lastConnectionTime = millis();
    
    resetCounter = 0;
    
  }
  else
  {
    Serial.println("Connection Failed.");   
    Serial.println();
    
    resetCounter++;
    
    if (resetCounter >=5 ) {resetEthernetShield();}

    lastConnectionTime = millis(); 
  }
}

void resetEthernetShield()
{
  Serial.println("Resetting Ethernet Shield.");   
  Serial.println();
  
  client.stop();
  delay(1000);
  
  Ethernet.begin(mac, ip, gateway, subnet);
  delay(1000);
}

----------------------------------------------------------------------------

Controle Remoto - TV-B-Gone Arduino


O projeto TV-B-Gone foi idealizado pela Adafruit e é vendido como um kit completo para montagem em casa, o objetivo é desligar qualquer TV  que esteja atrapalhando seu almoço ou leitura em lugares públicos.

No kit original o processador utilizado é o ATtiny85, mas o projeto foi portado para a IDE arduino e para o processador ATMega 328 por Ken Shirriff em seu blog (informações e códigos no link).

O esquema de montagem é bastante simples e eu fiz um pequeno esquema que está abaixo:


Este fim de semana me diverti bastante perturbando os amigos e o pessoal em casa, o led ir tem que ser forte, usei um de 8 mm (tirado de um controle remoto velho) para ter um alcance maior. No esquema do autor você vai ver que é sugerido o uso de transistors para controlar até uma série de leds em linha e aumentar muito o alcance.

O projeto pode ser montado com uma placa arduino UNO ou outras clones, eu resolvi montar uma arduino na breadboard pequena  para fazer um aparelho que pudesse esconder no bolso. A força vem de 3 pilhas AA ligadas diretamente na placa e colocadas em um container com liga e desliga incorporado. Não usei o botão de reset que tem no esquema acima. O bootloader foi carregado no chip usando o esquema arduino ISP.

.

TUIO E PROCESSING



Estive fazendo alguns experimentos com o processing e a biblioteca  TUIO, o tuio é um software que recnhece marcadores e tambem é usado para mesas multitoque. Para conhecer e baixar acesse http://www.tuio.org/.

No vídeo acima eu modifiquei o exemplo que vem com a biblioteca e criei um sketch com um fundo em jpg e duas imagens que são apresentadas na tela dependendo do marcador exibido na webcam.

Segue o código abaixo:

----------------------------------------------------------------------------------------
/*
    TUIO processing demo - part of the reacTIVision project
    http://reactivision.sourceforge.net/

Modificado por Miklos em 13/03/2011 - www.miklos.blog.br
*/

// we need to import the TUIO library
// and declare a TuioProcessing client variable
import TUIO.*;
TuioProcessing tuioClient;

// these are some helper variables which are used
// to create scalable graphical feedback
float cursor_size = 15;
float object_size = 120;
float table_size = 760;
float scale_factor = 1;
PFont font;
PImage bg;
PImage p0;
PImage p1;

void setup()
{
  
  size(800,600);
  bg = loadImage("fundo_teste.gif");
  p0 = loadImage("quad_teste.gif");
  p1 = loadImage("circ_teste.gif");
  
  //size(screen.width,screen.height);
 // size(640,480);
 // noStroke();
 // fill(0);
  
  loop();
  frameRate(30);
  //noLoop();
  
  hint(ENABLE_NATIVE_FONTS);
  font = createFont("Arial", 18);
  scale_factor = height/table_size;
  
  // we create an instance of the TuioProcessing client
  // since we add "this" class as an argument the TuioProcessing class expects
  // an implementation of the TUIO callback methods (see below)
  tuioClient  = new TuioProcessing(this);
}

// within the draw method we retrieve a Vector (List) of TuioObject and TuioCursor (polling)
// from the TuioProcessing client and then loop over both lists to draw the graphical feedback.
void draw()
{
  //background(255);
  background(bg);
  textFont(font,18*scale_factor);
  float obj_size = object_size*scale_factor; 
  float cur_size = cursor_size*scale_factor; 
   
  Vector tuioObjectList = tuioClient.getTuioObjects();
  for (int i=0;isize();i++) {
     TuioObject tobj = (TuioObject)tuioObjectList.elementAt(i);
      String simb = "" + tobj.getSymbolID();
     if( simb.equals("1") ){
     stroke(0);
     fill(0);
     pushMatrix();
     translate(tobj.getScreenX(width),tobj.getScreenY(height));
     rotate(tobj.getAngle());
    // rect(-obj_size/2,-obj_size/2,obj_size,obj_size);
     image(p0,-obj_size/2,-obj_size/2,obj_size,obj_size);
     popMatrix();
     fill(255);
     text(""+tobj.getSymbolID(), tobj.getScreenX(width), tobj.getScreenY(height));
     }
     if( simb.equals("2") ){
     stroke(0);
     fill(0);
     pushMatrix();
     translate(tobj.getScreenX(width),tobj.getScreenY(height));
     rotate(tobj.getAngle());
    // rect(-obj_size/2,-obj_size/2,obj_size,obj_size);
     image(p1,-obj_size/2,-obj_size/2,obj_size,obj_size);
     popMatrix();
     fill(255);
     text(""+tobj.getSymbolID(), tobj.getScreenX(width), tobj.getScreenY(height));
        } 
   }
/*  
   Vector tuioCursorList = tuioClient.getTuioCursors();
   for (int a=0;a
      TuioCursor tcur = (TuioCursor)tuioCursorList.elementAt(a);
      Vector pointList = tcur.getPath();
      
      if (pointList.size()>0) {
        stroke(0,0,255);
        TuioPoint start_point = (TuioPoint)pointList.firstElement();;
        for (int j=0;j
           TuioPoint end_point = (TuioPoint)pointList.elementAt(j);
           line(start_point.getScreenX(width),start_point.getScreenY(height),end_point.getScreenX(width),end_point.getScreenY(height));
           start_point = end_point;
        }
        
        stroke(192,192,192);
        fill(192,192,192);
        ellipse( tcur.getScreenX(width), tcur.getScreenY(height),cur_size,cur_size);
        fill(0);
        text(""+ tcur.getCursorID(),  tcur.getScreenX(width)-5,  tcur.getScreenY(height)+5);
      }
   }*/
   
}

// these callback methods are called whenever a TUIO event occurs

// called when an object is added to the scene
void addTuioObject(TuioObject tobj) {
  println("add object "+tobj.getSymbolID()+" ("+tobj.getSessionID()+") "+tobj.getX()+" "+tobj.getY()+" "+tobj.getAngle());
}

// called when an object is removed from the scene
void removeTuioObject(TuioObject tobj) {
  println("remove object "+tobj.getSymbolID()+" ("+tobj.getSessionID()+")");
}

// called when an object is moved
void updateTuioObject (TuioObject tobj) {
  println("update object "+tobj.getSymbolID()+" ("+tobj.getSessionID()+") "+tobj.getX()+" "+tobj.getY()+" "+tobj.getAngle()
          +" "+tobj.getMotionSpeed()+" "+tobj.getRotationSpeed()+" "+tobj.getMotionAccel()+" "+tobj.getRotationAccel());
}

// called when a cursor is added to the scene
void addTuioCursor(TuioCursor tcur) {
  println("add cursor "+tcur.getCursorID()+" ("+tcur.getSessionID()+ ") " +tcur.getX()+" "+tcur.getY());
}

// called when a cursor is moved
void updateTuioCursor (TuioCursor tcur) {
  println("update cursor "+tcur.getCursorID()+" ("+tcur.getSessionID()+ ") " +tcur.getX()+" "+tcur.getY()
          +" "+tcur.getMotionSpeed()+" "+tcur.getMotionAccel());
}

// called when a cursor is removed from the scene
void removeTuioCursor(TuioCursor tcur) {
  println("remove cursor "+tcur.getCursorID()+" ("+tcur.getSessionID()+")");
}

// called after each message bundle
// representing the end of an image frame
void refresh(TuioTime bundleTime) { 
  redraw();
}

-----------------------------------------------------------------------



TRICOPTERO COM WII MOTION - MULTIWII



Neste post estou iniciando as experiências com os multicópteros baseados na arduino. No vídeo acima e nas fotos está minha primeira tentativa, um tricóptero baseado na duemilenove e nos sensores do wii ( wii motion plus e nunchuck) o código é desenvolvido pela comunidade do site MultiWii e foi iniciado por Alexinparis no rcgroups.com. Foi a primeira tentativa e o primeiro acidente, vamos ver se consigo fazer ele voar de verdade...

FRAME DE MADEIRA E ALUMÍNIO




MECANISMO DE CONTROLE DE YAW





















CENTRO COM A PLACA E SENSORES


























O frame que eu fiz é bem caseiro mas estou animado pois está funcionando.... no início eu achei que era pesado e não ia voar mas como você pode ver no vídeo até levantou vôo ( e quase saiu pela janela). vou fazer novos vídeos dos testes de vôo e postar depois.

Internet of Things

LUX com arduino GPRS shield e sensor LDR.

/*
Graph: Feed 38642, Datastream lux
*/

Laboratórios, Lojas e Produtos

Blogs, Comunidades e Revistas