Synchronised Wireless Voting Device

1. Introducere

Pentru a putea realiza o analiză de film cât mai precisă și suficient de rapidă, ne-am gandit să implementăm un sistem format din mai multe dispozitive electronice și un server, legate într-o rețea wireless, care să funcționeze într-o sală de cinema.

Mai precis, fiecare scaun din sală va avea un astfel de dispozitiv – format dintr-o mini-tastatură, un transmițător/receptor wireless și (opțional) un display – care se va sincroniza cu serverul atunci când pornește filmul și va porni un ceas. Atunci când utilizatorul vrea să-și spună părerea despre momentul curent din film, apasă pe un buton – fiecare buton are o semnificație configurabilă. Atunci, dispozitivul formează un pachet cu codul de timp al filmului, codul butoului și codul dispozitivului și îl trimite la server.

Serverul receptionează pachetele primite de la dispozitivele din sală și are un soft care sintetizează informațiile.

2. Etapele proiectului

  1. Decidere asupra componentelor si construcția plăcuțelor. (2 exemplare)
    1. Componentele ce vor fi alese vor fi de test – la un preț mai scăzut (în caz că se stric să putem lua altele), dar scalabile – trecerea la componente de calitate mai bună să nu influentețe µprogramul din µprocesor.
    2. termen: nedefinit
  2. Dezvoltarea µprogramului pentru dispozitiv și pentru server
    1. Interacțiunea cu terminalul wireless
      1. Formarea unui pachet (nr. terminal + nr. pachet + cod timp + cod buton + crc)
      2. Depunerea pachetului intr-o coada de asteptare
      3. Expedierea la server si asteptare de ACK
      4. termen: nedefinit
    2. Interactiunea cu tastatura
      1. Recunoașterea fiecărui buton
      2. termen: nedefinit
    3. Dezvotarea softului pentru server (partea 1)
      1. Scrierea protocolului de inițializare a dispozitivelor în rețea (sincronizarea ceasurilor + trimiterea către terminale a valorii fiecărui buton)
      2. Depunerea într-o bază de date a codului de timp și a codului butonului pentru fiecare pachet recepționat.
      3. Scrierea semnalului de terminare
      4. Rezolvarea conflictelor
      5. termen: nedefinit
    4. Dezvotarea codului pentru display
      1. Pentru început, afișarea numărului butonului apăsat
      2. Afișarea unui help – un ciclu de forma: 1. taie aici, 2. lumină proastă – butonul și ce-nseamnă se afisează pentru o perioadă de timp, apoi se trece la următorul (când se ajunge la sfărșit se reia ciclul).
      3. Va exista un buton dedicat care aprinde ecranul pentru o perioadă de timp (salvare de energie).
      4. Într-o altă parte a ecranului se afișează titlul filmului și timpul.
      5. termen: nedefinit
  3. Alegerea componentelor finale
    1. trecerea la noile componente
    2. testare cu 2 dipozitive
    3. testtare cu 10 dispozitive
    4. rezolvarea conflicte (in transmisia wireless)
    5. termen: nedefinit

3. Use Cases

