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.