Show Posts
Pages: [1]
1  Using Arduino / Networking, Protocols, and Devices / Re: Arduino using GSM Siemens TC35i on: February 28, 2013, 07:37:05 am
Hi Dan,

Here's a sketch that should work for you.

Code:
/*
Arduino 1.0.1
 This sketch reads TC35 SMS to control items
 connected to the Arduino.
 
 The readTC35 and readkeyboard functions are from
 Process incoming serial data without blocking by Nick Gammon
 http://gammon.com.au/serial
 The rest of the sketch is by me
 
 Run this sketch and enter the folowing AT commands
 in the Serial Monitor to set user profile
 you only need to do this once.
 
 AT+CMGF=1          for txt mode
 AT+CNMI=2,1,0,0,1  message indication
 AT^SMGO=1          SMS full indication
 AT&W               store to memory
 
 To check what you have entered
 AT&V               display current configuration
 
 */



#include <SoftwareSerial.h>
SoftwareSerial gsmSerial(2,3);


//-------- TC35 GSM ---------------
int SMS_location_number;
const unsigned int MAX_INPUT = 165; // 160 characters for SMS plus a few extra
static unsigned int input_pos = 0;


void setup() {

  Serial.begin(9600);
  gsmSerial.begin(9600);


  //--- turn on TC35 ---
  // wire pin 8 Arduino to IGT pin on TC35
  // it grounds IGN pin for 100 ms
  // this is the same as pressing the button
  // on the TC35 to start it up

  pinMode(8, INPUT);
  digitalWrite(8, LOW);
  pinMode(8, OUTPUT);
  delay(100);
  pinMode(8, INPUT);


}//------ End setup -------

void loop() {

  readTC35();
  readKeyboard();

}//------ End loop --------

//---------------------------- Read TC35 ------------------------------------

// Read data from the TC35, When a linefeed is read the data is processed

void readTC35(){

  static char input_line [MAX_INPUT];
  //static unsigned int input_pos = 0;

  if (gsmSerial.available () > 0)
  {
    while (gsmSerial.available () > 0) {
      char inByte = gsmSerial.read ();

      switch (inByte)
      {

      case '\n':   // end of text
        input_line [input_pos] = 0;  // terminating null byte

        // terminator reached! process input_line here ...
        process_data (input_line);

        // reset buffer for next time
        input_pos = 0; 
        break;

      case '\r':   // discard carriage return
        break;

      default:
        // keep adding if not full ... allow for terminating null byte
        if (input_pos < (MAX_INPUT - 1))
          input_line [input_pos++] = inByte;
        break;

      }  // end of switch
    }  // end of while incoming data
  }  // end of if incoming data
}  // end of readTC35

//---------------------------- Read Keyboard --------------------------------

void readKeyboard(){

  static char input_line [MAX_INPUT];
  //static unsigned int input_pos = 0;

  if (Serial.available () > 0)
  {
    while (Serial.available () > 0) {
      char inByte = Serial.read ();

      switch (inByte)
      {

      case '\n':   // end of text
        input_line [input_pos] = 0;  // terminating null byte

        // terminator reached! process input_line here ...
        // if its an AT command, send it to TC35 without processing
        // ---------------- a --------------------- A -------------------- t -------------------- T --
        if(input_line[0] == 97 || input_line[0] == 65 && input_line[1] == 116 || input_line[1] == 84){
          gsmSerial.println(input_line);
        }
        else{
          process_data (input_line);
        }
        // reset buffer for next time
        input_pos = 0; 
        break;

      case '\r':   // discard carriage return
        break;

      default:
        // keep adding if not full ... allow for terminating null byte
        if (input_pos < (MAX_INPUT - 1))
          input_line [input_pos++] = inByte;
        break;

      }  // end of switch
    }  // end of while incoming data
  }  // end of if incoming data
}  // end of readKeyboard

//---------------------------- process_data --------------------------------

