Problem with C Code to Retrieve Temperatures over USB 2.0 in 3 Bytes

66 Views Asked by At

I am currently working on a heating regulation project in C.

I have already made a lot of progress on the different parts of the project but I am stuck on the temperature reading part.

The instruction I have is:

The reading is done via a USB 2.0 connection between the electronic board and the regulation microcomputer: • FPGA to USB transfer interface via FTDI's FT245R circuit • temperature transmission protocol: o digitized relative temperatures (SOT) outside and inside alternately transmitted over 6 bytes. o 40 ms period representing 100 seconds in reality. o coding of digitized relative temperature SOT on 12 bits (sensor coding kept): Absolute temperature in °C = -39.64 + 0.04 x SOT o format of transmission of digitized relative temperatures SOT: SOT decomposed into quartet and transmitted over 3 bytes to ensure synchronization.

And I have a descriptive table of how the two temperatures are represented on 3 bytes each:

                  Byte       bit   
                             7; 6 ; 5 ; 4 ; 3; 2 ; 1; 0 
Outer Temperature :1st      0 ;0 ;0 ;0 ; SOT bit 11;SOT bit 10;SOT bit 9;SOT bit 8 
                   2nd      0 ;0 ;0 ;1 ; SOT bit 7; SOT bit 6; SOT bit 5;SOT bit 4 
                   3rd      0 ;0 ;1 ;0 ; SOT bit 3; SOT bit 2; SOT bit 1;SOT bit 0 
Inner Temperature :1st      1 ;0 ;0 ;0 ; SOT bit 11;SOT bit 10;SOT bit 9;SOT bit 8 
                   2nd      1 ;0 ;0 ;1 ; SOT bit 7; SOT bit 6; SOT bit 5;SOT bit 4 
                   3rd      1 ;0 ;1 ;0 ; SOT bit 3; SOT bit 2; SOT bit 1;SOT bit 0

I have already made a releve() function, however I do not understand how to properly make my bit shift to get the right value.

#include "releve.h"
#include <windows.h>
#include "ftd2xx.h"
#include "define.h"
void releve(){
    FT_HANDLE ftHandle;
    FT_STATUS ftStatus;
    DWORD RxBytes = 8;
    DWORD BytesReceived;
    ftStatus = FT_Open(0, &ftHandle);
    char RxBuffer[6];
    // Déclaration des variables
    int tempExtSOT =  0.0;
    int tempIntSOT = 0.0;
    float tempExtDec = 0.0;
    float tempIntDec = 0.0;
    ftStatus = FT_Read(ftHandle,RxBuffer,RxBytes,&BytesReceived);
    
    for(int i =0;i<6;i++){
        if((r))
    }
// Conversion en décimal des valeurs SOT récupérées  
    tempExtDec = -39.64 + (0.04 * tempExtSOT);   // Conversion de la température extérieure en décimal  
    tempIntDec = -39.64 + (0.04 * tempIntSOT);   // Conversion de la température intérieure en décimal
    printf("%g\n", tempExtSOT);
    printf("%g\n", tempIntSOT);
    printf("%g\n", tempExtDec);
    printf("%g", tempIntDec);

I am using the FT_Read function to retrieve the values of the 6 bytes into a buffer in hexadecimal. Thank you for your help and guidance!


1

There are 1 best solutions below

0
paddy On

As you can see from your table, the values are simply packed in the lower 4 bits of each byte, supplied in big-endian order. So you can write a simple function that builds the value like this:

float GetTemperature(const char *byte3)
{
    int SOT = (byte3[0] & 0x0f) << 8
            | (byte3[1] & 0x0f) << 4
            | (byte3[2] & 0x0f);
    return -39.64f + 0.4f * SOT;
}

See that the construction of SOT simply masks-off the lower 4 bits, and then shifts the appropriate number of binary places to the left. The individual parts are combined with a bitwise-OR, but you can use ordinary addition in this case if you prefer.

You may also wish to use those upper 4 bits to verify that the data is valid.

Now you can use that to get the temperatures from your buffer:

float tempExtDec = GetTemperature(RxBuffer);
float tempIntDec = GetTemperature(RxBuffer + 3);