/*
 * VERSION 1.0 July 14th 2009 LATE  File: 'gas_temp_monitor10.c'
 * ~/Hadcon/actmel/hadshopomo/gas_temp_momitor_alex/gas_temp_monitor05.c
 * Author: Alejandro Gil based on Michael Traxler based and Giacomo Ortona's hadtempsens

Revision 1.0: FIRST OPERATIVE VERSION
14JULY09 LATE - I can set the the DualSwitches and the interface provides multiple serial port commands.
List of commands:
h --> this help
l --> shows all devices found in the bus
t --> shows all temperature devices in the bus, makes temperature conversion and shows devices addresses and values
d --> shows all ADCs in the bus, makes ADC conversion and shows devices addresses and values
s --> Reads the status of all DualSwitches (DS2413) on the bus
		FO (S command)-- both channels ON
		OF (R command)-- both channels OFF
		C3 (U command)-- Channels A:OFF, B:ON
		3C (T command)-- Channels A:ON, B:OFF
S --> Sets all DualSwitches (DS2413) on the bus to ON
R --> Sets all DualSwitches (DS2413) on the bus to OFF
T --> Not yet implemented: Sets a particular DualSwitch with A:ON, B:OFF
U --> Not yet implemented: Sets a particular DualSwitch with A:OFF, B:ON
W --> Not yet implemented: Sets a particular DualSwitch to ON or OFF
v,p,f,g--> Do not use: either old or test functions");
      		
14JULY09 - I can read the three type of sensors: Temperature sensors, ADCs and DualSwitches. There are separate cases for each.
13JULY09 - I can separate diferent type of sensors: Temperature sensors and ADCs. Switches reading still remaining.
09APRIL09- I can control the DS2413 dual switch and read it after a writing. This functionality is based on the functions: DoubleSwitch and SetOnDoubleSwitch.
1. The function 'ReadADCchannels' is a separate function that allow to readout the four channels of the chip by using pointers with a single call.
2. It si shown how to modify the RANGE of the ADC

 * It works with the command  './write_and_get_result m' and cat /dev/ttyS1

 * This program is running on the ATMEL AT90CAN128 and does the following:
 * - CAN READ THE INPUTS OF THE DS2450 ADC.
 * - CAN READ THE TEMPERATURES OF THE DS18D20
 * - It cost me a lot to make it work because I forgot to read the CRC after writing into memory (see example page 16-17 datasheet.

 * - There are still some bugs:
 * - Dunno why the caracter send by the etrax is always 'm'--> Only the 'm' case will work!
 *
 *
 */

/*
An 8-bit family code is stored in the first byte and identifies the device type as NVRAM, EEPROM, temperature sensor, Timekeeper, etc. The next 6 bytes store the unique individual serial number while the last byte contains a cyclic redundancy check (CRC) with a value based on the data contained in the first seven bytes. This allows the master to determine if an address was read error free.
The codes are:
20: DS2450 ADC ----------------->ie: 2020890C00000073, 2090920C00000078
28: DS18B20 (Temp. Sensor)------>ie: 283065E9000000EA, 286A9C7C01000095
3A: DS2413 (Double Switch)------>ie: 3ACFDA0100000048,
05: DS2405 (Single Switch)------>ie: 05D5253000000084, 05BA363000000051

*/

/*
 * $Id: rpc_monitor.c,v 1.1.1.1 2009-09-25 13:06:24 hadaq Exp $ $Source:
 * /home/giacomo/cvsroot/hadtempsens/tempsens2.c,v $ $Header:
 * /home/giacomo/cvsroot/hadtempsens/tempsens2.c,v 1.33 2006/09/22
 * 10:40:08 giacomo Exp $
 *
 */

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <util/delay.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/iocan128.h>


#include "OWIDeviceSpecific.h"
#include "OWIHighLevelFunctions.h"
#include "OWIBitFunctions.h"
#include <util/delay.h>

#define BV(x)  (1<<x)
#define BIT(x)  (1<<x)

uint8_t BUSES[5] = { OWI_PIN_0 };

#define DS1820_START_CONVERSION         0x44
#define DS1820_READ_SCRATCHPAD          0xbe
#define DS1820_WRITE_SCRATCHPAD         0x4E
#define DS1820_CONFIG_REGISTER          0x7f
#define DS1820_READ_POWER               0xb4

#define NUM_DEVICES       40
#define MAX_LENGTH_COMMAND  30

//ADC
#define DS2450_CONVERT                  0x3C
#define DS2450_READ_MEMORY              0xAA

#define BAUD               7

// the number of ADC conversions done to get an average voltage value
#define ADC_CYCLES 3

// wait ADC_TIMEOUT clock cycles for a single ADC conversion
#define ADC_TIMEOUT 1000

//PIN_BUS indicates the number of active pins for 1-wire bus on the HadCon board:
    //If PIN_BUS=0, it means pin 0 of the connector is active for 1-wire bus,
    //if PIN_BUS=1 then pin 0 and 1 are active,
    //and so on.
        // NOTE: [Somewere else it is defined connector_2]
#define PIN_BUS 0

#define FAMILY_DS2450_ADC    0x20
#define FAMILY_DS18B20_TEMP     0x28
#define FAMILY_DS2413_DUAL_SWITCH 0x3A

volatile uint16_t thigh = 900;
volatile uint16_t tlow = 100;

uint8_t IDS_ALL[NUM_DEVICES][8];  //Global variable to store the ID numbers of ALL devices.
uint16_t IDS_ALL_VALUES[NUM_DEVICES][8];  //Global variable to store the register values of ALL devices (either temperature, voltages, etc)
 



int
break_point (int error_code, char *s)
{
  uint8_t intstate = SREG;
  int i;
  char *str;

  cli ();

  i = error_code;
  str = s;
  _delay_ms (10);

  SREG = intstate;
  return 1;
}


/*
 *USART0 must be initialized before using this function
 *for use this function, be sure that data is no longer then 8 bit
 *(single character) this function will send 8 bits from the at90can128
 */
void
USART0_Transmit (uint8_t data)
{
  /*
   * wait for empty transmit buffer
   */
  while (!(UCSR0A & (1 << UDRE0)))
    {
    }
  /*
   * put the data into the buffer
   */
  UDR0 = data;
}

///////////////////////////////////////////
///////////////////////////////////////////
///////////////////////////////////////////
/*
 *  ReadDevicesID this function will read the ID´s of a certain number of
 * devices limited between 1 and NUM-DEVICES and will send the data through
 *  USART register
 * the function will return the number of devices on the bus
 * t is an array used for the storage of the temperatures values
 * IDS is a 2D array used for storage the sensors ID´s
*/

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

uint16_t ReadTemperature(unsigned char bus, unsigned char * id)
{
    uint16_t temperature;
   
    // Reset, presence.
   
    if (OWI_DetectPresence(bus)==0)
    {
    return -999; // Error
    }

    // Match id founded earlier
    OWI_MatchRom(id, bus);
    // Send READ SCRATCHPAD command.
    OWI_SendByte(DS1820_READ_SCRATCHPAD, bus);
    // Read only two first bytes (temperature low, temperature high)
    // and place them in the 16 bit temperature variable.

    temperature = OWI_ReceiveByte(bus);
    temperature |= (OWI_ReceiveByte(bus) << 8);
    return temperature;
}