void process_data (char * data){

  // display the data

    Serial.println (data);

  if(strstr(data, "??")){    // If data contains ?? display the menu
    Serial.print("\r\n Keyboard Help Menu\r\n ??         This Menu\r\n readsms    List the SMS messages\r\n smsgone    Delete all SMS messages\r\n");
  }

  if(strstr(data, "+CMGR:") && strstr(data, "+448080808080")){ 
    // Reads the +CMGR line to check if SMS is from a known Phone number
    // This if statement could cover the whole of the process_data function
    // then only known a phone number could control the Arduoino
  }

  if(strstr(data, "readsms")){    // If data contains readsms
    gsmSerial.println("AT+CMGL=\"ALL\"");  // Read all SMS on the SIM
  }

  if(strstr(data, "smsgone")){
    delete_All_SMS();
  }

  if(strstr(data, "^SMGO: 2")){ // SIM card FULL
    delete_All_SMS();           // delete all SMS
  }

  if(strstr(data, "+CMTI:")){    // An SMS has arrived
    char* copy = data + 12;      // Read from position 12 until a non ASCII number to get the SMS location
    SMS_location_number = (byte) atoi(copy);  // Convert the ASCII number to an int
    gsmSerial.print("AT+CMGR=");
    gsmSerial.println(SMS_location_number);  // Print the SMS in Serial Monitor
  }                                          // this SMS data will go through this process_data function again
                                             // any true if statements will execute

  if(strstr(data, "Heating on")){              // If data contains Heating on
    Serial.println("Heating is switched ON");  // Control your syuff here
    //delete_one_SMS();  // delete the SMS if you want
  }

  if(strstr(data, "Heating off")){
    Serial.println("Heating is switched OFF");
    //delete_one_SMS();
  }

  if(strstr(data, "Lights on")){
    Serial.println("Lights are ON");
    //delete_one_SMS();
  }

  if(strstr(data, "Lights off")){
    Serial.println("Lights are OFF");
    //delete_one_SMS();
  }
}  //--------------------------- end of process_data ---------------------------

void delete_one_SMS(){
  Serial.print("deleting SMS ");
  Serial.println(SMS_location_number);
  gsmSerial.print("AT+CMGD=");
  gsmSerial.println(SMS_location_number);
}

void delete_All_SMS(){
  for(int i = 1; i <= 20; i++) {
    gsmSerial.print("AT+CMGD=");
    gsmSerial.println(i);
    Serial.print("deleting SMS ");
    Serial.println(i);
    delay(500);
  }
}

Hope this helps
2  Topics / Home Automation and Networked Objects / Re: X10 in the UK and Europe on: February 06, 2013, 05:36:48 am
With all due respect to zoomKat, He has not read the specifications of the european X10 transponder. The firecracker uses 310 MHZ and the european X10 transponder uses 433.92 MHZ. They will not talk to each other. I found this out to my cost by not reading the specs of the firecracker and buying one.

I have not found any articles on the internet about people in Europe using an Arduino with X10 (except for people not able to make them work) So I decided to learn X10 myself and help others by starting this post and freely giving the information I have learned, which is in the first thread of this post.
 
3  Topics / Home Automation and Networked Objects / Re: X10 in the UK and Europe on: December 14, 2012, 03:54:41 pm
Hello Dax

Thank you for your interest of my X10 sketch. I am using a MAX232 to TTL converter like this one
http://www.ebay.co.uk/itm/MAX232-RS232-Serial-To-TTL-Output-Converter-Board-RXD-TXD-RTS-CTS-F-PIC-Atmel-/290712442058?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item43afcfd4ca

I had to make up a new cable from my CM12 because it came with a female DB9. The RS232 to TTL converter also had a female DB9. I tried using a gender changer but it also needed a nul modem to make it work.

Here's the connections I have used.

Holding the RJ11 with the cable away from you and the locking clip on the top.
From left to right, pins are 1 2 3 4

        Signal  DB9 Connector   RJ11 Connector
        SIN       Pin 2                 Pin 3
        SOUT    Pin 3                 Pin 1
        GND     Pin 5                 Pin 4
        RI         Pin 9                 Pin 2

You don't need to use pin 9 on the DB9.        
You may need to swap the wires on pins 2 and 3 on the DB9 if it not work first time.

Im using pins 2 and 3 on my Arduino for software serial for the RS232 to TTL converter, I notice the connection website your using  has pins 0 and 1 for the MAX232



