Arduino + Souliss + 4*4 keypad

Terve taas

Onko tÀÀllÀ kukaan tutustunut Soulikseen? http://www.souliss.net/

Olen jo useamman vuoden rakennellut ja parannellut kÀmpÀn valaistuksen ohjauksia.
Aikaisemmin oli valaistusta ohjaamassa arduino ja jokaisessa huoneessa 4*4 keypadi minkÀ painalluksia arduino tulkitsi ja sitÀ mukaa availi releitÀ.

Mielenkiinto herÀsi kun netissÀ tuli vastaan tuo souliss joka siis asennetaan andoidi vekottimeen ja puhelin juttelee arduinolle esim. ethernetin kautta.
Vaikuttaisi siltÀ ettÀ siitÀ saisi jalostettua aika hyvÀn ohjauksen kotiautomaatioihin, mutta taidot loppuvat kesken kun ei ohjelmointi ole kovin hyvin hallussa.
TÀhÀn saakka olen kaikki ohjelmoinnit hoitanut niin ettÀ olen etsinyt valmiit koodit, muutellut ja testaillut ne itselle sopiviksi joten koodit voivat olla hieman hölmösti tehtyjÀ.

Isoksi ongelmaksi on muodostumassa se ettÀ pitÀisi saada tuo keypadi ja souliss toimimaan ns. rinnakkain.
Soulisissa on valmiita esimerkkejÀ mitÀ muokkaamalla sain androidilla ohjattua 16 relettÀ ja RGB-nauhojen vÀrejÀ.

Ongelma on siinÀ ettÀ kun androidi-kÀnnykÀllÀ avaan releen se on auki niin kauan kun se taas androidista kytketÀÀn pois pÀÀltÀ.

Sama juttu tuossa arduino + keypad yhdistelmÀssÀ, painan keypadista nappulaa niin rele on niin kauan auki kun taas painan nappulaa uudelleen.

NÀmÀ kaksi laitteistoa pitÀisi saada jotenkin toimimaan niin ettÀ kun esim. kÀnnykÀllÀ laitan soulisin kautta makuuhuoneeseen valon pÀÀlle sen saisi sammutettua myös makuuhuoneen seinÀssÀ olevasta keypadin painikkeesta.

Laitteistona
Arduino mega + ethernet shield
Arduino mega + 4*4 keypad

Souliss code:

[code]/**************************************************************************
Souliss - Light with PIR Sensor

This example handle two lights as previous example but add an external
event (like a PIR sensor) to time-on the light in the active state.

If the device is set in AUTO mode, the external event drive the output
state, is always possible to control manually the light.    

Run this code on one of the following boards:
  - Arduino Ethernet (W5100) 
  - Arduino with Ethernet Shield (W5100)
  
As option you can run the same code on the following, just changing the
relevant configuration file at begin of the sketch
  - Arduino with ENC28J60 Ethernet Shield
  - Arduino with W5200 Ethernet Shield
  - Arduino with W5500 Ethernet Shield

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

// Configure the framework
#include “bconf/StandardArduino.h” // Use a standard Arduino
#include “conf/ethW5100.h” // Ethernet through Wiznet W5100
#include “conf/Gateway.h” // The main node is the Gateway, we have just one node
#include “conf/Webhook.h” // Enable DHCP and DNS

// Include framework code and libraries
#include <SPI.h>
#include “Souliss.h”

#define MYLIGHT 0 // This identify the number of the logic on this node
#define PEERLIGHT 0 // This identify the number of the logic on peer node

#define LEDCONTROL 0 // This is the memory slot for the logic that handle the light
#define LEDRED 1 // This is the memory slot for the logic that handle the light
#define LEDGREEN 2 // This is the memory slot for the logic that handle the light
#define LEDBLUE 3 // This is the memory slot for the logic that handle the light

#define LIGHT1_NODE1 4
#define LIGHT2_NODE1 5
#define LIGHT3_NODE1 6
#define LIGHT4_NODE1 7
#define LIGHT5_NODE1 8
#define LIGHT6_NODE1 9
#define LIGHT7_NODE1 10
#define LIGHT8_NODE1 11

#define LIGHT9_NODE1 12
#define LIGHT10_NODE1 13
#define LIGHT11_NODE1 14
#define LIGHT12_NODE1 15
#define LIGHT13_NODE1 16
#define LIGHT14_NODE1 17
#define LIGHT15_NODE1 18
#define LIGHT16_NODE1 19

#define LIGHT_ON_CYCLE 20 // Light ON for 10 cycles if triggered by a PIR sensor

void setup()
{
Initialize();

// Get the IP address from DHCP
GetIPAddress();                          
SetAsGateway(myvNet_dhcp);       // Set this node as gateway for SoulissApp  

// Set the typical logic to handle the lights
Set_AutoLight(LIGHT1_NODE1);
Set_AutoLight(LIGHT2_NODE1);
Set_AutoLight(LIGHT3_NODE1);
Set_AutoLight(LIGHT4_NODE1);
Set_AutoLight(LIGHT5_NODE1);
Set_AutoLight(LIGHT6_NODE1);
Set_AutoLight(LIGHT7_NODE1);
Set_AutoLight(LIGHT8_NODE1);

Set_AutoLight(LIGHT9_NODE1);
Set_AutoLight(LIGHT10_NODE1);
Set_AutoLight(LIGHT11_NODE1);
Set_AutoLight(LIGHT12_NODE1);
Set_AutoLight(LIGHT13_NODE1);
Set_AutoLight(LIGHT14_NODE1);
Set_AutoLight(LIGHT15_NODE1);
Set_AutoLight(LIGHT16_NODE1);    


Set_LED_Strip(LEDCONTROL);                  // Set a logic to control a LED strip

// Define inputs, outputs pins

pinMode(30, OUTPUT);                 // Power to relay Parveke
pinMode(32, OUTPUT);                 // Power to relay Keittiön alatasot
pinMode(34, OUTPUT);                 // Power to relay Keittiön alatasot
pinMode(36, OUTPUT);                 // Power to relay Keittiön alatasot
pinMode(38, OUTPUT);                 // Power to relay Keittiön alatasot
pinMode(40, OUTPUT);                 // Power to relay Keittiön alatasot
pinMode(50, OUTPUT);                 // Power to relay Keittiön alatasot
pinMode(44, OUTPUT);                 // Power to relay Keittiön alatasot




pinMode(33, OUTPUT);                 // Power to relay Makkarin vaatekaapit white
pinMode(35, OUTPUT);                 // Power to relay Olohuone vitriinit RGB
pinMode(37, OUTPUT);                 // Power to relay Olohuone vitriinit RGB

pinMode(39, OUTPUT);                 // Power to relay Olohuone verhokotelo RGB
pinMode(41, OUTPUT);                 // Power to relay Keittiö ylÀtaso RGB

pinMode(43, OUTPUT);                 // Power to relay Keittiö ylÀtaso RGB
pinMode(45, OUTPUT);                 // Power to relay Keittiö ylÀtaso RGB
pinMode(47, OUTPUT);                 // Power to relay Keittiö ylÀtaso RGB





pinMode(2, INPUT_PULLUP);                  // Hardware pulldown required
pinMode(3, OUTPUT);                 // Power the LED
pinMode(5, OUTPUT);                 // Power the LED
pinMode(6, OUTPUT);                 // Power the LED

}

void loop()
{
// Here we start to play
EXECUTEFAST() {
UPDATEFAST();

    // Execute the code every 3 time_base_fast      
    FAST_90ms() {
    
        // Use Pin2 and Pin 3 as ON/OFF command
        DigIn(22, LIGHT_ON_CYCLE, LIGHT1_NODE1); 
        DigIn(24, LIGHT_ON_CYCLE, LIGHT2_NODE1);

        
        // Execute the logic
        Logic_AutoLight(LIGHT1_NODE1);
        Logic_AutoLight(LIGHT2_NODE1);
        
        Logic_AutoLight(LIGHT3_NODE1);
        Logic_AutoLight(LIGHT4_NODE1);
        Logic_AutoLight(LIGHT5_NODE1);
        Logic_AutoLight(LIGHT6_NODE1);
        Logic_AutoLight(LIGHT7_NODE1);
        Logic_AutoLight(LIGHT8_NODE1);
        
        Logic_AutoLight(LIGHT9_NODE1);
        Logic_AutoLight(LIGHT10_NODE1);
        
        Logic_AutoLight(LIGHT11_NODE1);
        Logic_AutoLight(LIGHT12_NODE1);
        Logic_AutoLight(LIGHT13_NODE1);
        Logic_AutoLight(LIGHT14_NODE1);
        Logic_AutoLight(LIGHT15_NODE1);
        Logic_AutoLight(LIGHT16_NODE1);

        // Use Pin8 and Pin 9 as output on the electrical load
        nDigOut(30, Souliss_T1n_Coil, LIGHT1_NODE1); 
        nDigOut(32, Souliss_T1n_Coil, LIGHT2_NODE1);      
        nDigOut(34, Souliss_T1n_Coil, LIGHT3_NODE1);
        nDigOut(36, Souliss_T1n_Coil, LIGHT4_NODE1);
        nDigOut(38, Souliss_T1n_Coil, LIGHT5_NODE1);
        nDigOut(40, Souliss_T1n_Coil, LIGHT6_NODE1);
        nDigOut(50, Souliss_T1n_Coil, LIGHT7_NODE1);
        nDigOut(44, Souliss_T1n_Coil, LIGHT8_NODE1);  

        nDigOut(33, Souliss_T1n_Coil, LIGHT9_NODE1); 
        nDigOut(35, Souliss_T1n_Coil, LIGHT10_NODE1);      
        nDigOut(37, Souliss_T1n_Coil, LIGHT11_NODE1);
        nDigOut(39, Souliss_T1n_Coil, LIGHT12_NODE1);
        nDigOut(41, Souliss_T1n_Coil, LIGHT13_NODE1);
        nDigOut(43, Souliss_T1n_Coil, LIGHT14_NODE1);
        nDigOut(45, Souliss_T1n_Coil, LIGHT15_NODE1);
        nDigOut(47, Souliss_T1n_Coil, LIGHT16_NODE1);
        

        // Use Pin2 as command
        DigIn(2, Souliss_T1n_ToggleCmd, LEDCONTROL);        
        
        // Execute the logic that handle the LED
        Logic_LED_Strip(LEDCONTROL);

        // Use the output values to control the PWM
        analogWrite(3, mOutput(LEDRED));
        analogWrite(5, mOutput(LEDGREEN));
        analogWrite(6, mOutput(LEDBLUE));
        
    } 
    
    // Process data communication
    FAST_GatewayComms();
    
}

EXECUTESLOW()   {   
    UPDATESLOW();

    SLOW_10s()  {          
    
        // The timer handle timed-on states
        Timer_AutoLight(LIGHT1_NODE1);
        Timer_AutoLight(LIGHT2_NODE1);
        Timer_AutoLight(LIGHT3_NODE1);
        Timer_AutoLight(LIGHT4_NODE1);
        Timer_AutoLight(LIGHT5_NODE1);
        Timer_AutoLight(LIGHT6_NODE1);
        Timer_AutoLight(LIGHT7_NODE1);
        Timer_AutoLight(LIGHT8_NODE1);
        
        Timer_AutoLight(LIGHT9_NODE1);
        Timer_AutoLight(LIGHT10_NODE1);
        Timer_AutoLight(LIGHT11_NODE1);
      
        Timer_AutoLight(LIGHT12_NODE1);
        Timer_AutoLight(LIGHT13_NODE1);
        Timer_AutoLight(LIGHT14_NODE1);
        Timer_AutoLight(LIGHT15_NODE1);
        Timer_AutoLight(LIGHT16_NODE1);
                                                          
        Timer_LED_Strip(LEDCONTROL);            
    }     
}       

} [/code]

4*4 Matrix keypad

[code]/*
Keypad sketch
prints the key pressed on a keypad to the serial port
*/