Name Sincronizare
Actors Administratorul sistemului
Trigger 1. Actorul da semnalul (prin apasarea unui buton) de incepere a sincronizarii retelei. 2. Acest proces se reia la fiecare minut dupa prima executie pentru mentinerea sincronizarii retelei..
Preconditions 0. Alimentarea componentelor. 1. Existenta cel putin a unui dispozitiv in retea. 2. Existenta placutei de receptie si conexiunea acesteia la server 3. Existenta si rularea unei aplicatii software (care sa preia pachetele si sa le prelucreze) pe o masina Linux si a unui server IPv6
Main Scenario 1. Serverul trimite un mesaj broadcast de sincronizare (inceperea unui timer) 2. Dispozitivele receptioneaza semanlul si raspund cu ACK.
Alternative Scenarios 1.a. Clientul nu primeste pachetul de la server. 1.a.1. Clientul nu face nimic, iar serverul va retrimite dupa timeout-ul de la ACK. 2.a.1. ACK-ul se pierde. 2.a.2. La fel ca mai sus.
Post Conditions 1. Clientul si serverul au un ceas de timp real sincronizat.
Name Transmiterea semnificatiei butoanelor
Actors Administratorul sistemului
Trigger Actorul trimte un mesaj broadcast cu semnificatia fiecarui buton (in software-ul care ruleaza pe server se va completa un tabel)
Preconditions 1. Use case-ul de sincronizare sa se fi executat cu succes.
Main Scenario 1. Serverul trimite un mesaj cu date 2. Dispozitivele receptioneaza semanlul si raspund cu ACK.
Alternative Scenarios 1.a. Clientul nu primeste pachetul de la server. 1.a.1. Clientul nu face nimic, iar serverul va retrimite dupa timeout-ul de la ACK. 2.a.1. ACK-ul se pierde. 2.a.2. La fel ca mai sus.
Post Conditions 1. Clientul afiseaza intr-un ciclu pe display semnificatia butoanelor.
Name Transmiterea datelor statistice
Actors Utilizatorul
Trigger Actorul apasa pe un buton de la tastatura dispozitivului
Preconditions 1. Use case-ul de sincronizare sa se fi executat cu succes. 2. Use case-ul de transmitere a semnificatiei butoanelor sa se fi executat cu succes.
Main Scenario 1. Clientul creaza un pachet care contine numarul butonului, codul de timp curent, id-ul propriu. 2. Clientul depune pachetul intr-o coada de asteptare. 3. (cat timp coada nu e goala) Clientul ia pachetul din capul cozii, il trimite si asteapta ACK pentru el.
Alternative Scenarios 3.a. Clientul nu primeste ACK de la server. 3.a.1. Clientul retransmite pachetul.
Post Conditions 1. Serveul prelucreaza datele.

4. Componente

Componentele alese initial au fost:

  • Transmitator wireless: Zigbit ATZB-24-A2
    • Decriere oficiala: ZigBit™ is an ultra-compact, low-power, high-sensitivity 2.4 GHz IEEE 802.15.4/ZigBee® OEM module based on the innovative Atmel’s mixed-signal hardware platform. It is designed for wireless sensing, control and data acquisition applications. ZigBit modules eliminate the need for costly and time-consuming RF development, and shortens time to market for a wide range of wireless applications.
    • Elemente:
      • MicroController integrat ATMega 1281
      • Dimensiuni foarte mici (24 x 13.5 x 2.0 mm) ceea ce permite realizarea unei placute integrate ce se poate pune in interiorul unei carcase light-weight, usor de folosit.
      • High RX sensitivity (-101 dBm)
      • Consum foarte mic:
        • < 6 μA in Sleep mode
        • 19 mA in RX mode
        • 18 mA in TX mode
      • Memorie de dimensiune consistente (128K bytes de memorie flash, 8K bytes RAM, 4K bytes EEPROM)
      • Posibilitatea de a scrie o adresa MAC proprie in EEPROM
      • IEEE 802.15.4 compatibil
      • 2.4 GHz banda ISM
      • Software integrat BitCloud - serial bootloader, AT command set
  • Tastatura: MULTICOMP - 4234A1 - KEYPAD, 3×4 ARRAY
  • Display: EVERBOUQUET - MC1602C8-SYL - LCD MODULE, ALPHANUMERIC, 2×16
    • caracteristica principala: Supply Voltage - 5V - fapt care a dus la un conflict de alimentare, pentru ca Zigbit-ul functioneaza intre 1.8-3.5 V si a fost nevoie de 2 stabilizatoare.

Update

Principala problema cu aceste componente a fost ca RF Tranceiverul din interiorul Zigbit-ului e foarte sensibil si se poate arde foarte usor daca nu e protejat (ceea ce s-a si intamplat). Pentru schema finala vom folosi un tranceiver care este separat de ATmega 1281.