Let me know if this works for you,
Thanks.
LJRob.
 
4  Topics / Home Automation and Networked Objects / X10 in the UK and Europe on: December 07, 2012, 04:44:35 pm
Hi
Here is my sketch for X10 control. It does not use any libraries, the commands only need to be sent once and does not use the zero cross method.

The catch is the X10 controller is a CM12U. All I am doing is sending serial commands to the CM12U. I have been using X10 in my house for many years using an Apple Mini with no problems. I wanted to control my house with my Arduino.

I tried many sketches and libraries but could not get any of them to work. Then I tried reading the commands coming from my Apple Mini USB to serial and thought why not use a TTL to serial to send commands to the X10.

When the CM12U is first plugged into a socket it sends out a polling command. Unless you reply to this command it will not respond to any other X10 commands.

Code:
/*
  Arduino 1.0.1
 This sketch controls X10 modules using a TTL to RS232 and a UK CM12U X10 controller
 
 
 */


#include <SoftwareSerial.h> // For the TTL to RS232

#define A 0x60
#define B 0xE0
#define C 0x20
#define D 0xA0
#define E 0x10
#define F 0x90
#define G 0x50
#define H 0xD0
#define I 0x70
#define J 0xF0
#define K 0x30
#define L 0xB0
#define M 0x00
#define N 0x80
#define O 0x40
#define P 0xC0

#define UNIT_1 0x06
#define UNIT_2 0x0E
#define UNIT_3 0x02
#define UNIT_4 0x0A
#define UNIT_5 0x01
#define UNIT_6 0x09
#define UNIT_7 0x05
#define UNIT_8 0x0D
#define UNIT_9 0x07
#define UNIT_10 0x0F
#define UNIT_11 0x03
#define UNIT_12 0x0B
#define UNIT_13 0x00
#define UNIT_14 0x08
#define UNIT_15 0x04
#define UNIT_16 0x0C

#define ALL_UNITS_OFF 0x00
#define ALL_LIGHTS_ON 0x01
#define ON 0x02
#define OFF 0x03
#define DIM 0x04
#define BRIGHT 0x05
#define ALL_LIGHTS_OFF 0x06
#define EXTENDED_CODE 0x07
#define HAIL_REQUEST 0x08
#define HAIL_ACKNOWLEDGE 0x09
#define PRE_SET_DIM_1 0x0A
#define PRE_SET_DIM_2 0x0B
#define EXTENDED_DATA 0x0C
#define STATUS_ON 0x0D
#define STATUS_OFF 0x0E
#define STATUS_REQUEST 0x0F

#define d 600    // 600 ms to 2000 ms delay after first three bytes are sent
#define d2 20    // 20 ms delay waiting for checksum before sending the next three bytes

SoftwareSerial X10Serial(2, 3); // RX, TX to TTL RS232
              
byte incomingByte;     // from the X10 controller or the keyboard
byte Housecode_Devicecode; // for the X10Serial.write third byte
byte Housecode_Function;   // for the X10Serial.write third byte
byte luminance = 0x00;     // brightness and dim value

void setup() {

  Serial.begin(9600);
  X10Serial.begin(4800);    // X10 Baud 4800 8,NONE,1
  delay(d);    //
  PrintMenu();    // Print the menu on the screen
}

void loop() {

  CheckX10controller ();  // Check X10 controller
  CheckKeyboard();       // Check keyboard
}

// Read from X10 controller
void CheckX10controller () {

  if (X10Serial.available() > 0) {
    incomingByte = X10Serial.read();

    switch (incomingByte) {

      case ((byte)0xA5):          // Polling. This happens the first time you plug the X10 controller in the socket or after a power cut
      delay(d2);                  // wait 20 ms before sending Acknowledge
      X10Serial.write((byte)0x9B);   // Acknowledge / Clear, This must be cleared or it will not except any other x10 commands
      PowerSupplyRestored();
      break;

      case ((byte)0x5A):          // Polling. this happens after remote wireless button has been pressed.
      delay(d2);                  // wait 20 ms before sending Acknowledge
      X10Serial.write((byte)0xC3);   // Acknowledge / Clear, This must be cleared or it will not except any other x10 commands
      RFrestored();
      break;
    }
  }
}


