Difference between revisions of "Implementing Arduino using Generic Serial Device"

From LinuxMCE
Jump to: navigation, search
(Arduino Uno Setup)
(Arduino Uno Setup)
Line 100: Line 100:
 
Shopping list:
 
Shopping list:
  
Arduino Uno
+
* Arduino Uno
 +
* Ethernet Shield
 +
* LED
 +
* Resistors
 +
* Breadboard and some wires
 +
* IDE installed on computer
  
Ethernet Shield
 
  
LED
 
  
Resistors
+
'''Sketch for Arduino'''
  
IDE installed on computer
+
<var>
 +
/*
  
Sketch to upload to Arduino;
+
  arduino_control_by_lmce.ino:
  
<var>
+
This sketch sends and receive TCP message strings to LinuxMCE.
/*
+
 
  * Arduino LMCE interlink
+
*/
  *
+
 
  * A basic example displaying the ability of LinuxMCE
+
//*****************************************************************
  * to control an LED on an Arduino with
+
 
  * an ethernet shield.
+
//*with ethernet shield DON'T USE this pin: 10, 11, 12, 13 *
  *  
+
 
  * Daballiemo
+
//*****************************************************************
  * http://linuxmce.org
+
 
  */
+
#include <math.h>
#include <SPI.h>
+
#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
+
#include <Ethernet.h>
int switchPin = 2;
+
 
int LEDpin = 5; //LED set to pin 5
+
 
int x;
+
double Thermister(int RawADC); //function to read temperature from a thermister.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //must give WIZnet a MAC
+
 
byte ip[] = { 192, 168, 80, 129 }; //must configure WIZnet IP
+
 