5. Schema placii de baza

6. Dezvoltarea microProgramului

Am folosit 2 modalitati (platforme de delvoltare a codului pentru Zigbit)

  1. Contiki Operating System
    1. este un sistem de operare multitasking folosit pentru sistem embeded si pentru senzori wireless si care are o cantitate mica de memorie folosita. Contine o platforma completa de dezvoltare pentru dispozitive wireless .
    2. mai jos este exemplul de la care am plecat pentru sincronizarea serverului cu clientul
/*
 * This is a small example of how to write a TCP server using
 * Contiki's protosockets. It is a simple server that accepts one line
 * of text from the TCP connection, and echoes back the first 10 bytes
 * of the string, and then closes the connection.
 *
 * The server only handles one connection at a time.
 *
 */
 
#include <string.h>
#include <stdio.h>
/*
 * We include "contiki-net.h" to get all network definitions and
 * declarations.
 */
#include "contiki-net.h"
 
#include "webserver-nogui.h"
/*
 * We define one protosocket since we've decided to only handle one
 * connection at a time. If we want to be able to handle more than one
 * connection at a time, each parallell connection needs its own
 * protosocket.
 */
static struct psock ps;
 
/*
 * We must have somewhere to put incoming data, and we use a 10 byte
 * buffer for this purpose.
 */
static char buffer[10];
static double value;
static uint8_t unit, zeci, sute;
 
void ADC_init(void)
 {
	ADMUX |= _BV(REFS1)|_BV(REFS0);
	ADCSRA |= _BV(ADEN);
 
 }
 
 uint16_t ADC_get(void)
 {
	uint8_t i;
	uint16_t val=0;
 
	ADMUX = _BV(REFS1)|_BV(REFS0);
	for(i = 0; i < 20; i++)
	{
		ADCSRA |= _BV(ADSC);
		loop_until_bit_is_set(ADCSRA, ADIF);
		val+= ADC;
	}
	val = val / 20;
	return val;
 }
uint16_t ADC_getTemp(void)
 {
	uint8_t i;
	uint16_t val=0;
 
	ADMUX = _BV(REFS1)|_BV(REFS0)|_BV(MUX0);
	for(i = 0; i < 20; i++)
	{
		ADCSRA |= _BV(ADSC);
		loop_until_bit_is_set(ADCSRA, ADIF);
		val+= ADC;
	}
	val = (val / 20) - 9;
	return val;
 
 }
/*---------------------------------------------------------------------------*/
/*
 * A protosocket always requires a protothread. The protothread
 * contains the code that uses the protosocket. We define the
 * protothread here.
 */