int ReadDevicesID (uint8_t *pins, int showlist) {
    //A uint16_t t;
    char PD;
    //P uint8_t IDS[NUM_DEVICES][8];
    int countDEV = 0;//number of devices (initialized to 0)
    int countDEVbus=0;//number of devices on the current bus (initialized to 0)
    char cadena[100];
/*on String_to_Send are written the data to be sent away*/
    char String_to_Send[30];//27 should be enough
   
   
    PORTA |= 0x8;

/*clean one IDS array*/ //A BAD INITIALIZED?
    for(int a=0; a<7;a++){
        IDS_ALL[NUM_DEVICES-1][a]=0;
    }

    for(int b=0;b<PIN_BUS+1;b++) {/*initialize the bus*/
        OWI_Init(pins[b]);    //A 'b' Indicates the number of pins active for 1-wire bus on the HadCon board. If b is 0, it means pin 0 of the connector, if 1 pin 1 and so on.
       uint8_t res=1;
        countDEV = countDEV + countDEVbus;
        countDEVbus=0;//reset number of devices on the bus

    //break_point(PD, "presence");
        if((PD=OWI_DetectPresence(pins[b]))!=0) {
        //this will search the devices Id´s till the max number of devices is reached or
        // all the devices have been read out
    //break_point(PD, "presence");
    //break_point(countDEVbus, "Cound DEV bus");
           while(countDEVbus<NUM_DEVICES&&res!=OWI_ROM_SEARCH_FINISHED){
            if(countDEVbus==0){
                //A sprintf(cadena, "Dispositivo 0");
                //A USART_send_string (cadena);
                res=0;
            }
            OWI_DetectPresence(pins[b]);
            res=OWI_SearchRom(IDS_ALL[NUM_DEVICES-1], res, pins[b]);
            //break_point(res, "search ROM");
            for(int a=0;a<8;a++){
                IDS_ALL[countDEVbus][a]=IDS_ALL[NUM_DEVICES-1][a];
            }
            countDEVbus++;
        }
         //DEBUG sprintf(cadena, "Dispositivos encontrados:%d", countDEVbus);
        //DEBUG USART_send_string (cadena);
 

        /*order to all the devices on the bus to perform a temp conversion*/
        /* A        OWI_DetectPresence(pins[b]);
        OWI_SendByte(OWI_ROM_SKIP, pins[b]);
        OWI_SendByte(DS1820_START_CONVERSION, pins[b]);
         while (OWI_ReadBit(pins[b])==0){
            _delay_us(100);
                    }
            */
        //break_point(1443, String_to_Send);
        //this loop will record the IDS and the temperatures on regtemp
        for(uint8_t q=0;q<countDEVbus;q++){
            //A t = ReadTemperature(pins[b],IDS[q]);
                    //A sprintf(cadena, "Leo dispositivo:%d", q);
             //A USART_send_string (cadena);


		if (showlist==1){
			/*send the data (activate if DEBUG to see the list of all found devices*/
            		sprintf(String_to_Send,"%d: %02X%02X%02X%02X%02X%02X%02X%02X \n",q+countDEV,IDS_ALL[q][0],IDS_ALL[q][1],IDS_ALL[q][2],IDS_ALL[q][3],IDS_ALL[q][4],IDS_ALL[q][5],IDS_ALL[q][6],IDS_ALL[q][7]);
	                for(int j=0;j<strlen(String_to_Send);j++) {
                		if(String_to_Send[j]!=('\n'||'\0')) { //only non terminating characters have to be sent
                     			USART0_Transmit(String_to_Send[j]);
               			 } //end if
            		} //end for j
			 
		}//end if 'showlist'
        } //A end for q
        } //A if((PD=OWI_DetectPresence(pins[b]))!=0) {
    }// end OWI_Init(pins[b]);

    //if (showlist==1){USART0_Transmit ('\n');}
    //break_point(1, String_to_Send); 
   

    return countDEVbus;
}
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
int MakeTempConversionOfAllDevices(uint8_t *pins) {

    int b=PIN_BUS;
    char cadena[100];
   

    PORTA |= 0x8;
     
           //OWI_MatchRom(id, bus);  // Match id founded earlier
       //OWI_SendByte(0x5A, bus); //PIO Access write command

    for(int b=0;b<PIN_BUS+1;b++) {
            //OWI_Init(pins[b]);
        if (OWI_DetectPresence(pins[b])==0){
            return -999; // Error
          }
       
        OWI_SendByte(OWI_ROM_SKIP, pins[b]);
        OWI_SendByte(DS1820_START_CONVERSION, pins[b]);
        while (OWI_ReadBit(pins[b])==0){
 
            //sprintf(cadena, "loop waiting for the conversion of all temperature sensors");
            //USART_send_string (cadena);
            _delay_us(100);
        }
    }
    return 1; //1=ok
}
//////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
int ADCsInitialization(uint8_t *pins){
    uint16_t receive_CRC;
    int b=PIN_BUS;
    //SET UP non parasitic mode:
    for(int b=0;b<PIN_BUS+1;b++) { //OWI_Init(pins[b]);
        if (OWI_DetectPresence(pins[b])==0){ // --> the "DetectPresence" function already sends a Reset.
            return -999; // Error
          }
        OWI_SendByte(OWI_ROM_SKIP, pins[b]);  //
            OWI_SendByte(0x55, pins[b]); //write memory
            OWI_SendByte(0x1C, pins[b]); //address for VCC powered mode
            OWI_SendByte(0x00, pins[b]);
            OWI_SendByte(0x40, pins[b]); //data for VCC powered mode
        receive_CRC = OWI_ReceiveByte(pins[b]); // <-- IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION
            receive_CRC |= (OWI_ReceiveByte(pins[b]) << 8); // <-- IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION

        //SET UP 3.3V _____RANGE______ on all ADCs:
                 //primero leo el valor del byte... Bueno, no hace falta porque se cual tiene que ser...
            //OWI_DetectPresence(pins[b]); // --> the "DetectPresence" function already sends a Reset.
        //OWI_SendByte(OWI_ROM_SKIP, pins[b]);  //
          //OWI_SendByte(DS2450_READ_MEMORY, bus);
        //OWI_SendByte(0x00, bus);   //Send two bytes address (ie: 0x00 & 0x00,0x08 & 0x00,0x10 & 0x00,0x18 & 0x00)
        //OWI_SendByte(0x00, bus);
                 //...y luego con una mascara le cambio el bit que quiero
         OWI_DetectPresence(pins[b]); // --> the "DetectPresence" function already sends a Reset.
        OWI_SendByte(OWI_ROM_SKIP, pins[b]);  //
            OWI_SendByte(0x55, pins[b]); //write memory
            OWI_SendByte(0x09, pins[b]); //address for range change
            OWI_SendByte(0x00, pins[b]);
            OWI_SendByte(0x8D, pins[b]); // RANGE: 0x8C-->2.55V / 0x8D-->5V // C=12=1100 / D=13=1101
        receive_CRC = OWI_ReceiveByte(pins[b]); // <-- IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION
            receive_CRC |= (OWI_ReceiveByte(pins[b]) << 8); // <-- IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION
                          //________________//
    }//for(int b=0;b<PIN_BUS+1;b++) {
}



//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
int MakeADCConversionOfAllDevices(uint8_t *pins){
    uint16_t receive_CRC;
    int value=0;
    int b=PIN_BUS;
    for(int b=0;b<PIN_BUS+1;b++) { //OWI_Init(pins[b]);
        if (OWI_DetectPresence(pins[b])==0){ // --> the "DetectPresence" function already sends a Reset.
            return -999; // Error
          }

        OWI_SendByte(OWI_ROM_SKIP, pins[b]);
        //OWI_SendByte(DS1820_START_CONVERSION, pins[b]);
        OWI_SendByte(DS2450_CONVERT, pins[b]); //conversión
        OWI_SendByte(0x0F, pins[b]); // Master selecciona "mask" (todos los canales)
        OWI_SendByte(0xAA, pins[b]); // Master selecciona "read-out control" // OJO FF ILLEGAL!
        receive_CRC = OWI_ReceiveByte(pins[b]);  // <-- IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION
            receive_CRC |= (OWI_ReceiveByte(pins[b]) << 8); // <-- IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION
       // while (OWI_ReadBit(pins[b])==0)

           value=0;
           while (value!=1)  //bucle that waits for the conversion to be done
        {
                 value=OWI_ReadBit(pins[b]);
        _delay_ms(10);
                 //sprintf(cadenatmp, "KKKK%02X", value);
          //USART_send_string (cadenatmp);
        }
    }//for(int b=0;b<PIN_BUS+1;b++)

}
///////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
int FindTemperatureDevicesAndGetValues(uint8_t *pins, int countDev){
 

    int q=0;
    int b=PIN_BUS;
     char String_to_Send[100], cadena[20];
    uint16_t valueTemperature;

    //sprintf(cadena, "Num dispositivos encontrados:%d", countDev);
    //USART_send_string (cadena);

  for(int b=0;b<PIN_BUS+1;b++) {
    //sprintf(cadena, "Leo dispositivo:%d", b);
    //USART_send_string (cadena);
    for (q=0;q<countDev;q++){
        if (IDS_ALL[q][0]==0x28){ //28 is the identifier for DS18B20 temperature devices
            //sprintf(cadena, "Dispositivo de temperatura:%d", q);
            //USART_send_string (cadena);
            valueTemperature = ReadTemperature(pins[b],IDS_ALL[q]);
                    //A sprintf(cadena, "Leo dispositivo:%d", q);
             //A USART_send_string (cadena);
            sprintf(String_to_Send," SENSOR TEMPERATURA (Num. %d): %02X%02X%02X%02X%02X%02X%02X%02X %0.4X% \n",q,IDS_ALL[q][0],IDS_ALL[q][1],IDS_ALL[q][2],IDS_ALL[q][3],IDS_ALL[q][4],IDS_ALL[q][5],IDS_ALL[q][6],IDS_ALL[q][7],valueTemperature); 

            /*send the data*/
            //break_point(444, String_to_Send);
            for(int j=0;j<strlen(String_to_Send);j++) {
                if(String_to_Send[j]!=('\n'||'\0')) {
                    /*only non terminating characters have to be sent*/
                    USART0_Transmit(String_to_Send[j]);
                    } //end if
            } //end for j
        } //(IDS_ALL[q][0]==0x28){
       

    }//for (q=0;q<NUM_DEVICES;q++){
  }//for(int b=0;b<PIN_BUS+1;b++) {
    return (1);
}


