Код полон проблем, которые явно не являются частью вашего вопроса. Просто некоторые:
readTemp()
не возвращает температуру. Фактически, он возвращает 1, если это не удалось, и 1, если это успешно Вероятно, это ошибка.
readTemp()
выглядит так: все доступные датчики температуры, переданные ему в виде связного списка struct ds18b20
, а не только одного. Но на самом деле пропускает корневой узел и обращается ко второму и последующему без проверки его корректности. Если в корневом узле нет устройства (только указатель на первое устройство), вам нужно только передать его, передав вместо него rootNode->next
.
Не ясно, почему он динамически распределяет новый struct ds18b20
или почему он не может впоследствии отменить выделение. Это серьезная утечка памяти.
По-видимому, следующее, скорее всего, будет близко к тому, что вам нужно (не зная ничего о struct ds18b20
или о том, каков ожидаемый выходной сигнал датчика - просто исходя из свидетельств в коде (и закомментированного кода) Вы отправили - так что некоторые смелые предположения были сделаны.
int readTemp( struct ds18b20 *d, // List of sensors
float* temperatures, // Pointer to array to receive temperatures
int8_t max_temperatures ) // Max number of temperatures to receive
{
struct ds18b20* sensor = d ;
int count = 0 ;
while( sensor != NULL && count < max_temperatures )
{
int fd = open( sensor->devPath, O_RDONLY ) ;
if( fd >= 0 )
{
if( read( fd, buf, sizeof(buf) ) > 0 )
{
char buf[256];
char* temp_str = strstr(buf, "t=") + 2 ;
sscanf( temp_str, "%f", &temperatures[count] ) ;
temperatures[count] /= 1000 ;
count++ ;
}
close( fd ) ;
sensor = sensor->next ;
}
else
{
perror("Couldn't open the w1 device.");
}
}
return count ;
}
Тогда вы можете назвать это так:
int8_t devCount = findDevices( rootNode ) ;
float* temperatures = malloc( devCnt * sizeof(float) ) ;
int8_t tempCount = readTemp( rootNode->next, temperatures, devCount ) ;
for( int i = 0; i < tempCount; i++ )
{
printf( "Temp Act: %f\n", temperatures[i] ) ;
}
free( temperatures ) ;
Если вы знаете, что есть только одно устройство или вам нужно только напечатать первое, это можно упростить:
int8_t devCount = findDevices( rootNode ) ;
if( devCount > 0 )
{
float temperature = 0f ;
int8_t tempCount = readTemp( rootNode->next, temperature, 1 ) ;
if( tempCount > 0 )
{
printf( "Temp Act: %f\n", temperature ) ;
}
}
Проблемы в вашем main()
также различны, в том числе:
- Корневой узел распределяется без необходимости динамически
- несколько псевдонимов корневого узла создаются без необходимости
- Список устройств многократно пересчитывается, а список устройств выделяется и освобождается на каждой итерации бесконечного цикла. Предполагая, что количество датчиков не изменяется во время выполнения кода, это не нужно.
- Цикл никогда не заканчивается - даже в случае ошибки.
Лучшая реализация может выглядеть примерно так:
int main(void)
{
// Load pin configuration. Ignore error if already loaded
system("echo w1 > /sys/devices/bone_capemgr.9/slots>/dev/null");
struct ds18b20 rootNode = { 0 } ;
int8_t devCount = findDevices( rootNode ) ;
if( devCount > 0)
{
struct ds18b20* devlist = rootNode->next ;
float* temperatures = malloc( devCount * sizeof(float) ) ;
int8_t tempCount = 0 ;
do
{
tempCount = readTemp( devList, temperatures, devCount ) ;
for( int i = 0; i < tempCount; i++ )
{
printf( "Temp Act: %f\n", temperatures[i] ) ;
}
} while (tempCount > 0 ) ;
// Free resources after a temperature read fails
free( temperatures ) ;
// Free linked list memory
while( devlist != NULL )
{
// Save address of next before deleting current
struct ds18b20* next = devlist->next ;
// Free current devNode.
free( devlist ) ;
// get next
devlist = next ;
}
}
return 0 ;
}