EthernetServer server = EthernetServer(69); //TCP port the server is listening on, I'm using port 69, but you could use any
+
// Enter a MAC address and IP address for your controller below.
void setup()
+
// The IP address will be dependent on your local network:
{
+
 
   Ethernet.begin(mac, ip);
+
byte mac[] = {
 +
  0x90, 0xA2, 0xDA, 0x00, 0x58, 0x27 };
 +
byte ip[] = {
 +
  192,168,80,129};
 +
byte gateway[] = {
 +
  192,168,80,1 };
 +
byte subnet[] = {
 +
  255,255,255,0 };
 +
 
 +
unsigned int localPort = 69;     // local port to listen on
 +
 
 +
// buffers for receiving and sending data
 +
 
 +
char packetBuffer[1024]; //buffer to hold incoming commandpacket,
 +
EthernetServer server(69);
 +
 
 +
 
 +
void setup() {
 +
 
 +
  Serial.begin(9600);
 +
  Serial.println("Starting LinuxMCE sketch...");
 +
 
 +
  // start the Ethernet
 +
 
 +
   Ethernet.begin(mac, ip,gateway, subnet);
 
   server.begin();
 
   server.begin();
   Serial.begin(9600); //for troubleshooting purposes (not needed)
+
 
  pinMode(LEDpin, OUTPUT);
+
   //port setting:
  pinMode(switchPin, INPUT);                                   // sets the digital pin as input to read switch
+
 
}
+
  pinMode (5, OUTPUT);
void loop () {
+
//  pinMode (6, OUTPUT);
EthernetClient client = server.available(); //client connects to server
+
//  pinMode (8, OUTPUT);
if (client){ //if connection present
+
 
  x = client.read(); //read information coming from server
+
}
   Serial.println(x);} //print to serial (troublshooting only)
+
 
if (x == 49){ //if information sent is a zero
+
 
  digitalWrite(LEDpin, LOW);} //turn of LED
+
// variables uses to change the value of analogWrite function.
else if (x == 48){ //if information sent is a one
+
 
  digitalWrite(LEDpin, HIGH);}         //turn on LED
+
int dim = 0;
else if (x == 2){ //if information sent is a two
+
int dim_pin = 0;
  digitalWrite(LEDpin, HIGH); //blink the LED
+
 
  delay(500);
+
 
  digitalWrite(LEDpin, LOW);
+
void loop() {
  delay(500);}
+
 
if (digitalRead(switchPin) == 1){
+
 
  Serial.println("Button has been pressed " );
+
  bool send_cmd = false; //is true when i send a command.
  server.write("Button has been pressed ");}                    // Read the pin and display the value
+
 
}
+
  // if there's commanddata available, read a packet
 +
 
 +
  EthernetClient client = server.available();
 +
  int packetSize = 0;
 +
  if (client)
 +
  {
 +
 
 +
    if (client.connected()) {
 +
      while (client.available()) {
 +
        packetBuffer[packetSize] = client.read();
 +
        packetSize++;
 +
        packetBuffer[packetSize] = '\0';
 +
      }
 +
 
 +
      Serial.print("Contents: ");
 +
      Serial.print(packetBuffer);
 +
      Serial.print("   Buffersize: ");
 +
      Serial.println(packetSize);
 +
 
 +
      //if you receive a command that start with 'P' it means that you received a boolean value:
 +
      //LinuxMCE sends "Pon-x" or "Poff-x". The first turn on a pin
 +
      //(in this case: pin x), or make "true" a variable. The second just turn off the pin x.
 +
 
 +
 
 +
      if (packetBuffer[0] == 'P' ) {
 +
        char led_state_char[4];    //contains 'on' or 'off'
 +
        char pin_char[4]; // the pin number
 +
        int inCount = 0;
 +
        int var = 0;
 +
        int inCount_led_state_char;
 +
        int inCount_pin_char;
 +
 
 +
        for (int i = 1; i <  packetSize; i++)
 +
        {
 +
          if (packetBuffer[i] == '-') {
 +
            var++;
 +
            inCount = 0;     
 +
          }
 +
 
 +
          if (var == 0 && packetBuffer[i] != '-') {
 +
            led_state_char[inCount] = packetBuffer[i];
 +
            inCount++;
 +
            inCount_led_state_char = inCount;
 +
          }
 +
 
 +
          if (var == 1 && packetBuffer[i] != '-') {
 +
            pin_char[inCount] = packetBuffer[i];
 +
            inCount++;
 +
            inCount_pin_char = inCount;
 +
          }
 +
 
 +
          led_state_char[inCount_led_state_char] = '\0';
 +
          pin_char[inCount_pin_char] = '\0';
 +
        }
 +
        Serial.println(pin_char);
 +
 
 +
 
 +
        int pin = atoi(pin_char); //our pin number
 +
        Serial.print("pin: ");
 +
        Serial.print(pin);
 +
 
 +
 
 +
        if (strcmp(led_state_char,"on") == 0) { //if we send 'Pon-x'
 +
          Serial.println("    Status is ON");
 +
          char led_state_send[10] = "Pon-";
 +
          strcat(led_state_send, pin_char);
 +
          Serial.println(led_state_send);
 +
          client.print(led_state_send); //send a string to LMCE: "Pon-x"
 +
          digitalWrite(pin, HIGH); //turn on the pin 7
 +
        }
 +
 
 +
        if (strcmp(led_state_char,"off") == 0) { //if we send 'Poff-x'
 +
          Serial.println("    Status is OFF");
 +
          char led_state_send[10] = "Poff-";
 +
          strcat(led_state_send, pin_char);
 +
          Serial.println(led_state_send);
 +
          client.print( led_state_send); //send a string to LMCE: "Poff-x";
 +
          digitalWrite(pin, LOW);
 +
        }
 +
 
 +
        //int dim = packetBuffer[0];
 +
 
 +
        send_cmd = true; //we have read a command
 +
 
 +
      }
 +
 
 +
 
 +
 
 +
      //if we receive a command that start with 'D' it means that you have chosen a dim level in LMCE
 +
      //the string that we send is like : "D9-55" and it's means: 'd' is use for "dim", "9" is the pin that
 +
      //we want change dim, "55" is the dim value. LMCE range is from "0" to "100". The conversion 0-100 into 0-255 is done in this sketch
 +
      //we can use this dim to change directly the value to use in AnalogWrite,
 +
      //or to do something else.
 +
 
 +
      if (packetBuffer[0] == 'D') {
 +
        char dim_char[10];
 +
        char dim_pin_char[10];
 +
        int inCount = 0;
 +
        int var = 0;
 +
        int inCount_dim_pin_char;
 +
        int inCount_dim_char;
 +
 
 +
        for (int i = 1; i <  packetSize; i++)
 +
        {
 +
          //Serial.println(packetBuffer[i]);
 +
          if (packetBuffer[i] == '-') {
 +
            var++;
 +
            inCount = 0;     
 +
          }
 +
 
 +
          if (var == 0 && packetBuffer[i] != '-') {
 +
            dim_pin_char[inCount] = packetBuffer[i];
 +
            inCount++;
 +
            inCount_dim_pin_char = inCount;
 +
          }
 +
 
 +
          if (var == 1 && packetBuffer[i] != '-') {
 +
            dim_char[inCount] = packetBuffer[i];
 +
            inCount++;
 +
            inCount_dim_char = inCount;
 +
          }
 +
 
 +
          dim_pin_char[inCount_dim_pin_char] = '\0';
 +
          dim_char[inCount_dim_char] = '\0';
 +
        }
 +
 
 +
 
 +
        //Serial.println(dim_char);
 +
 
 +
        dim = atoi(dim_char); //here we have the dim number: 0-255
 +
        dim = dim * 2.55;
 +
        dim_pin = atoi(dim_pin_char); //and here the pin number
 +
 
 +
        Serial.println("dim pin: ");
 +
 
 +
        Serial.println(dim_pin);
 +
 
 +
        //int dim = packetBuffer[0];
 +
 
 +
        Serial.println("dim: ");
 +
 
 +
        Serial.println(dim);
 +
 
 +
        char dim_state_send[10] = "D";
 +
 
 +
        strcat(dim_state_send, dim_pin_char);
 +
 
 +
        strcat(dim_state_send, "-");
 +
 
 +
        strcat(dim_state_send, dim_char);
 +
 
 +
        Serial.println(dim_state_send);
 +
 
 +
        client.print( dim_state_send); //here return the made action.
 +
 
 +
        send_cmd = true;
 +
 
 +
        analogWrite(dim_pin, dim); //here we change the dim of the selected pin
 +
 
 +
      }
 +
 
 +
 
 +
 
  
 
</var>
 
</var>

Revision as of 14:56, 9 September 2012

Version Status Date Updated Updated By
710 Unknown N/A N/A
810 Unknown N/A N/A
1004 In Progress 3th September 2012 Daballiem0
1204 Unknown N/A N/A
1404 Unknown N/A N/A
Usage Information

General Info (Information not valid yet)

Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software. It's intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments.

Arduino can sense the environment by receiving input from a variety of sensors and can affect its surroundings by controlling lights, motors, and other actuators. The microcontroller on the board is programmed using the Arduino programming language (based on Wiring) and the Arduino development environment (based on Processing). Arduino projects can be stand-alone or they can communicate with software running on a computer (e.g. Flash, Processing, MaxMSP).

Arduino uno test.jpg

Setting up Arduino Uno and LinuxMCE to be able to control a RGB LED string

In the following I want to give an overview what needs to be done to have LinuxMCE control a RGB LED (string) through an Arduino. The string is within brackets as the only added to the Arduino to be able to control a ledstring is some mosfets and a powerblock.

Setting up Linuxmce

For now define Arduino as a vendor via Advanced -> Device Templates. Select the "Add Manufacturer" button and provide "Arduino" as manufacturer followed by save and close.

Define a new template for the Arduino Uno (which I am using atm)

Advanced -> Device Templates, selected "Add device template". Name the template "Arduino Uno", select Implements DCE, Device Category is "Interfaces - Specialized #97". Specify that your device is controlled via category "Device Category:Core" ("Computers - Core"). Otherwise the driver will not be started on the core. As I am using an Ethernet shield select "Is IP based", set "Comm Method" to Ethernet and under "Device data" add #69 TCP Port (int). Give the TCP Port the value "69", set it to required and allowed to modify.

Now set up the rest of the template according to http://wiki.linuxmce.org/index.php/How_to_add_your_own_GSD_device

#384 Process Receive Command For Child

cmdId = cmd.id_ # Command ID: ON, OFF, SET LEVEL
cmdTo = cmd.devidto_ # Device ID in LinuxMCE
devPort = device_.childdevices_[cmdTo].devdata_[12] # 12 contains a port/channel
childType = device_.childdevices_[cmdTo].devtemplid_ # Template ID to know type of device: switch or dimmer

deviceID = device_.childdevices_[cmd.devidto_].devdata_[12]

command = [0,0,0,0,0,0] # define command array

command [0] = ''                                  # Parameter
command [1] = ''                                  # Parameter
command [2] = ''                           	  # Parameter
command [3] = ''                                  # Parameter
command [4] = ''                                  # Parameter
command [5] = ''                                  # Parameter
command [6] = ''                                  # Parameter    

log ('logging from #384');
log ('Device ID');
log cmdTo;
log ('Port used');
log command[2];
log ('Command given');                             # orginal command from LMCE
log cmdId;
log ('Device Template');                           # Template ID ie switch, dimmer or RGB
log childType;
log ('Level');
log cmd.params_[76];                               # The level to set, as a value between 0 (off) and 100 (full).
                                                   # It can be preceeded with a - or + indicating a relative value.  +20 means up 20%.


case cmdId

when 192                                           # 192 is the 'ON' command
command [0] = 'P'                                  # Start indication is P (Power)
command [1] = 'on-'                                # '1' indicating 'ON'  
command [2] = deviceID                             # Port number defined in LMCE

when 193                                           # 193 is the 'OFF' command
command [0] = 'P'                                  # Start indication is P (Power)
command [1] = 'off-'                               # '1' indicating 'OFF'  
command [2] = deviceID                             # Port number defined in LMCE

when 184                                           # 184 is Level of dimmer
command [0] = 'D'                                  # indicate level command
command [1] = deviceID                             # Port number defined in LMCE
command [2] = '-'
command [3] = cmd.params_[76]                      # is level coming from LMCE

when 980                                           # 980 is color scenario command (template 1993)
command [3] = '3'                                  # indicate RGB command
command [4] = cmd.params_[279]                     # red level
command [5] = cmd.params_[280]                     # green level
command [6] = cmd.params_[281]                     # blue level
end


commandstring = command.to_s                       # wrap the command array into a string
log ('Sending');                                   # log that we are sending
log commandstring;                                 # put in logfile what we send
conn_.Send commandstring                           # send if off

Arduino Uno Setup

Arduino Uno shopping list

Shopping list:

  • Arduino Uno
  • Ethernet Shield
  • LED
  • Resistors
  • Breadboard and some wires
  • IDE installed on computer


Sketch for Arduino

/*

 arduino_control_by_lmce.ino:

This sketch sends and receive TCP message strings to LinuxMCE.

  • /

//*****************************************************************

//*with ethernet shield DON'T USE this pin: 10, 11, 12, 13 *

//*****************************************************************

  1. include <math.h>
  2. include <SPI.h> // needed for Arduino versions later than 0018
  3. include <Ethernet.h>


double Thermister(int RawADC); //function to read temperature from a thermister.


// Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network:

byte mac[] = {

 0x90, 0xA2, 0xDA, 0x00, 0x58, 0x27 };

byte ip[] = {

 192,168,80,129};

byte gateway[] = {

 192,168,80,1 };

byte subnet[] = {

 255,255,255,0 };

unsigned int localPort = 69; // local port to listen on

// buffers for receiving and sending data

char packetBuffer[1024]; //buffer to hold incoming commandpacket, EthernetServer server(69);


void setup() {

 Serial.begin(9600);
 Serial.println("Starting LinuxMCE sketch...");
 // start the Ethernet
 Ethernet.begin(mac, ip,gateway, subnet);
 server.begin();
 //port setting:
 pinMode (5, OUTPUT);

// pinMode (6, OUTPUT); // pinMode (8, OUTPUT);

}


// variables uses to change the value of analogWrite function.

int dim = 0; int dim_pin = 0;


void loop() {


 bool send_cmd = false; //is true when i send a command.
 // if there's commanddata available, read a packet
 EthernetClient client = server.available();
 int packetSize = 0;
 if (client)
 {
   if (client.connected()) {
     while (client.available()) {
       packetBuffer[packetSize] = client.read();
       packetSize++;
       packetBuffer[packetSize] = '\0';
     }
     Serial.print("Contents: ");
     Serial.print(packetBuffer);
     Serial.print("   Buffersize: ");
     Serial.println(packetSize);
     //if you receive a command that start with 'P' it means that you received a boolean value:
     //LinuxMCE sends "Pon-x" or "Poff-x". The first turn on a pin
     //(in this case: pin x), or make "true" a variable. The second just turn off the pin x.


     if (packetBuffer[0] == 'P' ) {
       char led_state_char[4];     //contains 'on' or 'off'
       char pin_char[4]; // the pin number
       int inCount = 0;
       int var = 0;
       int inCount_led_state_char;
       int inCount_pin_char;
       for (int i = 1; i <  packetSize; i++)
       {
         if (packetBuffer[i] == '-') {
           var++;
           inCount = 0;       
         }
         if (var == 0 && packetBuffer[i] != '-') {
           led_state_char[inCount] = packetBuffer[i];
           inCount++;
           inCount_led_state_char = inCount;
         }
         if (var == 1 && packetBuffer[i] != '-') {
           pin_char[inCount] = packetBuffer[i];
           inCount++;
           inCount_pin_char = inCount;
         }
         led_state_char[inCount_led_state_char] = '\0';
         pin_char[inCount_pin_char] = '\0';
       }
       Serial.println(pin_char);


       int pin = atoi(pin_char); //our pin number
       Serial.print("pin: ");
       Serial.print(pin);


       if (strcmp(led_state_char,"on") == 0) { //if we send 'Pon-x'
         Serial.println("    Status is ON");
         char led_state_send[10] = "Pon-";
         strcat(led_state_send, pin_char);
         Serial.println(led_state_send);
         client.print(led_state_send); //send a string to LMCE: "Pon-x"
         digitalWrite(pin, HIGH); //turn on the pin 7
       }
       if (strcmp(led_state_char,"off") == 0) { //if we send 'Poff-x'
         Serial.println("    Status is OFF");
         char led_state_send[10] = "Poff-";
         strcat(led_state_send, pin_char);
         Serial.println(led_state_send);
         client.print( led_state_send); //send a string to LMCE: "Poff-x";
         digitalWrite(pin, LOW);
       }
       //int dim = packetBuffer[0];
       send_cmd = true; //we have read a command
     }


     //if we receive a command that start with 'D' it means that you have chosen a dim level in LMCE
     //the string that we send is like : "D9-55" and it's means: 'd' is use for "dim", "9" is the pin that
     //we want change dim, "55" is the dim value. LMCE range is from "0" to "100". The conversion 0-100 into 0-255 is done in this sketch
     //we can use this dim to change directly the value to use in AnalogWrite,
     //or to do something else.
     if (packetBuffer[0] == 'D') {
       char dim_char[10];
       char dim_pin_char[10];
       int inCount = 0;
       int var = 0;
       int inCount_dim_pin_char;
       int inCount_dim_char;
       for (int i = 1; i <  packetSize; i++)
       {
         //Serial.println(packetBuffer[i]);
         if (packetBuffer[i] == '-') {
           var++;
           inCount = 0;       
         }
         if (var == 0 && packetBuffer[i] != '-') {
           dim_pin_char[inCount] = packetBuffer[i];
           inCount++;
           inCount_dim_pin_char = inCount;
         }
         if (var == 1 && packetBuffer[i] != '-') {
           dim_char[inCount] = packetBuffer[i];
           inCount++;
           inCount_dim_char = inCount;
         }
         dim_pin_char[inCount_dim_pin_char] = '\0';
         dim_char[inCount_dim_char] = '\0';
       }


       //Serial.println(dim_char);
       dim = atoi(dim_char); //here we have the dim number: 0-255
       dim = dim * 2.55;
       dim_pin = atoi(dim_pin_char); //and here the pin number
       Serial.println("dim pin: ");
       Serial.println(dim_pin);
       //int dim = packetBuffer[0];
       Serial.println("dim: ");
       Serial.println(dim);
       char dim_state_send[10] = "D";
       strcat(dim_state_send, dim_pin_char);
       strcat(dim_state_send, "-");
       strcat(dim_state_send, dim_char);
       Serial.println(dim_state_send);
       client.print( dim_state_send); //here return the made action.
       send_cmd = true;
       analogWrite(dim_pin, dim); //here we change the dim of the selected pin
     }