/*
 *  this function will read the ID´s and temperatures of a certain number of
 * devices limited between 1 and NUM-DEVICES and will send the data through
 *  USART register
 * the function will return the number of devices on the bus
 * t is an array used for the storage of the temperatures values
 * 
*/
int TempStored (uint8_t *pins) {
    uint16_t t;
    char PD;
    uint8_t IDS[NUM_DEVICES][8]; //IDS is a 2D array used for storage the sensors ID´s
    int countDEV = 0;  //number of devices
    int countDEVbus=0; //number of devices on the current bus
    char cadena[100];
/*  on String_to_Send is written the data to be sent away*/
    char String_to_Send[30];  //27 should be enough

    PORTA |= 0x8;

/*clean one IDS array*/
    for(int a=0; a<7;a++){
        IDS[NUM_DEVICES-1][a]=0;
    }
    for(int b=0;b<1;b++) {
/*initialize the bus*/
    sprintf(cadena, "Bus inicializado");
    USART_send_string (cadena);

    OWI_Init(pins[b]);
    uint8_t res=1;
    countDEV = countDEV + countDEVbus;
    countDEVbus=0;//reset number of devices on the bus

    //break_point(PD, "presence");
    if((PD=OWI_DetectPresence(pins[b]))!=0) {
//this will search the devices Id´s till the max number of devices is reached or
// all the devices have been read out
        //break_point(PD, "presence");
        //break_point(countDEVbus, "Cound DEV bus");
        while(countDEVbus<NUM_DEVICES&&res!=OWI_ROM_SEARCH_FINISHED){
        if(countDEVbus==0){
         sprintf(cadena, "Dispositivo 0");
          USART_send_string (cadena);
            res=0;
        }
        OWI_DetectPresence(pins[b]);
        res=OWI_SearchRom(IDS[NUM_DEVICES-1], res, pins[b]);
        //break_point(res, "search ROM");
        for(int a=0;a<8;a++){
            IDS[countDEVbus][a]=IDS[NUM_DEVICES-1][a];
        }
        countDEVbus++;
        }
         sprintf(cadena, "Dispositivos encontrados:%d", countDEVbus);
          USART_send_string (cadena);
/*order to all the devices on the bus to perform a temp conversion*/
        OWI_DetectPresence(pins[b]);
        OWI_SendByte(OWI_ROM_SKIP, pins[b]);
        OWI_SendByte(DS1820_START_CONVERSION, pins[b]);
        while (OWI_ReadBit(pins[b])==0)
        {
        _delay_us(100);
        }
    //break_point(1443, String_to_Send);
//this loop will record the IDS and the temperatures on regtemp
        for(uint8_t q=0;q<countDEVbus;q++){
        t = ReadTemperature(pins[b],IDS[q]);
                  sprintf(cadena, "Leo dispositivo:%d", countDEVbus);
          USART_send_string (cadena);
        sprintf(String_to_Send,"AVER%d: %02X%02X%02X%02X%02X%02X%02X%02X %.4X ",q+countDEV,IDS[q][0],IDS[q][1],IDS[q][2],IDS[q][3],IDS[q][4],IDS[q][5],IDS[q][6],IDS[q][7],t);

/*send the data*/
        //break_point(444, String_to_Send);
        for(int j=0;j<strlen(String_to_Send);j++) {
            if(String_to_Send[j]!=('\n'||'\0')) {
/*only non terminating characters have to be sent*/
            //break_point(443, String_to_Send);
            USART0_Transmit(String_to_Send[j]);
            }
        }
        }
    }
    }

   
    //break_point(1, String_to_Send); 
    USART0_Transmit ('\n');

    return countDEV;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////

//int ReadDualSwitches ( unsigned char bus, unsigned char * id, uint16_t *array_chn ) {
int ReadDualSwitches ( unsigned char bus, unsigned char * id, uint8_t *array_chn ) {
char cadenatmp[100];
uint16_t ValueReceived;
    
        if (OWI_DetectPresence(bus)==0)
        {
        return -999; // Error
        }
        OWI_MatchRom(id, bus);  // Match id founded earlier
        OWI_SendByte(0xFF5, bus); //PIO Access read command
	
        // Read two first bytes and place them in the 16 bit channel variable.
        array_chn[0] = OWI_ReceiveByte(bus);
        array_chn[0] |= (OWI_ReceiveByte(bus) << 8);
 
   /*     array_chn[1] = OWI_ReceiveByte(bus);
          array_chn[1] |= (OWI_ReceiveByte(bus) << 8);
   */

       // sprintf(cadenatmp, "PPPP %02X", array_chn[1]);
       // USART_send_string (cadenatmp);

        if (OWI_DetectPresence(bus)==0)
        {
        return -999; // Error
        }

    return 1;  //1=OK


}

//////////////////////////////////////////////////
//////////////////////////////////////////////////
/////////////////////////////////////////////////


int SetOnDoubleSwitch ( unsigned char bus, unsigned char * id, uint16_t *array_chn ) {
char cadenatmp[100];
uint16_t ValueReceived;
    
        if (OWI_DetectPresence(bus)==0)
        {
        return -999; // Error
        }
       OWI_MatchRom(id, bus);  // Match id founded earlier
       OWI_SendByte(0x5A, bus); //PIO Access write command
        //DUAL:A:ON B:OFF /SINGLE:OFF? --> FA+05          LEO:3CAAFFFF
        //DUAL:AMBOS SWITCHES OFF / SINGLE:ON?  -->FB+04  LEO:0FAAFFFF
        //DUAL:AMBOS SWITCHES ON / SINGLE:ON?  -->FC+03   LEO:F0AAFFFF
        //DUAL:A:OFF B:ON /SINGLE:ON? --> FD+02           LEO:C3AAFFFF
        //(3ACFDA0100000048 <-- DIRECCION LEIDA)
        //(FC=1111 1101) AL ESCRIBIR IMPORTA LOS ULTIMOS 2 BITS:
        //...EL BIT ULTIMO HACE REFERENCIA AL CANAL 'A' Y EL PENULTIMO AL CANAL 'B'
        //...CANAL A 1 SIGNIFICA SWITCH A OFF Y VICEVERSA.
        //OJO!: EL SINGLE SE PONE A OFF CUANDO SE PROGRAMA EL MICROCONTROLADOR!!!!
        //SOLO INTERESA EL PRIMER BYTE DE LO LEIDO (QUE CONTIENE EL ESTADO Y EL ESTADO INVERTIDO)
     OWI_SendByte(0xFB, bus); //Write new PIO output state
    OWI_SendByte(0x04, bus); //Write inverted new PIO output state
    // Read two first bytes and place them in the 16 bit channel variable.
    array_chn[0] = OWI_ReceiveByte(bus);
    array_chn[0] |= (OWI_ReceiveByte(bus) << 8);
 
    array_chn[1] = OWI_ReceiveByte(bus);
    array_chn[1] |= (OWI_ReceiveByte(bus) << 8);
   

    sprintf(cadenatmp, "PPPP %02X", array_chn[1]);
          USART_send_string (cadenatmp);

        if (OWI_DetectPresence(bus)==0)
        {
        return -999; // Error
        }

    return 1;  //1=OK


}

//int WriteDualSwitch (unsigned char bus, unsigned char * id, uint16_t *array_chn, int channelA, int channelB ) {
int WriteDualSwitch (uint8_t *pins, unsigned char * id, uint16_t *array_chn, int channelA, int channelB ) {
char cadenatmp[100];
uint16_t ValueReceived;
	//sprintf(cadenatmp, "Ha entrado en la función");
        //USART_send_string (cadenatmp);
    	
      if (OWI_DetectPresence(pins[0])==0)
        {
		//sprintf(cadenatmp, "No presence bus");
        	//USART_send_string (cadenatmp);
        	return -999; // Error
		
        }

	//OWI_DetectPresence(pins[0]);
	//sprintf(cadenatmp, "Si presence bus");
        //USART_send_string (cadenatmp);
        OWI_MatchRom(id, pins[0]);  // Match id founded earlier
        OWI_SendByte(0x5A, pins[0]); //PIO Access write command
        //DUAL:A:ON B:OFF /SINGLE:OFF? --> FA+05          LEO:3CAAFFFF
        //DUAL:AMBOS SWITCHES OFF / SINGLE:ON?  -->FB+04  LEO:0FAAFFFF
        //DUAL:AMBOS SWITCHES ON / SINGLE:ON?  -->FC+03   LEO:F0AAFFFF
        //DUAL:A:OFF B:ON /SINGLE:ON? --> FD+02           LEO:C3AAFFFF
        //(3ACFDA0100000048 <-- DIRECCION LEIDA)
        //(FC=1111 1101) AL ESCRIBIR IMPORTA LOS ULTIMOS 2 BITS:
        //...EL BIT ULTIMO HACE REFERENCIA AL CANAL 'A' Y EL PENULTIMO AL CANAL 'B'
        //...CANAL A 1 SIGNIFICA SWITCH A OFF Y VICEVERSA.
        //OJO!: EL SINGLE SE PONE A OFF CUANDO SE PROGRAMA EL MICROCONTROLADOR!!!!
        //SOLO INTERESA EL PRIMER BYTE DE LO LEIDO (QUE CONTIENE EL ESTADO Y EL ESTADO INVERTIDO)
	if (channelA==1 && channelB==1) { //both channels off
	     	OWI_SendByte(0xFB, pins[0]); //Write new PIO output state
    		OWI_SendByte(0x04, pins[0]); //Write inverted new PIO output state 
	}

	if (channelA==1 && channelB==0) {  //channel A off, channel B on
	     	OWI_SendByte(0xFD,pins[0]); //Write new PIO output state
    		OWI_SendByte(0x02, pins[0]); //Write inverted new PIO output state 
	}

	if (channelA==0 && channelB==1) { //channel A on, channel B off
	     	OWI_SendByte(0xFA, pins[0]); //Write new PIO output state
    		OWI_SendByte(0x05, pins[0]); //Write inverted new PIO output state 
	}

	if (channelA==0 && channelB==0) {  //both channels on
	     	OWI_SendByte(0xFC, pins[0]); //Write new PIO output state
    		OWI_SendByte(0x03, pins[0]); //Write inverted new PIO output state 
	//sprintf(cadenatmp, "llwga00", array_chn[1]);
        //USART_send_string (cadenatmp);
	}
	
    // Read two first bytes and place them in the 16 bit channel variable.
    array_chn[0] = OWI_ReceiveByte(pins[0]);
    array_chn[0] |= (OWI_ReceiveByte(pins[0]) << 8);
 
    array_chn[1] = OWI_ReceiveByte(pins[0]);
    array_chn[1] |= (OWI_ReceiveByte(pins[0]) << 8);
   

    //sprintf(cadenatmp, "PPPP %02X", array_chn[1]);
    //USART_send_string (cadenatmp);

        if (OWI_DetectPresence(pins[0])==0)
        {
        return -999; // Error
        }

    return 1;  //1=OK


}
//////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////

int ReadADCchannels(unsigned char bus, unsigned char * id, uint16_t *array_chn, const int size )
 

{

    char cadenatmp[100];

    
        if (OWI_DetectPresence(bus)==0)
        {
        return -999; // Error
        }
        
        OWI_MatchRom(id, bus);  // Match id founded earlier
       OWI_SendByte(DS2450_READ_MEMORY, bus);
     OWI_SendByte(0x00, bus);   //Send two bytes address (ie: 0x00 & 0x00,0x08 & 0x00,0x10 & 0x00,0x18 & 0x00)
     OWI_SendByte(0x00, bus);


    // Read two first bytes and place them in the 16 bit channel variable.
    array_chn[0] = OWI_ReceiveByte(bus);
    array_chn[0] |= (OWI_ReceiveByte(bus) << 8);
 
    array_chn[1] = OWI_ReceiveByte(bus);
    array_chn[1] |= (OWI_ReceiveByte(bus) << 8);
     
    array_chn[2] = OWI_ReceiveByte(bus);
    array_chn[2] |= (OWI_ReceiveByte(bus) << 8);

    array_chn[3] = OWI_ReceiveByte(bus);
    array_chn[3] |= (OWI_ReceiveByte(bus) << 8);
   

//sprintf(cadenatmp, "PPPP %02X", array_chn[1]);
//          USART_send_string (cadenatmp);

    return 1;  //1=OK
}

int DoubleSwitch (uint8_t *pins) {
    uint16_t t,IDS_VALUE[NUM_DEVICES][16],receive_CRC, KK;
    char PD;
    uint8_t IDS[NUM_DEVICES][8],value;
    int countDEV = 0, i=0;//number of devices
    int countDEVbus=0;//number of devices on the current bus
    char cadena[100], cadenatmp[500];
/*on String_to_Send are written the data to be sent away*/
    char String_to_Send[100];//27 should be enough

    PORTA |= 0x8;
    KK=0x11;

/*clean one IDS array*/
    for(int a=0; a<7;a++){
        IDS[NUM_DEVICES-1][a]=0;
    }
    for(int b=0;b<1;b++) {

//initialize IDS_VALUE array
for(int a=0; a<16;a++){
        IDS_VALUE[NUM_DEVICES-1][a]=0;
    }

/*initialize the bus*/
    OWI_Init(pins[b]);
    uint8_t res=1;
    countDEV = countDEV + countDEVbus;
    countDEVbus=0;//reset number of devices on the bus

    //break_point(PD, "presence");
    if((PD=OWI_DetectPresence(pins[b]))!=0) {
//this will search the devices Id´s till the max number of devices is reached or
// all the devices have been read out
        //break_point(PD, "presence");
        //break_point(countDEVbus, "Cound DEV bus");
        while(countDEVbus<NUM_DEVICES&&res!=OWI_ROM_SEARCH_FINISHED){
        if(countDEVbus==0){
         sprintf(cadena, "Dispositivo 0");
          USART_send_string (cadena);
            res=0;

               
        }
        OWI_DetectPresence(pins[b]);
        res=OWI_SearchRom(IDS[NUM_DEVICES-1], res, pins[b]);
        //break_point(res, "search ROM");
        for(int a=0;a<8;a++){
            IDS[countDEVbus][a]=IDS[NUM_DEVICES-1][a];
        }
        countDEVbus++;
        }
         sprintf(cadena, "Dispositivos encontrados:%d", countDEVbus);
          USART_send_string (cadena);
/*order to all the devices on the bus to perform a temp conversion*/
        //OWI_ResetPulse(bus); //ALEX
      
        for(uint8_t q=0;q<countDEVbus;q++){
                        i= SetOnDoubleSwitch(pins[b], IDS[q], IDS_VALUE[q]); 
                       
           
                                                
        //}
        sprintf(cadena, "\n Leo dispositivo:%d", countDEVbus);
         sprintf(String_to_Send," SENSORRS %d: %02X%02X%02X%02X%02X%02X%02X%02X %.4X%.4X%.4X%.4X%.4X%.4X%.4X%.4X%.4X%.4X%.4X%.4X%.4X%0.4X%.4X%.4X ",q+countDEV,IDS[q][0],IDS[q][1],IDS[q][2],IDS[q][3],IDS[q][4],IDS[q][5],IDS[q][6],IDS[q][7],IDS_VALUE[q][0],IDS_VALUE[q][1],IDS_VALUE[q][2],IDS_VALUE[q][3],IDS_VALUE[q][4],IDS_VALUE[q][5],IDS_VALUE[q][6],IDS_VALUE[q][7],IDS_VALUE[q][8],IDS_VALUE[q][9],IDS_VALUE[q][10],IDS_VALUE[q][11],IDS_VALUE[q][12],IDS_VALUE[q][13],IDS_VALUE[q][14],IDS_VALUE[q][15]); 

/*send the data*/
        //break_point(444, String_to_Send);
        for(int j=0;j<strlen(String_to_Send);j++) {
            if(String_to_Send[j]!=('\n'||'\0')) {
/*only non terminating characters have to be sent*/
            //break_point(443, String_to_Send);
            USART0_Transmit(String_to_Send[j]);
            }
        }
        }
    }
    }

   
    //break_point(1, String_to_Send); 
    USART0_Transmit ('\n');

    return countDEV;
}

/*

/******************************************************************************
******************************************************************************
******************************************************************************
*/
uint16_t ReadVoltage(unsigned char bus, unsigned char * id, int cont)
{
    uint16_t voltage;

    if (cont==0) //The reset, matchrom and SendByte are only sent the first time for each device.
    {         
        if (OWI_DetectPresence(bus)==0)
        {
        return -999; // Error
        }
        
        OWI_MatchRom(id, bus);  // Match id founded earlier
       OWI_SendByte(DS2450_READ_MEMORY, bus);
     OWI_SendByte(0x00, bus);   //Send to bytes after the read command (ie: 0x00 & 0x00,0x08 & 0x00,0x10 & 0x00,0x18 & 0x00)
     OWI_SendByte(0x00, bus);
    }

    // Read only two first bytes and place them in the 16 bit temperature variable.
    voltage = OWI_ReceiveByte(bus);
    voltage |= (OWI_ReceiveByte(bus) << 8);
    return voltage;
}


/*  ADC
 *  this function will read the ID´s and temperatures of a certain number of
 * devices limited between 1 and NUM-DEVICES and will send the data through
 *  USART register
 * the function will return the number of devices on the bus
 * t is an array used for the storage of the VOLTAGE values
 * IDS is a 2D array used for storage the sensors ID´s
*/
int VoltageStored (uint8_t *pins) {
    uint16_t t,IDS_VALUE[NUM_DEVICES][16],receive_CRC, KK;
    char PD;
    uint8_t IDS[NUM_DEVICES][8],value;
    int countDEV = 0, i=0;//number of devices
    int countDEVbus=0;//number of devices on the current bus
    char cadena[100], cadenatmp[500];
/*on String_to_Send are written the data to be sent away*/
    char String_to_Send[100];//27 should be enough

    PORTA |= 0x8;
    KK=0x11;

/*clean one IDS array*/
    for(int a=0; a<7;a++){
        IDS[NUM_DEVICES-1][a]=0;
    }
    for(int b=0;b<1;b++) {

//initialize IDS_VALUE array
for(int a=0; a<16;a++){
        IDS_VALUE[NUM_DEVICES-1][a]=0;
    }

/*initialize the bus*/
    OWI_Init(pins[b]);
    uint8_t res=1;
    countDEV = countDEV + countDEVbus;
    countDEVbus=0;//reset number of devices on the bus

    //break_point(PD, "presence");
    if((PD=OWI_DetectPresence(pins[b]))!=0) {
//this will search the devices Id´s till the max number of devices is reached or
// all the devices have been read out
        //break_point(PD, "presence");
        //break_point(countDEVbus, "Cound DEV bus");
        while(countDEVbus<NUM_DEVICES&&res!=OWI_ROM_SEARCH_FINISHED){
        if(countDEVbus==0){
         sprintf(cadena, "Dispositivo 0");
          USART_send_string (cadena);
            res=0;

               
        }
        OWI_DetectPresence(pins[b]);
        res=OWI_SearchRom(IDS[NUM_DEVICES-1], res, pins[b]);
        //break_point(res, "search ROM");
        for(int a=0;a<8;a++){
            IDS[countDEVbus][a]=IDS[NUM_DEVICES-1][a];
        }
        countDEVbus++;
        }
         sprintf(cadena, "Dispositivos encontrados:%d", countDEVbus);
          USART_send_string (cadena);
/*order to all the devices on the bus to perform a temp conversion*/
        //OWI_ResetPulse(bus); //ALEX
      

        //SET UP non parasitic mode:
         OWI_DetectPresence(pins[b]); // --> the "DetectPresence" function already sends a Reset.
        OWI_SendByte(OWI_ROM_SKIP, pins[b]);  //
            OWI_SendByte(0x55, pins[b]); //write memory
            OWI_SendByte(0x1C, pins[b]); //address for VCC powered mode
            OWI_SendByte(0x00, pins[b]);
            OWI_SendByte(0x40, pins[b]); //data for VCC powered mode
        receive_CRC = OWI_ReceiveByte(pins[b]); // <-- IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION
            receive_CRC |= (OWI_ReceiveByte(pins[b]) << 8); // <-- IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION

        //SET UP 3.3V _____RANGE______ on all ADCs:
                 //primero leo el valor del byte... Bueno, no hace falta porque se cual tiene que ser...
            //OWI_DetectPresence(pins[b]); // --> the "DetectPresence" function already sends a Reset.
        //OWI_SendByte(OWI_ROM_SKIP, pins[b]);  //
          //OWI_SendByte(DS2450_READ_MEMORY, bus);
        //OWI_SendByte(0x00, bus);   //Send two bytes address (ie: 0x00 & 0x00,0x08 & 0x00,0x10 & 0x00,0x18 & 0x00)
        //OWI_SendByte(0x00, bus);
                 //...y luego con una mascara le cambio el bit que quiero
         OWI_DetectPresence(pins[b]); // --> the "DetectPresence" function already sends a Reset.
        OWI_SendByte(OWI_ROM_SKIP, pins[b]);  //
            OWI_SendByte(0x55, pins[b]); //write memory
            OWI_SendByte(0x09, pins[b]); //address for range change
            OWI_SendByte(0x00, pins[b]);
            OWI_SendByte(0x8D, pins[b]); // RANGE: 0x8C-->2.55V / 0x8D-->5V // C=12=1100 / D=13=1101
        receive_CRC = OWI_ReceiveByte(pins[b]); // <-- IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION
            receive_CRC |= (OWI_ReceiveByte(pins[b]) << 8); // <-- IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION
                          //________________//

        OWI_DetectPresence(pins[b]);
        OWI_SendByte(OWI_ROM_SKIP, pins[b]);
        //OWI_SendByte(DS1820_START_CONVERSION, pins[b]);
        OWI_SendByte(DS2450_CONVERT, pins[b]); //conversión
        OWI_SendByte(0x0F, pins[b]); // Master selecciona "mask" (todos los canales)
        OWI_SendByte(0xAA, pins[b]); // Master selecciona "read-out control" // OJO FF ILLEGAL!
        receive_CRC = OWI_ReceiveByte(pins[b]);  // <-- IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION
            receive_CRC |= (OWI_ReceiveByte(pins[b]) << 8); // <-- IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION
       // while (OWI_ReadBit(pins[b])==0)

           value=0;
           while (value!=1)  //bucle that waits for the conversion to be done
        {
                 value=OWI_ReadBit(pins[b]);
        _delay_ms(10);
                 sprintf(cadenatmp, "KKKK%02X", value);
          USART_send_string (cadenatmp);
        }
    //break_point(1443, String_to_Send);
//this loop will record the IDS and the temperatures on regtemp
            //countDEVbus=2; //ALEX-->LIMITA a dos los dispositivos encontrados
        for(uint8_t q=0;q<countDEVbus;q++){
        //for (int i=0; i<16; i++)
        //{
           
            //IDS_VALUE[q][i] = ReadVoltage(pins[b],IDS[q],i);
                        i= ReadADCchannels(pins[b], IDS[q], IDS_VALUE[q],4);  //4 is the number of channels per chip
 

                       
           
                                                
        //}
        sprintf(cadena, "\n Leo dispositivo:%d", countDEVbus);
         sprintf(String_to_Send," SENSORRS %d: %02X%02X%02X%02X%02X%02X%02X%02X %.4X%.4X%.4X%.4X%.4X%.4X%.4X%.4X%.4X%.4X%.4X%.4X%.4X%0.4X%.4X%.4X ",q+countDEV,IDS[q][0],IDS[q][1],IDS[q][2],IDS[q][3],IDS[q][4],IDS[q][5],IDS[q][6],IDS[q][7],IDS_VALUE[q][0],IDS_VALUE[q][1],IDS_VALUE[q][2],IDS_VALUE[q][3],IDS_VALUE[q][4],IDS_VALUE[q][5],IDS_VALUE[q][6],IDS_VALUE[q][7],IDS_VALUE[q][8],IDS_VALUE[q][9],IDS_VALUE[q][10],IDS_VALUE[q][11],IDS_VALUE[q][12],IDS_VALUE[q][13],IDS_VALUE[q][14],IDS_VALUE[q][15]); 

/*send the data*/
        //break_point(444, String_to_Send);
        for(int j=0;j<strlen(String_to_Send);j++) {
            if(String_to_Send[j]!=('\n'||'\0')) {
/*only non terminating characters have to be sent*/
            //break_point(443, String_to_Send);
            USART0_Transmit(String_to_Send[j]);
            }
        }
        }
    }
    }

   
    //break_point(1, String_to_Send); 
    USART0_Transmit ('\n');

    return countDEV;
}

/*
 *this function initialize the USART 0 register needed to allow the at90can128
 *USART transmissions
 */
void
USART0_Init (unsigned int baud)
{
  // no tx are possible when the inizialization is going on.
  // if is possible, use TXC0 flag.

  // interruption should be disabled (cli())
  uint8_t intstate = SREG;
  cli ();
  /*
   * the TXC flag bit is set 1 when the entire frame in the Transmit
   * Shift Register has been shifted out and there are no new data
   * currently present in the transmit buffer
   */
  while (0 << TXC0)
    {
    }
  /*
   * set baud rate
   */
  UBRR0H = (uint8_t) (baud >> 8);
  UBRR0L = (uint8_t) (baud);
  /*
   * set frame format: I will set it now as 8 bits, no parity 1 stop bit
   */
  UCSR0C = (0 << UMSEL0) | (0 << UPM0) | (0 << USBS0) | (3 << UCSZ0);
  /*
   * enable transmitter and interrupt at receive
   */
  UCSR0B = (1 << TXEN0) | (1 << RXEN0) | (1 << RXCIE0);
  SREG = intstate;
}


void
Init (void)
{

  uint8_t intstate = SREG;
  cli ();

  // use port A as output
  DDRA = 0xFF;
  PORTA = 0x00;


  // use port B as input with activated pullups
  DDRB = 0x00;
  PORTB = 0xFF;

  // use port C as input with deactivated pullups
  //DDRC = 0x03;
  //PORTC = 0x00;

 // use port C as output
  DDRC = 0xFF;
  PORTC = 0x00;

  // use port E as input with activated pullups
  DDRE = 0x00;
  PORTE = 0xFF;

  // use port F as input with ctivated pullups
  DDRF = 0x00;
  PORTF = 0xFF;

  // enable ADC and set clock prescale factor to 64 (p.280)
  ADCSRA = BIT (ADEN) | 0x06;
  // 0x80 => ADEN => enable ADC

  //break_point(BIT(ADEN) | 0x06, "hhallo");

  // low speed and manually triggered ADC conversion mode
  ADCSRB = 0;

  // deactivate digital input buffer for used ADC pins
#ifdef DISABLE_JTAG
  DIDR0 = 0xFF;
  //MCUCR |= 0x80;   // deactivate whole JTAG interface
#else
  DIDR0 = 0x0F;
#endif

  // enable only compare match interrupt on timer 1, channel A
  TIMSK1 = 0x02;

  // normal counter mode (no wave and/or PWM stuff) for timer 1, channel A
  TCCR1A = 0;
  TCCR1C = 0;

  SREG = intstate;

}                // End of Init




/*
 * USART0 must be initialized before using this function, if data is longer
 * than 8bit, properly working is not assured
 */
uint8_t
USART0_Receive (void)
{
    uint16_t count = 0;
  /*
   * Wait for data to be received
   */
  while ( !(UCSR0A & (1 << RXC0))  && count < 5000 ) {
      count++;
      _delay_ms(1);
  }

  if(count>1000) {
     // break_point (count, "count too large");
      
  }

  /*
   * Get and return received data from buffer
   */
  return UDR0;
}



int
USART_send_string (char *str)
{
  uint16_t j;

  for (j = 0; j < strlen ((char *) str) && j < 80; j++)
    {
      USART0_Transmit (str[j]);
    }
  USART0_Transmit ('\n');

  return 0;
}

void
toggle_pin (unsigned char pin_number)
{
  // USART_send_string("toggle pin called");

  long int i, c, d;
  _delay_ms (10);
  for (i = 0; i <= 50; i++)
    {
      _delay_ms (10);
      d = d + i * c;
      c = d + i;
    }

  // toggle FrontLED
  PINA = 0x3;


}


enum
{
  eNoError = 0,
  eWrongCANAddress = 1,        // bogus address set on hex-switches
  eCANDataSize = 2,        // bogus amount of bytes arrived
  eI2CTimeout = 4,        // I²C problem
  eI2CFatalError = 8,        // I²C problem
  eI2CRetryFailed = 16,        // I²C problem
  eADCTimeout = 32,        // ADC conversion failed
  eCPLDAcknowledgeTimeout = 64    // CPLD communication problem
} ErrorCodes;

uint16_t Voltages[8];        // current supply voltages of the board

int
GetVoltage (unsigned int channel_nr)
{
  uint16_t Timeout;
  uint16_t Value;
  uint16_t iStep;
  int16_t TotalValue;

#ifndef DISABLE_JTAG
  // we need the JTAG interface, thus do not measure
  // the upper four ADC channels (used for JTAG, too)
  if (channel_nr > 3)
    {
      Voltages[channel_nr] = 0;
      return eNoError;
    }
#endif

  // use 3.3V supply voltage as reference voltage
  // and select the voltage to be measured
  ADMUX = 0x40 | (unsigned char) channel_nr;
  //ADMUX = 0x40 | 0x1B;

  TotalValue = 0;
  for (iStep = 0; iStep < ADC_CYCLES; iStep++)
    {
      // start a new single conversion
      ADCSRA |= BIT (ADSC);

      // wait until conversion is complete
      Timeout = ADC_TIMEOUT;
      while (!(ADCSRA & BIT (ADIF)) && (--Timeout > 0));

      // clear interrupt flag from former conversion
      ADCSRA |= BIT (ADIF);

      if (Timeout == 0)
    {
      return eADCTimeout;
    }

      // one must read ADCL before ADCH!
      Value = ADCL;
      Value |= (unsigned int) (ADCH & 0x03) << 8;

      //break_point(Value, "value");

      TotalValue += Value;
    }

  TotalValue = TotalValue / 3;

  // save results
  Voltages[channel_nr] = (uint16_t) TotalValue;

  return eNoError;
}

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////

int FindFamilyDevicesAndGetValues(uint8_t *pins, int countDev, uint8_t familyID){
    int q=0, i=0;
    int b=PIN_BUS;
     char String_to_Send[100], cadena[20];
    uint16_t readValue, zeroValue=0x00;
    uint8_t readVal8=0;


    //sprintf(cadena, "Num dispositivos encontrados:%d", countDev);
    //USART_send_string (cadena);

  for(int b=0;b<PIN_BUS+1;b++) {
    //sprintf(cadena, "Leo dispositivo:%d", b);
    //USART_send_string (cadena);
    for (q=0;q<countDev;q++){
        if (IDS_ALL[q][0]==familyID){ //ie: 28 is the identifier for DS18B20 temperature devices
            //sprintf(cadena, "Dispositivo de temperatura:%d", q);
	    //USART_send_string (cadena);
//#define FAMILY_DS2450_ADC    0x20
//#define FAMILY_DS18B20_TEMP     0x28
//#define FAMILY_DS2413_DUAL_SWITCH 0x13
            if (familyID==FAMILY_DS18B20_TEMP){
            //sprintf(cadena," SENSOR TEMPERATURA (Num. %d):",q);
            //USART_send_string (cadena);
            readValue = ReadTemperature(pins[b],IDS_ALL[q]);
	    /*if (readValue!=1){

                 sprintf(cadena, "Error reading temperatures", q);
                 USART_send_string (cadena);
                 return 0;
            }
	    */
            sprintf(String_to_Send,"%d: %02X%02X%02X%02X%02X%02X%02X%02X %.4X%\n",q, IDS_ALL[q][0],IDS_ALL[q][1],IDS_ALL[q][2],IDS_ALL[q][3],IDS_ALL[q][4],IDS_ALL[q][5],IDS_ALL[q][6],IDS_ALL[q][7],readValue);
	    //USART_send_string (String_to_Send);

            }

            else if (familyID==FAMILY_DS2450_ADC){
            
            	//sprintf(cadena," ADC (Num. %d):",q);
            	//USART_send_string (cadena);
            	readValue= ReadADCchannels(pins[b], IDS_ALL[q], IDS_ALL_VALUES[q],4);
            	if (readValue!=1){

                    sprintf(cadena, "Error reading ADC channels", q);
                     USART_send_string (cadena);
                    return 0;
             	}
                sprintf(String_to_Send,"%d: %02X%02X%02X%02X%02X%02X%02X%02X %.4X %.4X %.4X %.4X%\n",q, IDS_ALL[q][0],IDS_ALL[q][1],IDS_ALL[q][2],IDS_ALL[q][3],IDS_ALL[q][4],IDS_ALL[q][5],IDS_ALL[q][6],IDS_ALL[q][7],IDS_ALL_VALUES[q][0],IDS_ALL_VALUES[q][1],IDS_ALL_VALUES[q][2],IDS_ALL_VALUES[q][3]);
            	//USART_send_string (String_to_Send);

            }
           
	    else if (familyID==FAMILY_DS2413_DUAL_SWITCH){
            	//ALEX//
            	//sprintf(cadena," DUAL SWITCH (Num. %d):",q);
            	//USART_send_string (cadena);
           	 //readValue= ReadDualSwitches(pins[b], IDS_ALL[q], IDS_ALL_VALUES[q]);
		readValue= ReadDualSwitches(pins[b], IDS_ALL[q], &readVal8);
           	 /*if (readValue!=1){

                    sprintf(cadena, "Error reading Dual switches", q);
                     USART_send_string (cadena);
                    return 0;
             	}
		*/
	     
             	sprintf(String_to_Send,"%d: %02X%02X%02X%02X%02X%02X%02X%02X %.2X\n",q, IDS_ALL[q][0],IDS_ALL[q][1],IDS_ALL[q][2],IDS_ALL[q][3],IDS_ALL[q][4],IDS_ALL[q][5],IDS_ALL[q][6],IDS_ALL[q][7],readVal8);
            	//USART_send_string (String_to_Send);
	
                
           }

           else {return 0; }
                    //A sprintf(cadena, "Leo dispositivo:%d", q);
             //A USART_send_string (cadena);
            // 

 

            /*send the data*/
            //break_point(444, String_to_Send);
           for(int j=0;j<strlen(String_to_Send);j++) {
                if(String_to_Send[j]!=('\n'||'\0')) {
                    /*only non terminating characters have to be sent*/
                    USART0_Transmit(String_to_Send[j]);
                    } //end if
            } //end for j
        } //(IDS_ALL[q][0]==0x28){
       

    }//for (q=0;q<NUM_DEVICES;q++){
  }//for(int b=0;b<PIN_BUS+1;b++) {
    return (1);
}

/////////////////////////////////////////////////////77
/////////////////////////////////////////////////////////
static uint8_t ascii2byte(char *val)
{
    uint8_t temp = *val;
    
    if(temp > 0x60) temp -= 39;  // convert chars a-f
	temp -= 48;  // convert chars 0-9
	temp *= 16;
    
    temp += *(val+1);
    if(*(val+1) > 0x60) temp -= 39;  // convert chars a-f
	temp -= 48;  // convert chars 0-9	

    return temp;

}


 
enum states {idle, below_low_thres, in_between , above_high_thres };
uint8_t cur_state;

int main (void)
{
  /*
   * connected brate is the serial transmission baud rate regtemp is a
   * usercommand is the command that defines what action to perform
   */
  //
  // the definitions
  // of signed int


  uint8_t i;
  uint16_t res;
  char str[80];

  cur_state = idle;

 
  USART0_Init (BAUD);

  Init ();

  _delay_ms (10);

  // ALEX COMMENTED USART_send_string ("please give command");

  _delay_ms (10);

  cli();

//  break_point (1, "before enable interrupt");  high

  // enable interrupts
  sei();

//  break_point (1, "after enable interrupt"); 

  res = GetVoltage (0);

  PORTA = PORTA | (0x2); // turn on lamp

  if(Voltages[0] < tlow) {
      cur_state = below_low_thres;
      //PORTA = PORTA | (0x1); // turn on relais
      PORTA = PORTA & (~0x1); // turn off relais
  }
  else if(Voltages[0] > thigh) {
      cur_state = above_high_thres;
      //PORTA = PORTA | (0x1); // turn on relais
      PORTA = PORTA & (~0x1); // turn off relais
  }
  else {
      cur_state = in_between;
      PORTA = PORTA | (0x1); // turn on relais
  }

  //sprintf(str, "cur_state: %d", cur_state);
  //break_point (res, str); 

  while (1) {
      res = GetVoltage (0);
     
      /*
      if(res != eNoError) {
      Voltages[0]=1222;
      }
      */

      switch (cur_state) {
      case in_between:      
      {
          if(Voltages[0] > thigh) {
          // turn off relais
          //break_point (res, "above threshold"); 
          PORTA = PORTA & (~0x1);
          cur_state = above_high_thres;
          }
          if(Voltages[0] < tlow) {
          // turn off relais
          //break_point (res, "above threshold"); 
          PORTA = PORTA & (~0x1);
          cur_state = below_low_thres;
          }
      }
      break;
      case below_low_thres:      
      {
          _delay_ms(100);
          _delay_ms(100);
          PINA = 0x2; // toggle LED

          if(Voltages[0] > tlow +2) {
          // turn on relais
          PORTA = PORTA | (0x3);
          cur_state = in_between;
          }
      }
      break;
      case above_high_thres:
      {

          _delay_ms(100);
          _delay_ms(100);
          PINA = 0x2; // toggle LED

          //break_point (res, "above threshold"); 
          if(Voltages[0] < thigh -2) {
          // turn on relais and lamp
          PORTA = PORTA | (0x3);
            cur_state = in_between;
          }
      }
      break;
      default:
      {
          cur_state = below_low_thres;

      }
      }

      i=i*2;
  }// end of while-loop

} // end of main




ISR(USART0_RX_vect) {

  uint8_t i, deviceAddress[8],value8;
  uint16_t value_read;
  char tmp_str[100], command_str[MAX_LENGTH_COMMAND],deviceAddress_str[9];
  //uint8_t res = 0, res2 = 0;
  uint8_t usercommand;
  int counter=0, q=0, NumDevicesFound=0;

  cli();


  //USART_send_string ("entered USART0_RX_vect");

  //strcpy(tmp_str, "no command received from ETRAX.");
   
  usercommand = USART0_Receive();


  switch (usercommand)
  {
      case 'h': // shows help
      {
      		sprintf(tmp_str, "List of commands");
      		USART_send_string (tmp_str);
		sprintf(tmp_str, "h --> this help");
      		USART_send_string (tmp_str);
		sprintf(tmp_str, "l --> shows all devices found in the bus");
      		USART_send_string (tmp_str);
		sprintf(tmp_str, "t --> shows all temperature devices in the bus, makes temperature conversion and shows devices addresses and values");
      		USART_send_string (tmp_str);
		sprintf(tmp_str, "d --> shows all ADCs in the bus, makes ADC conversion and shows devices addresses and values");
      		USART_send_string (tmp_str);
		sprintf(tmp_str, "s --> Reads the status of all DualSwitches (DS2413) on the bus");
      		USART_send_string (tmp_str);
		sprintf(tmp_str, "S --> Sets all DualSwitches (DS2413) on the bus to ON");
      		USART_send_string (tmp_str);
		sprintf(tmp_str, "R --> Sets all DualSwitches (DS2413) on the bus to OFF");
      		USART_send_string (tmp_str);
		sprintf(tmp_str, "T --> Not yet implemented: Sets a particular DualSwitch with A:ON, B:OFF");
      		USART_send_string (tmp_str);
		sprintf(tmp_str, "U --> Not yet implemented: Sets a particular DualSwitch with A:OFF, B:ON");
      		USART_send_string (tmp_str);
		sprintf(tmp_str, "W --> Not yet implemented: Sets a particular DualSwitch to ON or OFF");
      		USART_send_string (tmp_str);
		sprintf(tmp_str, " v,p,f,g--> Do not use: either old or test functions");
      		USART_send_string (tmp_str);
				
      }
      break;

      case 'l': // List of all devices found in the bus
      {
      		NumDevicesFound=ReadDevicesID(BUSES, 1);
      }
      break;
      
      case 't': // Shows all temperature devices in the bus, makes temperature conversion and shows devices addresses and values
      {
      		NumDevicesFound=ReadDevicesID(BUSES, 0);
		MakeTempConversionOfAllDevices(BUSES);
	        FindFamilyDevicesAndGetValues(BUSES, NumDevicesFound, FAMILY_DS18B20_TEMP);
      }
      break;
 
      case 'd': // shows all ADCs in the bus, makes ADC conversion and shows devices addresses and values
      {
      		NumDevicesFound=ReadDevicesID(BUSES, 0);
		ADCsInitialization(BUSES);
      		MakeADCConversionOfAllDevices(BUSES);
      		FindFamilyDevicesAndGetValues(BUSES, NumDevicesFound, FAMILY_DS2450_ADC);
      }
      break; 

      case 's': //
      {
		NumDevicesFound=ReadDevicesID(BUSES, 0);
      		FindFamilyDevicesAndGetValues(BUSES, NumDevicesFound, FAMILY_DS2413_DUAL_SWITCH);
      }
      break;

      case 'S': // Sets all DualSwitches on the bus to ON
      {
		NumDevicesFound=ReadDevicesID(BUSES, 0);
		//TO DO: check that the address of the switch is existing.... 

		//Example address: '05D5253000000084'
		deviceAddress[0]=0x05;deviceAddress[1]=0xD5;deviceAddress[2]=0x25;deviceAddress[3]=0x30;
		deviceAddress[4]=0x00;deviceAddress[5]=0x00;deviceAddress[6]=0x00;deviceAddress[7]=0x84;


		//sprintf(tmp_str,"%02X%02X%02X%02X%02X%02X%02X%02X\n",deviceAddress[0],deviceAddress[1],deviceAddress[2],deviceAddress[3],deviceAddress[4],deviceAddress[5],deviceAddress[6],deviceAddress[7]);
		//USART_send_string (tmp_str);

		for (q=0;q<NumDevicesFound;q++){
       			 if (IDS_ALL[q][0]==FAMILY_DS2413_DUAL_SWITCH){
			//sprintf(tmp_str,"encuentra dispositivo");
			//USART_send_string (tmp_str);
			//sprintf(tmp_str,"%02X%02X%02X%02X%02X%02X%02X%02X\n",deviceAddress[0],deviceAddress[1],deviceAddress[2],deviceAddress[3],deviceAddress[4],deviceAddress[5],deviceAddress[6],deviceAddress[7]);
			//USART_send_string (tmp_str);
			//(unsigned char bus, unsigned char * id, uint16_t *array_chn, bool channelA, bool channelB )
			//DONE: VER POR QUE AQUI NO VA LA LLAMADA PARA SETEAR LOS SWITCHES--> IT WAS THE FIRST ARGUMENT OF THE FUNCTION, BE CAREFULL WITH THAT!!
			WriteDualSwitch(BUSES, IDS_ALL[q],IDS_ALL_VALUES[q],0,0); //BOTH CHANNELS ON
			//SetOnDoubleSwitch(BUSES, IDS_ALL[q], IDS_ALL_VALUES[q]);
      			//FindFamilyDevicesAndGetValues(BUSES, NumDevicesFound, FAMILY_DS2413_DUAL_SWITCH);
			}
		}
      }
      break;

      case 'R': // // Sets all DualSwitches on the bus to OFF
      {
		NumDevicesFound=ReadDevicesID(BUSES, 0);
		
		for (q=0;q<NumDevicesFound;q++){
       			 if (IDS_ALL[q][0]==FAMILY_DS2413_DUAL_SWITCH){
			WriteDualSwitch(BUSES, IDS_ALL[q],IDS_ALL_VALUES[q],1,1); //BOTH CHANNELS OFF
			
			}
		}
      }
      break;

      case 'T': // // Sets all DualSwitches on the bus to OFF
      {
		NumDevicesFound=ReadDevicesID(BUSES, 0);
		
		for (q=0;q<NumDevicesFound;q++){
       			 if (IDS_ALL[q][0]==FAMILY_DS2413_DUAL_SWITCH){
			WriteDualSwitch(BUSES, IDS_ALL[q],IDS_ALL_VALUES[q],0,1); //A:ON, B:OFF
			
			}
		}
      }
      break;

      case 'U': // // Sets all DualSwitches on the bus to OFF
      {
		NumDevicesFound=ReadDevicesID(BUSES, 0);
		
		for (q=0;q<NumDevicesFound;q++){
       			 if (IDS_ALL[q][0]==FAMILY_DS2413_DUAL_SWITCH){
			WriteDualSwitch(BUSES, IDS_ALL[q],IDS_ALL_VALUES[q],1,0); //A:OFF, B:ON
			
			}
		}
      }
      break;

      case 'W': //function to set an specific switch to ON or OFF (Not implemented yet)
      {
        
	/*	counter=0;
		while (usercommand!='z' && counter<MAX_LENGTH_COMMAND){ 
			usercommand = USART0_Receive();
			
			command_str[counter]= usercommand;
			counter++;
		}
		command_str[counter]='\0';
		USART_send_string (command_str);

*/

		// Command type:
		// S 286A9C7C01000095 xxz 
		// Where:
		// S = Write DualSwitches (DS2413)
		// 286A9C7C01000095 = 1-Wire device address
		// xx = values of first and second switch channel (where x is either 1 or 0)
		// z = end of command

//HOW TO CONVERT CHAR TO UINT8_T?????????????-------------------------------------------
/*
		deviceAddress_str[0]= (command_str[2]);
		deviceAddress_str[1]= (command_str[3]);
		deviceAddress_str[2]= (command_str[4]);
		deviceAddress_str[3]= (command_str[5]);
		deviceAddress_str[4]= (command_str[6]);
		deviceAddress_str[5]= (command_str[7]);
		deviceAddress_str[6]= (command_str[8]);
		deviceAddress_str[7]= (command_str[9]);

				deviceAddress[0]= ascii2byte(command_str[2]);
		//deviceAddress[0] |= (ascii2byte(command_str[3]) << 4);

		deviceAddress[1]= ascii2byte(command_str[4]);
		deviceAddress[1] |= (ascii2byte(command_str[5]) << 4);

		deviceAddress[2]= ascii2byte(command_str[6]);
		deviceAddress[2] |= (ascii2byte(command_str[7]) << 4);

		deviceAddress[3]= ascii2byte(command_str[8]);
		deviceAddress[3] |= (ascii2byte(command_str[9]) << 4);

		deviceAddress[4]= ascii2byte(command_str[10]);
		deviceAddress[4] |= (ascii2byte(command_str[11]) << 4);

		deviceAddress[5]= ascii2byte(command_str[12]);
		deviceAddress[5] |= (ascii2byte(command_str[13]) << 4);

		deviceAddress[6]= ascii2byte(command_str[14]);
		deviceAddress[6] |= (ascii2byte(command_str[15]) << 4);

		deviceAddress[7]= ascii2byte(command_str[16]);
		deviceAddress[7] |= (ascii2byte(command_str[17]) << 4);

		deviceAddress[8]= ascii2byte(command_str[18]);
		deviceAddress[8] |= (ascii2byte(command_str[19]) << 4);
		//deviceAddress[8]='\0';
	        *var_pntr = ascii2byte(command_str[2]);
		//deviceAddress=atoi(deviceAddress_str[0]);

		//sprintf(tmp_str,"%c%c%c%c%c%c%c%c\n",deviceAddress_str[0],deviceAddress_str[1],deviceAddress_str[2],deviceAddress_str[3],deviceAddress_str[4],deviceAddress_str[5],deviceAddress_str[6],deviceAddress_str[7]);

		sprintf(tmp_str,"%02X%02X%02X%02X%02X%02X%02X%02X\n",deviceAddress[0],deviceAddress[1],deviceAddress[2],deviceAddress[3],deviceAddress[4],deviceAddress[5],deviceAddress[6],deviceAddress[7]);
*/
		//echo -n "WS 286A9C7C01000095 11z" > /dev/ttyS1
		
		//command_str[counter]='\n';
        	//ReadDoubleSwitch(BUSES);
        	 //DoubleSwitch(BUSES);
        	//SetOffDoubleSwitch(BUSES);
        	//sprintf(tmp_str, "Toma doble switch!!");

        /*	USART_send_string (tmp_str);

		if (command_str[0]=='S'){
			WriteDualSwitch();	
		}
        */




     }


      break;

     case 'v': //ADC
      {
         
      VoltageStored(BUSES);
          sprintf(tmp_str, "Toma maroma!!");
      USART_send_string (tmp_str);
      }
      break;
     case 'p': //temp orig
      {
         
      TempStored(BUSES);
          sprintf(tmp_str, "Ya te he mostrado el valor!");
      USART_send_string (tmp_str);
      }
      break;
     case 'f': //Read all sensors reparately
      {
          //Get all device addresses and separate them in different arrays depending of the family
      NumDevicesFound=ReadDevicesID(BUSES, 1); //1 shows a list of all devices, 0 hides it!!
      //sprintf(tmp_str, "Num dispositivos encontrados despues de ReadDevices:%d", NumDevicesFound);
      //USART_send_string (tmp_str);
      //sprintf(tmp_str, "Ya te he mostrado las direcciones de todos los sensores!");
      //USART_send_string (tmp_str);
      //TEMPERATURE
      //Make temperature conversion of all devices:
      MakeTempConversionOfAllDevices(BUSES);
      //sprintf(tmp_str, "Realizada conversion de los sensores de temperatura!");
      //USART_send_string (tmp_str);
      //sprintf(tmp_str, "Temperature sensors found:");
      //USART_send_string (tmp_str);
      //FindTemperatureDevicesAndGetValues(BUSES, NumDevicesFound);

      FindFamilyDevicesAndGetValues(BUSES, NumDevicesFound, FAMILY_DS18B20_TEMP);

//#define FAMILY_DS2450_ADC    0x20
//#define FAMILY_DS18B20_TEMP     0x28
//#define FAMILY_DS2413_DUAL_SWITCH 0x13
      //ADCs
          //Inicialization of ADCs (non parasitic mode and 5V range)
      ADCsInitialization(BUSES);
          //DEBUG sprintf(tmp_str, "Made ADC inicialization!");
          //DEBUG USART_send_string (tmp_str);

      // Make ADC conversion for all devices:
      MakeADCConversionOfAllDevices(BUSES);
          //DEBUG sprintf(tmp_str, "Made ADC conversion!");
          //DEBUG USART_send_string (tmp_str);

      //sprintf(tmp_str, "Temperature sensors found:");
      //USART_send_string (tmp_str);
      FindFamilyDevicesAndGetValues(BUSES, NumDevicesFound, FAMILY_DS2450_ADC);
   
      FindFamilyDevicesAndGetValues(BUSES, NumDevicesFound, FAMILY_DS2413_DUAL_SWITCH);
 

      //TempStored(BUSES);
      //Read values of voltages, PASSING the addresses of the specific sensors found
      //TempStored(BUSES);
      //Read status of switches, PASSING the addresses of the specific sensors found
      //TempStored(BUSES);
          //sprintf(tmp_str, "Ya te he mostrado las direcciones de todos los sensores!");
      //USART_send_string (tmp_str);
      }
      break;
     case 'g': //set values (How can we do this??): Get also Device Address and set value?
      {
         
      TempStored(BUSES);
          sprintf(tmp_str, "Ya te he mostrado el valor!");
      USART_send_string (tmp_str);
      }
      break;
      default:
      {
      sprintf(tmp_str, "Error, unknown command received : %c", usercommand);
      USART_send_string (tmp_str);
      }
      break;

  }            // end of switch




  // break_point (1, "end of main");

  sei();

}  // end of ISR



//ERROR CODES:
// -999 error detecting presence on the 1-wire bus.