static
PT_THREAD(handle_connection(struct psock *p))
{
 
 
  /*
   * A protosocket's protothread must start with a PSOCK_BEGIN(), with
   * the protosocket as argument.
   *
   * Remember that the same rules as for protothreads apply: do NOT
   * use local variables unless you are very sure what you are doing!
   * Local (stack) variables are not preserved when the protothread
   * blocks.
   */
  PSOCK_BEGIN(p);
 
  /*
   * We start by sending out a welcoming message. The message is sent
   * using the PSOCK_SEND_STR() function that sends a null-terminated
   * string.
   */
  PSOCK_SEND_STR(p, "Sparrow node online.\n");
 
  /*
   * Next, we use the PSOCK_READTO() function to read incoming data
   * from the TCP connection until we get a newline character. The
   * number of bytes that we actually keep is dependant of the length
   * of the input buffer that we use. Since we only have a 10 byte
   * buffer here (the buffer[] array), we can only remember the first
   * 10 bytes received. The rest of the line up to the newline simply
   * is discarded.
   */
//  PSOCK_READTO(p, '\n');
 
  /*
   * And we send back the contents of the buffer. The PSOCK_DATALEN()
   * function provides us with the length of the data that we've
   * received. Note that this length will not be longer than the input
   * buffer we're using.
   */
 
 
  PSOCK_SEND_STR(p, "Voltage: ");
  //PSOCK_SEND(p, buffer, PSOCK_DATALEN(p));
 
  value = ADC_get() / 200.0;
  unit = (uint8_t)value%10;
  zeci = (uint8_t)(value * 10)%10;
  sute = (uint8_t)(value * 100)%10;
 
  sprintf(buffer,"%d.%d%dV\n",unit,zeci,sute);
  PSOCK_SEND_STR(p, buffer);
 
  PSOCK_SEND_STR(p, "Temperatura la babanu: ");
 
  value = ADC_getTemp() / 8.0;
  unit = ((uint8_t)value/10)%10;
  zeci = (uint8_t)value%10;
  sute = (uint8_t)(value * 10)%10;
 
  //PSOCK_SEND(p, buffer, PSOCK_DATALEN(p));
   sprintf(buffer,"%d%d.%dC\n",unit,zeci,sute);
  PSOCK_SEND_STR(p, buffer);
 
  /*
   * We close the protosocket.
   */
  PSOCK_CLOSE(p);
 
  /*
   * And end the protosocket's protothread.
   */
  PSOCK_END(p);
}
/*---------------------------------------------------------------------------*/
/*
 * We declare the process.
 */
PROCESS(example_psock_server_process, "Example protosocket server");
/*---------------------------------------------------------------------------*/
/*
 * The definition of the process.
 */
 
 
PROCESS_THREAD(example_psock_server_process, ev, data)
{
  /*
   * The process begins here.
   */
  PROCESS_BEGIN();
 
  /*
   * We start with setting up a listening TCP port. Note how we're
   * using the HTONS() macro to convert the port number (1010) to
   * network byte order as required by the tcp_listen() function.
   */
  tcp_listen(HTONS(1010));
	ADC_init();
  /*
   * We loop for ever, accepting new connections.
   */
  while(1) {
 
    /*
     * We wait until we get the first TCP/IP event, which probably
     * comes because someone connected to us.
     */
    PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);
 
    /*
     * If a peer connected with us, we'll initialize the protosocket
     * with PSOCK_INIT().
     */
    if(uip_connected()) {
 
      /*
       * The PSOCK_INIT() function initializes the protosocket and
       * binds the input buffer to the protosocket.
       */
      PSOCK_INIT(&ps, buffer, sizeof(buffer));
 
      /*
       * We loop until the connection is aborted, closed, or times out.
       */
      while(!(uip_aborted() || uip_closed() || uip_timedout())) {
 
	/*
	 * We wait until we get a TCP/IP event. Remember that we
	 * always need to wait for events inside a process, to let
	 * other processes run while we are waiting.
	 */
	PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);
 
	/*
	 * Here is where the real work is taking place: we call the
	 * handle_connection() protothread that we defined above. This
	 * protothread uses the protosocket to receive the data that
	 * we want it to.
	 */
	handle_connection(&ps);
      }
    }
  }
 
  /*
   * We must always declare the end of a process.
   */
  PROCESS_END();
}
/*---------------------------------------------------------------------------*/
AUTOSTART_PROCESSES(&webserver_nogui_process,&example_psock_server_process);
  1. BitCloud
    1. pachet software de la Atmel folosit pentru dezvoltare de aplicatii scalabile si securizate wireless. Mai mult, Zigbit-ul vine cu un bootloader instalat si in corelatie cu BitCloud.
    2. mai jos urmeaza o parte din codul de stabilire a conexiunii intre 2 noduri
/**************************************************************************//**
  \file Peer2Peer.c
 
  \brief Peer-2-peer sample application.
 
  \author
    Atmel Corporation: http://www.atmel.com \n
    Support email: avr@atmel.com
 
  Copyright (c) 2008 , Atmel Corporation. All rights reserved.
  Licensed under Atmel's Limited License Agreement (BitCloudTM).
 
  \internal
    History:
    14.10.09 A. Taradov - Added FIFO for received packets
******************************************************************************/
 
