poniedziałek, 20 sierpnia 2012

RTCU data logger

In this example I used a DS1820 1-Wire temperature sensor. The temperature is read from the sensor and written in a ASCII file on the SD-Card in the RTCU. Here's the code

 PROGRAM a1wire;  
 // These are the local variables of the program block  
 VAR  
   ow_dev : int;  
   sign : sint;  
   family : int;  
   dane_sint1, dane_sint2 : sint;  
   dane_int1, dane_int2 : int;  
   temp_calk, temp_ulam : int;  
   file_id : file;  
 END_VAR;  
   ow_dev:=owSearchX(first:=0, last:=255, reset:=true); // Scan the 1-Wire network  
   DebugMsg(message:=intToStr(v:=ow_dev)); // Number of 1-Wire devices in our case it is 1  
   family:=owGetFamily(device:=1); // Get the family name of the device  
   DebugMsg(message:=intToStr(v:=family)); // Family name of the device  
   DebugMsg(message:=owGetID(family:=family, device:=1)); // Get the 64bit ID of the device  
   if fsMediaPresent(media:=0) and (fsMediaOpen(media:=0)=0) then fsMediaQuickFormat(media:=0); fsDirCreate(name:="test"); fsDirChange(path:="A:\test"); fsFileClose(fd:=fsFileCreate(name:="test.txt")); fsMediaClose(media:=0); DebugMsg(message:="file created"); end_if; // if media is present and opened create a directory and go inside  
   fsMediaOpen(media:=0); // Open SD-Card  
   displayClear();  
 BEGIN  
   // Code from this point until END will be executed repeatedly  
   owAccess(family:=family, device:=1); // Acces the DS1820  
   owWrite(data:=16#44); // Order the DS1820 to convert temperature  
   Sleep(delay:=700); // Wait for 700 ms (DS1820 datasheet says tha this should be at least 750ms, but 700ms work for this particular DS1820)  
   owRelease(); // Release the 1-Wire network  
   owAccess(family:=family, device:=1); // Acces it again  
   owWrite(data:=16#BE); // Order the DS1820 to send the scratchpad content  
   owRead(data:=dane_sint1); // Read LSB   
   owRead(data:=dane_sint2); // Read MSB  
   if dane_sint1<0 then // Convert the temperature  
    sign:=64;   
    else   
      sign:=0;   
    end_if;  
   temp_calk:= shr8(in:=shl8(in:=dane_sint1, n:=1), n:=2)+sign;  
   if dane_sint2 <> 0 then // Get the sign of the temperature  
    temp_calk:=temp_calk*-1;   
    end_if;  
   temp_ulam:= 5*(dane_sint1 mod 2); // Calculate the fractional part of the temperature  
   owRelease(); // Release the 1-Wire network  
   if fsMediaOpen(media:=0)=0 then // Open the SD-Card  
    file_id := fsFileOpen(name:="a:\test\test.txt"); // Open file  
    if fsFileStatus(fd:=file_id) = 0 then // If file is opened...  
      DebugMsg(message:="file write status "+ intToStr(v:=fsFileWriteStringNL(fd:=file_id, str:="temp="+intToStr(v:=temp_calk)+","+intToStr(v:=temp_ulam)))); // ...write a string in it  
      fsFileClose(fd:=file_id); // Close the file  
      end_if;  
    end_if;  
   displayString(message:="temp="+intToStr(v:=temp_calk)+","+intToStr(v:=temp_ulam)); // Display the temperature  
 END;  
 END_PROGRAM;  

And it works! producing a test.txt file with

temp=28,0
temp=28,5
temp=28,5
etc...

Okay, that's great, but hey - I used the whole controller capacity for that. Every single run of the software takes ~1s (mainly due to the fact that I'm waiting for the temperature conversion for 700ms). So the next thing to do is to put the temperature reading from the 1-Wire sensor into a asynchronous functionblock or another thread, as this controller is able to multithread. Stay tuned for that, as I guess it will take me a bit to do ;-).

And I would like to thank Stanko, for help with calculating the temperature from the 1-Wire data :-).

Brak komentarzy:

Prześlij komentarz