martes, 16 de octubre de 2012

Negamatik. x10 + Arduino (3) - Proccessing Server

En esta entrada escribiré el código en processing, que actuará como servidor el cual recibirá ordenes a traves de internet y se las transmitirá al arduino que tengamos conectado al puerto USB del ordenador, el cual a su vez estará conectado al módulo X10.

import processing.net.*;

String HTTP_GET_REQUEST = "GET /";
String HTTP_POST_REQUEST = "POST /";
String HTTP_HEADER = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
int NUM_MESN = 15;

Server s;
Client c;
String input;
String error="";

String [] mens = new String[NUM_MESN];
int num = 0;

void setup()
{
  size(450, 600);
  background(204);
  stroke(0);
  initMens();
  s = new Server(this, 6661); // start server on http-alt
}

void draw()
{
  background(204);
  stroke(0);
 
  // Receive data from client
  c = s.available();
  if (c != null) {
    input = c.readString();
    textSize(14);
    fill(0, 102, 153);
    text(input, 15, 60);

    String cab = "";
    if(input.indexOf("\n")>0){
      cab = input.substring(0, input.indexOf("\n"));
    }
   
    if (cab.indexOf(HTTP_GET_REQUEST) == 0) // starts with ...
    {
      c.write(HTTP_HEADER);  // answer that we're ok with the request and are gonna send html     
      // some html
      c.write("<html><head><title>Processing talkin'</title></head><body><h3>Your base are belong to us!");
      c.write("</h3></body></html>");     
      // close connection to client, otherwise it's gonna wait forever
      c.stop();
    }else if(cab.indexOf(HTTP_POST_REQUEST) == 0){
          Date d = new Date();
          long timestamp = d.getTime();
          String date = new java.text.SimpleDateFormat("HH:mm:ss dd-MM-yyyy").format(timestamp);

          c.write(HTTP_HEADER);

          String data = "";
          if(input.indexOf("STATUS")>0){
            data = input.substring(input.indexOf("STATUS"), input.length());
            data = data.substring(data.indexOf("=")+1, data.length());   
        setMens("ST: " + data + " | " + date);
            //envio arduino orden status
            c.write("OK");
         
          }else if(input.indexOf("ENCIENDE")>0){
            data = input.substring(input.indexOf("ENCIENDE"), input.length());
            data = data.substring(data.indexOf("=")+1, data.length());   
        setMens("ON:   " + data + " | " + date);
            //envio arduino orden encender + data
            c.write("OK");
          }else if(input.indexOf("APAGA")>0){
            data = input.substring(input.indexOf("APAGA"), input.length());
            data = data.substring(data.indexOf("=")+1, data.length());   
        setMens("OFF: " + data + " | " + date);
            //envio arduino orden apagar + data
            c.write("OK");
          }else{
            data = input;
            error="Ultimo error:\n" + data +  "\n| " + date;   
        setMens("ERR: POST  | " + date);
            c.write("RE");
          }
      // close connection to client, otherwise it's gonna wait forever
      c.stop();
    }
    else if (input.indexOf("message=") == 0) // starts with ...
    {
         println("aqui    nunca:" + input);
    }
    //delay(10000);
  }else{
    fill(#035BAD);
    text("waiting for you ... port 6661", 15, 30);
    printMens();
    printError();
    //println("waiting for you ... port 6661");
  }
}

void printMens(){
  for(int i = 0; i<NUM_MESN; i++){
      fill(#035BAD);
      text((i+1)+".- ", 15, 50+20*i);
     
      fill(#1B85E8);
      text(mens[i], 50, 50+20*i);
  }
}

void printError(){
  fill(160, 0, 0);
  text(error, 15, 380);
}

void initMens(){
  for(int i = 0; i<NUM_MESN; i++){
      mens[i]="";
  }
}

void setMens(String men){
  String [] tmp = mens;
 
  if(num==NUM_MESN){
     num = NUM_MESN-1;
     for(int i = 0; i<NUM_MESN-1; i++){
       mens[i]= tmp[i+1];
     }
  }
  mens[num] = men;
  num++;
}

Negamatik. x10 + Arduino (2)

Para comenzar vamos a tener que conectar el arduino al módulo bidireccional X10 por medio de un cable RJ-11. El esquema de conexión es el siguiente:


Las resistencias del ZCROSS y del RCV son de 10k cada una.

En el arduino tendremos el siguiente código, el cual recibe ordenes del pc por el interfaz Serial del USB, las procesa y se las envía al módulo X10:

/*
NegaMatik.pde

Interface serie para arduino para controlar dispositivo X10 de Marmitek.
Ordenes que recive:

. {CASA|ACCION}

. {A2|1}- //ON

. {A2|2}- //Off

. {A2|INFO}
*/
#include <x10.h>
#include <x10constants.h>

#define ZCROSS_PIN     2               // BLK pin 1 of PSC05
#define RCVE_PIN       3               // GRN pin 3 of PSC05
#define TRANS_PIN      4               // YEL pin 4 of PSC05
#define LED_PIN        13              // for testing

x10 myHouse= x10(ZCROSS_PIN,TRANS_PIN,RCVE_PIN,LED_PIN);// set up a x10 library instance:


String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

void setup() {
// initialize serial:
Serial.begin(9600);

//Serial.println("INICIO....");
// reserve 200 bytes for the inputString:
//inputString.reserve(200);
}

void loop() {
// print the string when a newline arrives:
if (stringComplete) {
  Serial.println(inputString);
  procesarOrden(inputString);
 
  // clear the string:
  inputString = "";
  stringComplete = false;
}
}

/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX.  This routine is run between each
time loop() runs, so using delay inside loop can delay
response.  Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
  // get the new byte:
  char inChar = (char)Serial.read();
  // add it to the inputString:
 
  inputString += inChar;
  // if the incoming character is a newline, set a flag
  // so the main loop can do something about it:
  if (inChar == '-') {
    stringComplete = true;
  }
}
}


void procesarOrden(String cadena){
int pos = cadena.indexOf("{");
String casaUnidad;
char accion;
char casa;
char unidad;
char unidad2;

if(pos>=0){
    int pos2 = cadena.indexOf("|");
    if(pos2>0){

       casaUnidad = cadena.substring(pos+1, pos2);
       casa = casaUnidad.charAt(0);
       unidad = casaUnidad.charAt(1);
       unidad2 = casaUnidad.charAt(2);
     
       pos = pos2;
       pos2 = cadena.indexOf("}");
       if(pos2>0){
           //Serial.println("{ACCION_OK}");
           accion = cadena.substring(pos+1, pos2).charAt(0);
           procesarOrden2(casa, unidad, unidad2, accion);
       }else{
           //Serial.println("{ERR_ACCION}");
       }

}else{

    //Serial.println("{ERR_CASA}");

}
}else{
    //Serial.println("{ERR_ORDEN}");
}

}

void procesarOrden2(char casa, char unidad, char unidad2, char accion) {
  //Serial.println(casa);
  //Serial.println(unidad);
  //Serial.println(accion);
 
  if (accion == '1') {  //ON
       //Serial.println(" on");
       myHouse.write(getHouse(casa), getUnit(unidad, unidad2), 1);
       myHouse.write(getHouse(casa), ON, 1);
     
              // on
 }else if (accion == '2') { // OFF
       //Serial.println(" off");
       myHouse.write(getHouse(casa), getUnit(unidad, unidad2), 1);
       myHouse.write(getHouse(casa), OFF, 1);
    
          // off
 }else{
   myHouse.Check_Rcvr();                       // print out the received command
   myHouse.debug();
   myHouse.reset();
   //Serial.println("hola");

 }
//devolver info


}


byte getUnit(char unidad, char unidad2){
switch(unidad){
 
  case '0':
 
  switch (unidad2) {
    case '1': return UNIT_1;
          break;
    case '2':return UNIT_2;
          break;

case '3':return UNIT_3;
          break;

case '4':return UNIT_4;
          break;

case '5':return UNIT_5;
          break;

case '6':return UNIT_6;
          break;

case '7':return UNIT_7;
          break;

case '8':return UNIT_8;
          break;

case '9':return UNIT_9;
          break;
default: return UNIT_9;
  }
 
  case '1':
  switch(unidad2){
case '0':return UNIT_10;
          break;

case '1':return UNIT_11;
          break;

case '2':return UNIT_12;
          break;

case '3':return UNIT_13;
          break;

case '4':return UNIT_14;
          break;

case '5':return UNIT_15;
          break;

case '6':return UNIT_16;
          break;
    default: return UNIT_16;
 }
 default: return UNIT_16;
}
}


byte getHouse(char casa){
switch (casa) {

case 'A': return HOUSE_A;
            break;
    case 'B': return HOUSE_B;
            break;

case 'C': return HOUSE_C;
            break;

case 'D': return HOUSE_D;
            break;

case 'E': return HOUSE_E;
            break;

case 'F': return HOUSE_F;
            break;

case 'G': return HOUSE_G;
            break;

case 'H': return HOUSE_H;
            break;

case 'I': return HOUSE_I;
            break;

case 'J': return HOUSE_J;
            break;

case 'K': return HOUSE_K;
            break;

case 'L': return HOUSE_L;
            break;

case 'M': return HOUSE_M;
            break;

case 'N': return HOUSE_N;
            break;

case 'O': return HOUSE_O;
            break;

case 'P': return HOUSE_P;
            break;
    default: return HOUSE_K;
 }
}



Continúa aqui...

martes, 7 de agosto de 2012

Negamatik. x10 + Arduino (1)

En este proyecto voy a realizar un sistema domótico para encender la calefacción de mi casa y una luz.

Para la realización del proyecto he optado por la utilización de un modulo bidireccional X10 de Marmitek, y modulos de aparato y casquillo para conectar la calefacción y una bombilla. Gracias a esta implementación, me ahorro cualquier tipo de obra en mi casa, ya que estos se comunican a traves del cable de corriente de casa.

También utilizaré un Arduino para comunicarme con el modulo bidireccional y con el cliente final, que será una página web accesible tanto desde la propia LAN, como a traves de internet, para un completo control de los aparatos cuando no se esté en casa.

Para la primera versión de este proyecto, el Arduino estará conectado a un PC por cable USB, y en el PC correrá un servidor HTTP escrito en Processing para la comunicación con internet.

En una siguiente versión, utilizaré el modulo ethernet de arduino, y así eliminaré el PC de la ecuación. Con lo que quedará un sistema completamente autónomo y sin necesidad de que haya un ordenador de por medio. Tan solo tendría que estar conectado a un router y a la linea eléctrica para funcionar.



continua aqui

lunes, 5 de diciembre de 2011

Proyector Laser DIY v1

Materiales:
  • un laser rojo de 5mw
 (http://www.dealextreme.com/p/red-laser-module-focused-dot-3-5v-4-5v-9mm-5mw-5900)
  • 2 motores pap unipolares a 12V
(http://www.riabelectronics.cl/motor-paso-a-paso-de-alta- calidad-12v.html)

El laser lo conecto a un pin digital del arduino como si se tratase de
un led

Para conectar los motores al arduino, utilizo dos chip ULN2003A.
Conectándolo al arduino por el metodo de los 4 cables.
(http://www.arduino.cc/en/Tutorial/StepperUnipolar)



He utilizado la libreria Stepper, y los motores los he configurado a
una velocidad de 9 vueltas por minuto (lentorro) y 2039 pasos por
vuelta. Todo esto a ojo. Modificandolo por el método de prueba-
error...

Si los pongo a mas velocidad, los motores empiezan a dar pasos de
mas o de menos.

Le he añadido un joystick de los de playstation (http://www.seeedstudio.com/depot/electronic-brick-playstation2-analog-joystickanalog-p-468.html?cPath=190) para colocar los espejos en la posicion inicial indicada, y cuando aprieto el botón, que dibuje un dibujo preestablecido. Un cuadrado, un
triangulo... en este caso fué una especie de corazón que está dibujado en papel en la siguiente foto en la esquina.








Para dibujar he hecho una función que le vas pasando punto inicial y
punto final, y te dibuja la recta entre los dos puntos.Implementando el algoritmo de Bresenham.

 #include <Stepper.h>

#define STEPS 2039
#define ledPin 2  //LASER

Stepper stepper1(STEPS, 8, 9, 10, 11);
Stepper stepper2(STEPS, 4, 3, 5, 6);

const int buttonPin = 12;
int buttonState = 0;

int posX = 0;
int posY = 0;

void setup()
{
  Serial.begin(9600);
  // set the speed of the motor to 30 RPMs
  stepper1.setSpeed(9);
  stepper2.setSpeed(9);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
 
  digitalWrite(ledPin, HIGH);
}

void loop()
{
   buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {
    corazon();
  }
 
  digitalWrite(ledPin, HIGH);
  // get the sensor value
  int val = analogRead(0);

  if(val>850){
    moverMotor1i();
  }else if(val < 190){
    moverMotor1();
  }
  
  int val2 = analogRead(1);
  Serial.println(val2);
  if(val2>950){
    moverMotor2();
  }else if(val2 < 100){
    moverMotor2i();
  }
}

void corazon(){
  posX = 0;
  posY = 0;
  dibujaLinea(8, 4);
  dibujaLinea(12, 12);
  dibujaLinea(8, 20);
  dibujaLinea(5, 15);
  dibujaLinea(3, 15);
 
  dibujaLinea(0, 9);
  dibujaLinea(0, 7);
  dibujaLinea(0, 9);
 
  dibujaLinea(-3, 15);
  dibujaLinea(-5, 15);
  dibujaLinea(-8, 20);
  dibujaLinea(-12, 12);
  dibujaLinea(-8, 4);
  dibujaLinea(0, 0);
}

void dibujaLinea(int x1, int y1){
  bresenham(posX, posY, x1, y1);
  posX = x1;
  posY = y1;
}

void bresenham(int x0, int y0, int x1, int y1){
  int x;
  int y;
  int dx;
  int dy;
  int p;
  int incE;
  int incNE;
  int stepx;
  int stepy;
  int nStepX;
  int nStepY;
 
  nStepX = 0;
  nStepY = 0;
 
  dx = (x1 - x0);
  dy = (y1 - y0);
/* determinar que punto usar para empezar, cual para terminar */
  if (dy < 0) {
    dy = -dy;
    stepy = -1;
  } else{
    stepy = 1;
  }
 
  if (dx < 0) {
    dx = -dx;
    stepx = -1;
  }
  else {
    stepx = 1;
  }
  x = x0;
  y = y0;
 
  //g.drawLine( x0, y0, x0, y0);
/* se cicla hasta llegar al extremo de la línea */
 
  if(dx>dy){
    p = 2*dy - dx;
    incE = 2*dy;
    incNE = 2*(dy-dx);
    while (x != x1){
      x = x + stepx;
      stepper1.step(stepx);
      nStepX = nStepX + stepx;
      if (p < 0){
        p = p + incE;
      }
      else {
        y = y + stepy;
        stepper2.step(stepy);
      nStepY = nStepY + stepy;
        p = p + incNE;
      }
      //g.drawLine( x0, y0, x0, y0);
    }
  }
  else{
    p = 2*dx - dy;
    incE = 2*dx;
    incNE = 2*(dx-dy);
    while (y != y1){
      y = y + stepy;
      stepper2.step(stepy);
      nStepY = nStepY + stepy;
    
      if (p < 0){
        p = p + incE;
      }
      else {
        x = x + stepx;
        stepper1.step(stepx);
        nStepX = nStepX + stepx;
        p = p + incNE;
      }
      //g.drawLine( x0, y0, x0, y0);
    }
  }
}






No dejeis de visitar http://www.negadeth.es