Go Down

Topic: Problema GPS+Sensor de temperatura (Read 1 time) previous topic - next topic

Jarcorcriu

Hola, estoy realizando un proyecto en el que uso un GPS y un sensor de temperatura, entre otras cosas.

Por separado funcionan bien, pero cuando los conecto entran en conflicto por algún motivo y el sensor se "vuelve loco". Recoge valores irreales constantemente: en un momento mide 22ºC y a los 3 segundos baja 9ºC.

El GPS (Venus de Sparkfun) tiene el pin de 3.3V conectado al de 3.3V de Arduino (MEGA 2560), GND con GND y TX con el pin digital 10 de Arduino. ¿Es necesario conectar también el RX? El sensor de temperatura (digital) está conectado a 5V, GND y pin digital 5.
Todas las conexiones están bien realizadas y el código es correcto. Supongo que debe haber algún conflicto en la comunicación, pero no domino ese tema. ¿Tendría que usar otra comunicación serial (por lo que sé, el MEGA tiene varias)?

Todo esto está conectado junto con otros elementos a una pantalla LCD, por lo que el código es extenso y algo lioso, pero si alguien lo quiere para echar un vistazo lo pongo sin problemas.

Gracias!

EJTR


sube el codigo para revisarlo porque al  parecer todo esta bien.

Jarcorcriu

En concreto el sensor que da problemas es el DS18B20, que utiliza la funcion  getTemp()


Code: [Select]
#include <genieArduino.h>  
#include <SoftwareSerial.h>  //GPS library
#include <OneWire.h> //Temperature Sensor DS18B20
#include <TinkerKit.h>


bool formTriggered = 0;
bool videoStarted = 0;
int formNumber = 0; // Starts on Form0
int frameNumber = -1; // Non-Zero number to start with
long period;


long tempC;      
int tempPin = 2;  //Analogic pin for temperature sensor LM35
int tempState0 = LOW;
long previousMillis0 =0;
long interval0 = 3000;


int DS18S20_Pin = 5; //Digital pin for temperature sensor DS18S20
OneWire ds(DS18S20_Pin);
int tempState1 = LOW;
long previousMillis1 =0;
long interval1 =3000;


SoftwareSerial gpsSerial(10, 11); // TX, RX (RX not used)
const int sentenceSize = 80;
char sentence[sentenceSize];


TKGyro gyro(I0, I1, TK_X4);
int X;
int Y;


void setup()
{
 gpsSerial.begin(9600);
 genieBegin (GENIE_SERIAL, 9600);  
 genieAttachEventHandler(myGenieEventHandler);
 
 //Reset the Display (change D4 to D2 if you have original 4D Arduino Adaptor)
 pinMode(4, OUTPUT);  // Set D4 on Arduino to Output (4D Arduino Adaptor V2 - Display Reset)
 digitalWrite(4, 1);  // Reset the Display via D4
 delay(100);
 digitalWrite(4, 0);  // unReset the Display via D4
 
 delay (3500); //let the display start up
 
 genieWriteObject(GENIE_OBJ_TIMER, 0x00, 1); // Start Video by Starting Timer0
 delay(100); // Delay long enough so video starts and the frameNumber > 0 else code below gets stuck
}



void loop(){
   
 // Do this only every 'period' rather than every loop
 if(millis() > period)
 {  
   genieReadObject(GENIE_OBJ_FORM, 0x00); // Poll to request current Form number  
   
   // Check the current video frame number if on Form0 only
   if(formNumber == 0)
   {
     genieReadObject(GENIE_OBJ_VIDEO, 0x00); // Poll to request current Video frame
   }  
   
   period = millis() + 1000; // set the period of this
 }
 
 // If on Form0 and the Frame is back to 0, the Video has therefore stopped
 if (formNumber == 0 && frameNumber == 0)
 {
   genieWriteObject(GENIE_OBJ_FORM, 0x01, 0); // Change to Form1
   formNumber = 1;
 }
 
 genieDoEvents(); // check library for new data every loop
 
 
   
   if (formNumber == 1)
   {
   
        unsigned long currentMillis1 = millis();
          if (currentMillis1 - previousMillis1 > interval1)
          {
            previousMillis1 = currentMillis1;
            if (tempState1 == LOW)
            tempState1 = HIGH;
            else
            tempState1 = LOW;
     
            digitalWrite(DS18S20_Pin, tempState1);
            float temperature = getTemp();
            temperature = constrain(temperature, 0, 125);
            genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x02, temperature);  
            genieWriteObject(GENIE_OBJ_GAUGE, 0x00, temperature);
           
            if (temperature >= 120){
              genieWriteObject(GENIE_OBJ_USER_LED, 0x00, 1);}
          }
         
          static int i = 0;
          if (gpsSerial.available()){
           char ch = gpsSerial.read();
           if (ch != '\n' && i < sentenceSize){
             sentence[i] = ch;
             i++;}
           else{
             sentence[i] = '\0';
             i = 0;
             displayGPS();}}    
   }
   
   
   if (formNumber == 2){  
 
        unsigned long currentMillis0 = millis();
         if (currentMillis0 - previousMillis0 > interval0)
         {
           previousMillis0 = currentMillis0;
           if (tempState0 == LOW && tempState1 == LOW){
           tempState0 = HIGH;
           tempState1 = HIGH;}
           else{
           tempState0 = LOW;
           tempState1 = LOW;}
     
           digitalWrite(tempPin, tempState0);
           tempC = analogRead(tempPin);        
           tempC = (5.0 * tempC * 100.0)/1024.0;
           tempC = constrain(tempC, 0, 50);
           genieWriteObject(GENIE_OBJ_THERMOMETER, 0x00, tempC);
           genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, tempC);
           digitalWrite(DS18S20_Pin, tempState1);
           float temperature = getTemp();
           temperature = constrain(temperature, 0, 125);
           genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x01, temperature);
           genieWriteObject(GENIE_OBJ_THERMOMETER, 0x01, temperature);
         }
  }
 
 
   if (formNumber == 3){
        X = (((gyro.readXAxisRate())*100)/1500);
        X = constrain(X, -100, 100);
        Y = (((gyro.readYAxisRate())*100)/1500);
        Y = constrain(Y, -100, 100);
        genieWriteObject(GENIE_OBJ_METER,0x00,X);
        genieWriteObject(GENIE_OBJ_METER,0x01,Y);
   }
 
   
   if (formNumber == 4){
           static int i = 0;
          if (gpsSerial.available()){
           char ch = gpsSerial.read();
           if (ch != '\n' && i < sentenceSize){
             sentence[i] = ch;
             i++;}
           else{
             sentence[i] = '\0';
             i = 0;
             displayGPS();}}    
   }
   
   
   if (formNumber == 5){
           static int i = 0;
          if (gpsSerial.available()){
           char ch = gpsSerial.read();
           if (ch != '\n' && i < sentenceSize){
             sentence[i] = ch;
             i++;}
           else{
             sentence[i] = '\0';
             i = 0;
             displayGPS();}}
   }    



}