// Read from Keyboard
void CheckKeyboard() {

  if (Serial.available() > 0) {
    incomingByte = Serial.read();

    switch (incomingByte) {

    case '?':                       // Keyboard "?"
      PrintMenu();               // Print help menu
      break;

    case '1':                     // Keyboard "1"
      X10Command(A+UNIT_1,A+ON, 0x00); // A1 ON
      break;

    case '2':                       // Keyboard "2"
      X10Command(A+UNIT_1,A+OFF, 0x00); // A1 OFF
      break;

    case '3':                     // Keyboard "3"
      X10Command(A+UNIT_2,A+ON, 0x00);  // A2 ON
      break;

    case '4':                       // Keyboard "4"
      X10Command(A+UNIT_2,A+OFF, 0x00); // A2 OFF
      break;

    case 'p':                       // Keyboard "p"
      PowerSupplyStatus();              // Check X10 Interface power supply
      break;

    case '0':                       // Keyboard "0" send all units OFF to A ... P
      for (int i = 0x00; i <= 0xF0; i += 0x08) {
        X10Function(i+ALL_UNITS_OFF,0x00);
        delay(300);
      }
      break;

    case 'b':                       // Keyboard "b" brighten lamp A2
      X10Command(A+UNIT_2, A+BRIGHT, 0x03);
      break;

    case 'd':                     // Keyboard "d" dim lamp A2
      X10Command(A+UNIT_2, A+DIM, 0x03);
      break;
    }

  }  
}

void X10Command(byte Housecode_Devicecode, byte Housecode_Function, byte luminance) {

  // first three bytes
  X10Serial.write((byte)0x04);                      // start code
  X10Serial.write((byte)Housecode_Devicecode);      // house code and device code
  delay(d2);                                        // short delay to wait for checksum from Interface
  X10Serial.write((byte)0x00);                      // Acknowledge checksum

  delay(d);                                         // long delay Interface ready

  // second three bytes
  X10Serial.write((byte)0x06 + (luminance << 3));  // start code plus bright or dim value. luminance value is shiftbit left by 3
  X10Serial.write((byte)Housecode_Function);       // house and function code. on/off dim/bright
  delay(d2);                                       // short delay to wait for checksum from Interface
  X10Serial.write((byte)0x00);                     // Acknowledge checksum
}

void X10Function(byte Housecode_Function, byte luminance) {

  // second three bytes
  X10Serial.write((byte)0x06 + (luminance << 3));  // start code plus bright or dim value. luminance value is shiftbit left by 3
  X10Serial.write((byte)Housecode_Function);       // house and function code. on/off dim/bright
  delay(d2);                                       // short delay to wait for checksum from Interface
  X10Serial.write((byte)0x00);                     // Acknowledge checksum
}

void PowerSupplyStatus() {

  X10Serial.write((byte)0xEB);                     // send Enable Ring to check power supply
  delay(20);                                       // short to wait for checksum from Interface
  if (X10Serial.read() == ((byte) 0xEB)) {         // checksum should be 0xEB
    PowerSupplyHealthy();                          // X10 controller still mains on
  }
  else {
    PowerSupplyDown();                            // X10 controller dead
  }
}

void PowerSupplyHealthy() {
  Serial.println("\nPower Supply Healthy");
}
void PowerSupplyDown() {
  Serial.println("\nPower Supply Down");
}
void PowerSupplyRestored() {
  Serial.println("\nPower Supply Restored");
}
void RFrestored() {
  Serial.println("\nRemote polling Reset");
}

void PrintMenu() {
  Serial.println("X10 Menu");
  Serial.println(
  "? Help\n"
    "1 A1 Appliance ON\n"
    "2 A1 Appliance OFF\n"
    "3 A2 Lamp ON\n"
    "4 A2 Lamp OFF\n"
    "b A2 Bright\n"
    "d A2 Dim\n"
    "0 All Units OFF A to P\n"
    "p Check Power Supply");
}
Pages: [1]