const int numRows = 4; // number of rows in the keypad
const int numCols = 4; // number of columns
const int debounceTime = 20; // number of milliseconds for switch to be stable

// keymap defines the character returned when the corresponding key is pressed
const char keymap[numRows][numCols] =
{
{‘1’, ‘2’, ‘3’, ‘A’},
{‘4’, ‘5’, ‘6’, ‘B’},
{‘7’, ‘8’, ‘9’, ‘C’},
{’*’, ‘0’, ‘#’, ‘D’}
};

// this array determines the pins used for rows and columns
const int rowPins[numRows] = { 9, 8, 7, 6 }; // Rows 0 through 3
const int colPins[numCols] = { 5, 4, 3, 2 }; // Columns 0 through 2

void setup()
{
Serial.begin(9600);
for (int row = 0; row < numRows; row++)
{
pinMode(rowPins[row],INPUT); // Set row pins as input
digitalWrite(rowPins[row],HIGH); // turn on Pull-ups
}
for (int column = 0; column < numCols; column++)
{

pinMode(colPins[column],OUTPUT); // Set column pins as outputs
// for writing
digitalWrite(colPins[column],HIGH); // Make all columns inactive
}
}

void loop()
{
char key = getKey();
if( key != 0) { // if the character is not 0 then
// it’s a valid key press
Serial.print("Got key ");
Serial.println(key);
}
}

// returns with the key pressed, or 0 if no key is pressed
char getKey()
{
char key = 0; // 0 indicates no key pressed

for(int column = 0; column < numCols; column++)
{
digitalWrite(colPins[column],LOW); // Activate the current column.
for(int row = 0; row < numRows; row++) // Scan all rows for
// a key press.
{
if(digitalRead(rowPins[row]) == LOW) // Is a key pressed?
{
delay(debounceTime); // debounce
while(digitalRead(rowPins[row]) == LOW)
; // wait for key to be released
key = keymap[row][column]; // Remember which key
// was pressed.
}
}
digitalWrite(colPins[column],HIGH); // De-activate the current column.
}
return key; // returns the key pressed or 0 if none
}[/code]

Miettinyt pÀÀn puhki ohjelmallista sekÀ kytkennÀllistÀ ratkaisua mutta ideat loppuvat kesken :confused:

En ole tutustunut Soulikseen.

Onko niin, ettÀ tuossa Souliksessa on joku serveri, jonka kanssa Androidi kommunikoi? Ja Arduino kyselee sieltÀ Androidilla asetettua tilaa?

Jos noin, niin ÀkkiseltÀÀn ajatelen ongelmasi lienee siinÀ ettÀ Arduino kyselee Soulikselta mikÀ on Souliksessa oleva releiden tila ja asettaa ulostulot sen mukaan. NÀppÀimistöltÀ tulevat asetukset ei pysy pÀÀllÀ kun Arduno ehtii hakea uudelleen Souliksessa oleva tilan?

Jos nÀin, silloin pitÀÀ se matriisinÀppÀimistön aiheuttama muutos kertoa sille Soulikselle.

Voin toki olla hakoteillÀkin.