Mainpage:Enjoy your Z1 now

From Zolertia

Jump to: navigation, search

Contents

Introduction

The aim of this example is show how to use a couple of Z1. This example explains how two program two Z1 motes and ends with how to visualize data in a computer.

Download code: EnjoyYourZ1Now.tar.gz

Requirements

  • Two Z1 motes
  • TinyOS platform and Z1 suport for TinyOS
  • Python 2.5 or upper

Program a Sink and a Source Z1 mote

Specification

  • Z1 mote Sink waits for data packets.
  • Z1 mote Source send data to Sink mote.
  • Number of Z1 motes Source can be [1,n].
  • If number of Z1 motes Source > 1 then each mote must be identifiable (identification byte/s in their Pay Load).
  • Z1 can send [1,n] kinds of packets.
  • If the packet kind > 1 then each packet must be identifiable (identification byte/s in their Pay Load, or description must be different).

Implementation (TinyOS 2.1.1)

  • You need to install the Z1 support for TinyOS.

Comments to implementation

  • If you have more than Z1 Source mote, they must be identifiable.
    • In the header file TestMsg.h you can add mote identifications and define an identification for the mote that will be programmed.
enum {
 	MOTE_ID_0 = 0x00,
  	MOTE_ID_1,
  	MOTE_ID_2,
  	MOTE_ID_3,
 	MOTE_ID_4,
  	MOTE_ID_5
 
     } MoteIdentificators;
#define MOTE_ID MOTE_ID_5
  • You can modify the rate of acceleration and temperature values.
    • In the file Temperature_AccelerationC.nc
event void Boot.booted()
{
  call TimerTemperature.startPeriodic(1024);
  call AccelControl.start();
}
event void AccelControl.startDone(error_t error)
{
call TimerAccel.startPeriodic(500);
}

Get and plot the data received by your Sink Z1 mote

Specification

  • Z1 mote Sink waits for data packets send by one or more Source mote.
  • Number of Z1 motes Source can be [1,n].
    • If number of Z1 motes Source > 1 then each mote must be identifiable (identification byte/s in their Pay Load).
  • Z1 can send [1,n] kinds of packets.
    • If the packet kind > 1 then each packet must be identifiable (identification byte/s in their Pay Load, or description must be different).
  • Data packets are send to a remote server in a XML format.

Design

  • Packets are read from the Z1 Sink serial port connection.
  • At serial port layer the data packets are like this example:

A packet has: Header + Pay Load + Meta data

Header: 7e 45 00 ff ff 00 01 0a 00 aa 7f 42

Pay Load: 01 00 ff 53 00 8f 00 4c

Meta data: a9 2d 7e

  • XML data are send to a remote server via FTP.
  • Classes
Class MyZ1HarvesterSender{
 
     //MyZ1HarvesterSender collects and sends data
 
     //stores packet templates
     packetsTemplates as Array of PacketDescription 
 
     //stores motes
     motes as Array of Z1mote 
 
     //stores the current packet
     currentPacketReceives as Array of Bytes
 
     //stores the template index of the current packet 
     currentPacketIndexTemplate as Integer 
 
      //if true data can be inserted in a xml file and send
     dataMustBeSend as Boolean 
 
 
      //initializes an array of templates, an array of motes, and atributes 
      constructor(serialPortName as String)
 
      //makes a template for each packet that a sink must proces 
      definePacketsTemplates() 
 
      //opens a serial port
      openSerialPort(serialPortName as String) 
 
      //waits for a data writted by a sink (when a sink receive a packet the write in the serial port where it's connected )
      run()
 
      //resolves if a packet belongs to a know template
      isAProcesablePacket() 
 
      //resolves if a mote is registred, actualize its last packet-received's date-time, and actualize status
      actualizeMoteList()
 
      //proces data contained in the packet
      procesCurrentPacketData(current as PacketDescription) 
 
      //returns an array with the packet position and the bytes's number to be proces. the argument is a literal description the  byte or group of bytes
      getIndexAndBytesToProcess(queryGroupOfBytes as String)
 
      //proces an unsigned integer. The argument is an array with the packet position and the number bytes's to be proces
      procesUnsignedData(index_nBytes as Array[2]) 
 
      //for each kind of packet template makes a Z1DataFTPSender and a Z1DataPachubeSender instance 	
      sendDataToRemoteServer() 
 
      //initializes the array container of proces data
      iniDataList()
  }
 
 
Class  Z1mote
{
      //Description of a Z1 Mote
 
      //mote identification
      moteId as String 
 
      //mote is live
      moteStatus as Boolean 
 
      //date and time of the last packet received from a mote, can be necessary for set its status
      lastDateSend as Date-Time 
 
      //initializes the class atributes
      constructor(moteId as String) 
 
      //returns moteId value
      getMoteIdentification() 
 
      //returns moteStatus value
      getMoteStatus() 
 
      //changes moteStatus value
      setMoteStatus() 
 
      //returns lastDateSend value
      getLastDateSend() 
 
     //changes lastDateSend value
     setLasDateSend() 
}
 
