Souliss, Domotica e IoT basata su Arduino ed Android

Vista l'assenza di una guida utente, riporto brevemente una descrizione di Souliss utile a comprendere come è stato sviluppato il software.

Ogni nodo ha un'area dati (un array da 30 byte) suddiviso in tre gruppi:

  • Tipici,
  • Input,
  • Output

Il primo gruppo, Tipici, contiene un codice identificativo della logica implementata nel nodo. Può essere utilizzato da applicazioni precompilate (ad esempio l'UI Android) per capire come interpretare o comandare i dati provenienti da nodo.

Il secondo gruppo, Input, è uno spazio dedicato agli ingressi sia hardware sia software. Analogamente il terzo gruppo è per gli output.

Per default l'area di memoria è indirizzata per slot, il cui numero è attualmente 8. Uno slot è composto da tre byte, uno per ogni gruppo. Tutti i metodi implemetati in Souliss sono indirizzati per slot.

Prendendo l'esempio 1 allegato alla libreria. Si tratta della gestione di un digital output (ad esempio un relé) con comandi locali e remoti.

Il codice, a meno degli indirizzamenti e selezione dei pin è il seguente:

		// Execute the code every 2 time_base		
		if (!(phase % 2))
		{
			// Use Pin2 as ON command, Pin3 as OFF command
			Souliss_DigIn(2, Souliss_T01_OnCmd, memory_map, 0);
			Souliss_DigIn(3, Souliss_T01_OffCmd, memory_map, 0);			
			
			// Execute the logic
			Souliss_T1(memory_map, 0, &data_changed);

			// Use Pin9 as output on the electrical load
			Souliss_DigOut(9, Souliss_T01_Coil, memory_map, 0);	
		}

Il codice viene eseguito ogni due time_base del codice (100 ms) La funzione Souliss_DigIn() associa ad un pin della scheda una funzione ed il relativo slot, ad esempio

Souliss_DigIn(2, Souliss_T01_OnCmd, memory_map, 0);

Dichiara il pin 2 (precedentemente impostato come input) come OnCmd (On Command) e lo associa allo slot 0 della memory_map

Souliss_T1(memory_map, 0, &data_changed);

Esegue la logica T1 (tipico 1) sullo slot 0, quindi usa lo slot 0 di input per leggere i dati e lo stesso per gli output. La variabile data_changed viene usata come trig per l'invio dei dati.

Infine, Souliss_DigOut() prende lo slot 0 di output e lo lega al pin 9.

		// Execute the code every 5 time_base		  
		if (!(phase % 5))
		{   
			// Retreive data from the communication channel
				Souliss_SerialData(memory_map, &data_changed);
		}

		// Execute the code every 10 time_base		  
		if (!(phase % 10))
		{   
		// Open a communication channel, check channel status
		Souliss_SerialChannel(network_address_2, memory_map, 0, 0, 1, 0, &healty, &count);
		}

La funzione Serial_Data recupera i dati dalla comunicazione seriale (ethernet, chibiduino, ...) in base alle configurazione di vNet.

Il dispositivo ha ingressi hardwired alla scheda, volendo introdurre un modulo remoto si può dichiarare un canale di comunicazione con Souliss_SerialChannel() dove 0, 0, 1, 0 sta per slot ingresso, slot uscita, numero byte, canale di comunicazione.

Lo slot di ingresso è quello relativo alla propria memory_map, i dati provenienti da questo canale di comunicazione sono inseriti nello slot 0 degli input.
Lo slot di uscita è quello da cui leggere, viene letto lo slot 0 degli output del dispositivo di rete con indirizzo network_address_2.

Il canale di comunicazione è un indice interno, può variare da 0 a 10 e non può essere ripetuto all'interno dello stesso dispositivo.

Per realizzare un pannello con pulsanti remoti, che quindi agiscono su un dispositivo di rete diverso, in particolare quello a cui è fisicamente collegato il relé

		if (!(phase % 2))
		{
			// Use Pin2 as ON command, Pin3 as OFF command	
			Souliss_DigIn(2, Souliss_T01_OnCmd, memory_map, 0);
			Souliss_DigIn(3, Souliss_T01_OffCmd, memory_map, 0);	
			
			// Make the input slot 0 a remote input
			Souliss_LinkIO(memory_map, 0, 0, &data_changed);
		} 
		
		// Execute the code every 5 time_base		  
		if (!(phase % 5))
		{ 
  			// Retreive data from the communication channel
			Souliss_SerialData(memory_map, &data_changed);
			
			// If Souliss_LinkIO is used, a reset is required
			if(data_changed == MaCaco_NODATACHANGED)
				Souliss_ResetOutput(memory_map, 0);
		}

Il codice è estremamente simile al precedente, la differenza è che non viene eseguita nessuna logica. Gli input sono riportati in output direttamente tramite la funzione Souliss_LinkIO() in modo che possano essere letti dall'altro modulo.

Saluti,
Dario.