void myGenieEventHandler(void)
{
 genieFrame Event;
 genieDequeueEvent(&Event);
 
 //If the cmd received is from a Read Object
 if(Event.reportObject.cmd == GENIE_REPORT_OBJ)
 {  
   if (Event.reportObject.object == GENIE_OBJ_VIDEO)   // If the Read Object was from a Video
   {
     if (Event.reportObject.index == 0)  // If Video0
     {
       frameNumber = genieGetEventData(&Event);  // Receive the frame data from the Video0
     }
   }
   
   if (Event.reportObject.object == GENIE_OBJ_FORM)   // If the Read Object was from a Form
   {
     formNumber = genieGetEventData(&Event);
   }
 }
}




float getTemp()  // Devuelve la temperatura del DS18S20 en grados centígrados

{

byte data[12];
byte addr[8];

if ( !ds.search(addr)) {
 
  ds.reset_search();
  return -1000;
}

if ( OneWire::crc8( addr, 7) != addr[7]) {
 
  return -1000;
}

if ( addr[0] != 0x10 && addr[0] != 0x28) {
 
  return -1000;
}

ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end

byte present = ds.reset();
ds.select(addr);  
ds.write(0xBE); // Read Scratchpad


for (int i = 0; i < 9; i++) { // we need 9 bytes
 data[i] = ds.read();
}

ds.reset_search();

byte MSB = data[1];
byte LSB = data[0];

float tempRead = ((MSB << 8) | LSB); //using two's compliment
float TemperatureSum = tempRead / 16;

return TemperatureSum;

}




void displayGPS()
{
 char field[20];
 
 getField(field, 0);
 if (strcmp(field, "$GPRMC") == 0)
 {
   getField(field, 9);  // Date
   genieWriteStr(0,field);
   
   getField(field, 1);  // Time
   genieWriteStr(1,field);
   
   getField(field, 3);  // Latitude
   genieWriteStr(2,field);
   getField(field, 4); // N/S
   genieWriteStr(3,field);

   
   getField(field, 5);  // Longitude
   genieWriteStr(4,field);
   getField(field, 6);  // E/W
   genieWriteStr(5,field);
   
   getField(field, 8); //Course over ground
   genieWriteObject(GENIE_OBJ_USERIMAGES,0x00,*field);
   
 }
 
 getField(field, 0);
 if (strcmp(field, "$GPVTG") == 0)
 {
   getField(field, 7);  // speed over gorund km/h
   genieWriteObject(GENIE_OBJ_LED_DIGITS,0x03,*field);
 }

}




void getField(char* buffer, int index)
{
 int sentencePos = 0;
 int fieldPos = 0;
 int commaCount = 0;
 while (sentencePos < sentenceSize)
 {
   if (sentence[sentencePos] == ',')
   {
     commaCount ++;
     sentencePos ++;
   }
   if (commaCount == index)
   {
     buffer[fieldPos] = sentence[sentencePos];
     fieldPos ++;
   }
   sentencePos ++;
 }
 buffer[fieldPos] = '\0';

}

Heke

Si empleas un ds18b20 que pinta este codigo:
Quote
long tempC;     
int tempPin = 2;  //Analogic pin for temperature sensor LM35
int tempState0 = LOW;
long previousMillis0 =0;
long interval0 = 3000;

Go Up