Class PacketDescription
{
	//Description of a packet
 
        //max len of an array at lower layer of TinyOS 2.x standard
	PACKETMAXLEN = 46 
 
        //a literal name for the packet 
	packetName as String 
 
        //a numerical name for the packet, that must be the identification contained in the packet	
	packetIdentifiaction as Integer 
 
        //array that contains and array [literal byte/s description, number of bytes to proces, procesed data array] with the information of each packet byte or the bytes that are an interest for proces
	byteContent as Array[PACKETMAXLEN] of [string, number of bytes, data[] ]
 
        //the interval time that the packet is send by a Z1 mote Source
	intervalTime as Integer 
 
        //initializes the class atributes
	constructor(packetname as String, packetId as Integer) 
 
        //returns packetName value
	getPacketName() 
 
        //returns packetIdentification value
	getPacketIdentification() 
 
        //return byteContent value
	getDescriptionContent(index) 
 
        //return byteContent value at index position
	getDescriptionContentAtIndex(index)
 
        //return the position of the first description 	ocurrence in byteContent
	getIndexOfDescriptionContent(description)
 
        //change value at index position in byteContent
	setDescriptionContentAtIndex(index,value) 
 
        //returns intervalTime value
	getIntervalTime() 
 
        //change intervalTime value 
	setIntervalTime(value) 
 
}
 
Class Z1DataFTPSender
{
	//makes an xml document and sends data to a remote ftp server.
 
	//ftp address
        FTPADDRESS as String 
 
        //ftp user
	FTPUSER as String 
 
        //ftp password
	FTPPASSWORD as String 
 
        //ftp folder
	FTPFOLDER as String 
 
        //template name assigned by the user
	templateName as String 
 
        //data to send
	dataToSend as Array of [string, number of bytes, data[] ] 
 
	//initializes the class atributes and call the function for make an xml document and send data
        constructor(template as Array) 
 
        //creates a file with docName and xml extension and send it to a remote server
	sendDocument(doc as String, docName) 
 
        //make an string with a xml format
	makeAndSendDocument 
}
 
Class Z1DataPachubeSender
{
	// send data to Pachube you need to obtain a key and URL from Pachube. 
 
        //Pachube Key
	PACHUBE_KEY as String
 
        //Pachube Url
	PACHUBE_URL as String 
 
        //data template  to send	
        dataToSend as Array 
 
        //initializes the class atributes and call the function for send the last data
	constructor 
 
        //send data to Pachube
	sendLastDataToPachube 
}


File:DiagramaClases.png

Implementation (Python 2.6)

Python 2.6 has been use for the implementation of the software need to receive and send data from a Z1 Sink Mote. You need to install the additional packets to your Python. There are pySerial and Python-EEML .

Comments to implementation

If you change the packet content send by a source mote, you must make changes in the MyZ1HarvesterSender implementation.These changes could be:

  • in your constants definitions
  • in your packets template definitions
  • in the process of packet content

An example, you decide that the temperature data send by a source mote must be contained in 3 bytes or the packet kind identification must to be 5. Certainly you must make some changes in your template definition and also (or not ...) in the content process like as show below:

# here we indicate that the temperature packet identification is  now 5
self.__packetsTemplates.append(PacketDescription(self.DESC_TEMPERATURE,5))
self.__packetsTemplates[0].setDescriptionContentAtIndex(10, [self.DESC_PACKETNUMBER,2,[]])
self.__packetsTemplates[0].setDescriptionContentAtIndex(12, [self.DESC_MOTEIDENTIFICATION,1,[]])
self.__packetsTemplates[0].setDescriptionContentAtIndex(13, [self.DESC_PACKETKIND,1,[]])
# here we indicate that the number of bytes to be proces is 3
self.__packetsTemplates[0].setDescriptionContentAtIndex(14, [self.DESC_TEMPERATUREVALUE,3,[]])
self.__packetsTemplates[0].getDescriptionContent().append([self.DESC_DATETIME,0,[]])

You can decide when you want send your data if you modify the constant:

 
TEMPN = 300 #a xml must be send every 300 sec (sync with temperature packet)

You can send your data to a remote FTP server or to Pachube server or only save your data in a xml file.

  • Send data to a remote FTP and Pachube server:
 
 def sendDataToRemoteServer(self):
     for item in self.__packetsTemplates:
       Z1DataPachubeSender(item)
       Z1DataFTPSender(item)
     self.__dataMustBeSend = 0
     self.iniDataList()
  • Send data to a remote FTP or Pachube server
    • Comment the line
      Z1DataFTPSender(item)
      or
      Z1DataPachubeSender(item)
  • If you just want see the data in your pc in a html page:
    • Comment the line
      Z1DataPachubeSender(item)
    • Comment the code like as show below:
def sendDocument(self,doc, docName):
        try:
            fileName =docName + ".xml"
            session = file("./" + fileName , 'w+' )
            session.write(doc.toxml())
            session.close()
            '''
            f = open("./" + fileName,"rb")
 
            conn=ftplib.FTP(self.FTPADDRESS)
            conn.login(user=self.FTPUSER, passwd=self.FTPPASSWORD)
            conn.cwd(self.FTPFOLDER)
            conn.storbinary('STOR ' + fileName,f)
            '''
        except Exception:
            print "error: " + str(sys.exc_info()[1])
            #conn.close()
        finally:
            pass
            #f.close()
            #conn.close()
  • You have your data into a xml file in your python script folder. At your python script folder add a file with .htm or .html extension and with the code:
<html>
<head><script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript" src="plotZolertiaData.js"></script>
 </head>
  <body>
  </body>
</html>
  • The code into the java script (plotZolertiaData.js) plot your data using the API chart from Google.


Now you are ready to run your Z1 Source and Sink motes.

1.Connect your Sink Z1 mote

2.Connect your Source Z1 mote/s

3.Verify the serial port assigned by the OS for the Sink Z1 mote

4.Run MyZ1HarvesterSender

  • Microsoft Windows OS: python MyZ1HarvesterSender COMXX
  • Linux OS: python MyZ1HarvesterSender /dev/ttyUSBXX


Download code: EnjoyYourZ1Now.tar.gz

Personal tools
Navigation
MansOS Support
General guides and apps
Assistance