/******************************************************************************
                    Includes section
******************************************************************************/
#include <types.h>
#include <configServer.h>
#include <appTimer.h>
#include <zdo.h>
#include <peer2peer.h>
#include <serialInterface.h>
 
/******************************************************************************
                    Define(s) section
******************************************************************************/
 
/******************************************************************************
                    Variables section
******************************************************************************/
// Network related variables
static uint16_t nwkAddr;                        // Own NWK address
static AppMessageBuffer_t appMessageBuffer;     // Application message buffer
static uint8_t messageIdTx = 0;                 // Application transmitted message ID
static uint8_t messageIdRx = 0;                 // Next expected ID of received message
static uint16_t actualDataLength = 0;           // Actual data length to be transmitted via network
 
// Data indications FIFO related variables
static uint8_t apsDataIndFifo[APP_DATA_IND_BUFFER_SIZE];
static uint16_t apsDataIndFifoStart = 0;
static uint16_t apsDataIndFifoEnd = 0;
 
// USART related variables
static HAL_UsartDescriptor_t appUsartDescriptor;          // USART descriptor (required by stack)
static bool usartTxBusy = false;                          // USART transmission transaction status
static uint8_t usartTxBuffer[APP_USART_TX_BUFFER_SIZE];   // USART Tx buffer
static uint8_t usartRxBuffer[APP_USART_RX_BUFFER_SIZE];   // USART Rx buffer
 
// Application related parameters
static AppState_t appState = APP_INITIAL_STATE;  // application state
static AppDataTransmissionState_t appDataTransmissionState = APP_DATA_TRANSMISSION_READY_STATE;
static ZDO_StartNetworkReq_t networkParams; // request params for ZDO_StartNetworkReq
static APS_DataReq_t apsDataReq;
 
// Endpoint parameters
static SimpleDescriptor_t simpleDescriptor = { APP_ENDPOINT, APP_PROFILE_ID, 1, 1, 0, 0 , NULL, 0, NULL };
static APS_RegisterEndpointReq_t endpointParams;
static bool noIndications = false;
 
// Timer indicating starting network during network joining.
// Also used as delay timer between APS_DataConf and APS_DataReq.
static HAL_AppTimer_t delayTimer;
 
/***********************************************************************************
                    Static functions declarations section
***********************************************************************************/
static void APS_DataIndication(APS_DataInd_t* dataInd);
static void APS_DataConf(APS_DataConf_t* confInfo);
static void ZDO_StartNetworkConf(ZDO_StartNetworkConf_t* confirmInfo);
static void initNetwork(void);
static void startNetwork(void);
static void networkSendData(bool newTransmission);
 
static void startBlinkTimer(void);
static void startingNetworkTimerFired(void);
static void delayTimerFired(void);
 
static void initSerialInterface(void);
static void usartStartSending(void);
static void usartBytesReceived(uint16_t readBytesLen);
static void usartWriteConf(void);
 
static uint16_t fifoFreeSpace(void);
static void fifoWriteData(uint8_t *data, uint16_t size);
static uint16_t fifoReadData(uint8_t *data, uint16_t size);
 
static void buttonReleased(uint8_t buttons);
 
/***********************************************************************************
                    Implementation section
***********************************************************************************/

7. Coordonatori

  1. Razvan Tataroiu
  2. Dan Tudose
  3. Andrei Voinescu

8. Concluzii

Produsul are un potential mare de piata, putand fi utilizat in foarte multe domenii care presupun feedback live din partea clientilor.

9. Referinte

  1. datasheet zigbit
  2. Contiki contiki

10. Contractor

Universitatea de Arta Teatrala si Cinematografica “I.L.Caragiale” - Bucuresti www.unatc.ro

pm/prj2010/rtataroiu/synchronised_wireless_voting_device.txt · Last modified: 2021/04/14 17:07 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0