C++ RasPi - Segmentation fault while in endless loop - c++

So I run an DS18S20 with an LCD Display.
I'm measuring my Room Temperature and displaying it on the LCD.
In said endless loop, I'm getting a Segmentation Fault after it ran 5-6 times. I've read that it must be a variable and got the suspicion that it's in my getTmp() function but don't know how to fix it.
I've been learning C++ for two weeks now and need your help.
Thank you in advance.
My Code:
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <wiringPi.h>
#include <lcd.h>
#include <unistd.h>
using namespace std;
#define ever (;;)
//USE WIRINGPI PIN NUMBERS
#define LCD_RS 25 //Register select pin
#define LCD_E 24 //Enable Pin
#define LCD_D4 23 //Data pin 4
#define LCD_D5 22 //Data pin 5
#define LCD_D6 21 //Data pin 6
#define LCD_D7 14 //Data pin 7
void getTmp(string *y)
{
ifstream file("/sys/bus/w1/devices/10-00080366745a/w1_slave");
string f[2];
if (file.is_open())
{
for (int i = 0; i < 2; ++i)
{
getline(file, f[i]);
}
}
string s = f[1];
bool x = true;
int i3 = 0, i2 = 0;
while (x)
{
if (i2 <= 4 && i2 > 0)
{
y[i2 - 1] = s[i3];
++i2;
}
if (i2 > 4)
{
x = false;
}
if (s[i3] == '=')
{
i2 = 1;
}
++i3;
}
}
int main()
{
unsigned int microseconds = 5000;
string b[4];
string *y = b;
int lcd;
wiringPiSetup();
const char *tmp;
for ever
{
getTmp(y);
string t = "Temp = "+b[0]+b[1]+"."+b[2]+b[3]+"°C";
tmp=t.c_str();
lcd = lcdInit (2, 16, 4, LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7, 0, 0, 0, 0);
lcdPuts(lcd, tmp);
cout << tmp << endl;
usleep(microseconds);
}
return 0;
}

Related

Multiple Definitions Error of Global Arrays [duplicate]

This question already has answers here:
c++ multiple definitions of a variable
(5 answers)
multiple definition error c++
(2 answers)
What exactly is One Definition Rule in C++?
(1 answer)
Closed 2 years ago.
I am attempting to compile my c++ code, and I continue getting the error:
/tmp/ccEsZppG.o:(.bss+0x0): multiple definition of `mailboxes'
/tmp/ccEZq43v.o:(.bss+0x0): first defined here
/tmp/ccEsZppG.o:(.bss+0xc0): multiple definition of `threads'
/tmp/ccEZq43v.o:(.bss+0xc0): first defined here
/tmp/ccEsZppG.o:(.bss+0x120): multiple definition of `semaphores'
/tmp/ccEZq43v.o:(.bss+0x120): first defined here
collect2: error: ld returned 1 exit status
Here is my code:
addem.cpp
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
#include "mailbox.h"
using namespace std;
void *sumUp(void *arg);
int main(int argc, char *argv[]) {
int numThreads, minThreads, maxInt, minInt;
if (argc < 3) {
cout << "Error: Need three arguments" << endl;
return 1;
}
numThreads = atoi(argv[1]);
maxInt = atoi(argv[2]);
minThreads = 1;
minInt = 1;
if (numThreads < 1) {
cout << "Cannot work with less than one thread\n"
<< "It's okay but do better next time!\n"
<< "We'll work with 1 thread this time.\n";
numThreads = minThreads;
} else if (numThreads > MAXTHREAD) {
cout << "Sorry, the max for threads is 10.\n"
<< "We'll work with 10 threads this time.\n";
numThreads = MAXTHREAD;
}
if (maxInt < 1) {
cout << "What do you want me to do? I can't count backwards!\n"
<< "I can barely count forwards! Let's make the max number\n"
<< "be 1 to save time\n";
maxInt = minInt;
}
struct msg outgoingMail[numThreads];
int divider = maxInt / numThreads;
int count = 1;
//initialize arrays (mailboxes, semaphores)
for (int i = 0; i < numThreads; i++) {
sem_init(&semaphores[i], 0, 1);
outgoingMail[i].iSender = 0;
outgoingMail[i].type = RANGE;
outgoingMail[i].value1 = count;
count = count + divider;
if (i = numThreads - 1) {
outgoingMail[i].value2 = maxInt;
} else {
outgoingMail[i].value2 = count;
}
}
for (int message = 0; message < numThreads; message++) {
SendMsg(message+1, outgoingMail[message]);
}
int thread;
for (thread = 0; thread <= numThreads; thread++) {
pthread_create(&threads[thread], NULL, &sumUp, (void *)(intptr_t)(thread+1));
}
struct msg incomingMsg;
int total = 0;
for (thread = 0; thread < numThreads; thread++) {
RecvMsg(0, incomingMsg);
total = total + incomingMsg.value1;
}
cout << "The total for 1 to " << maxInt << " using "
<< numThreads << " threads is " << total << endl;
return 0;
}
void *sumUp(void *arg) {
int index,total;
index = (intptr_t)arg;
struct msg message;
RecvMsg(index, message);
message.iSender = index;
message.type = ALLDONE;
total = 0;
for (int i = message.value1; i <= message.value2; i++) {
total += i;
}
SendMsg(0, message);
return (void *) 0;
}
mailbox.cpp
#include <stdio.h>
#include <iostream>
#include "mailbox.h"
using namespace std;
int SendMsg(int iTo, struct msg &Msg) {
if (safeToCall(iTo)) {
cout << "Error calling SendMsg" << endl;
return 1;
}
sem_wait(&semaphores[iTo]);
mailboxes[iTo] = Msg;
sem_post(&semaphores[iTo]);
return 0;
}
int RecvMsg(int iFrom, struct msg &Msg) {
sem_wait(&semaphores[iFrom]);
if (safeToCall(iFrom)) {
cout << "Error calling RecvMsg" << endl;
return 1;
}
mailboxes[iFrom] = Msg;
sem_post(&semaphores[iFrom]);
return 0;
}
bool safeToCall(int location) {
bool safe = !(location < 0 || location > MAXTHREAD + 1);
return safe;
//return true;
}
mailbox.h
#ifndef MAILBOX_H_
#define MAILBOX_H_
#define RANGE 1
#define ALLDONE 2
#define MAXTHREAD 10
#include <semaphore.h>
#include <pthread.h>
struct msg {
int iSender; /* sender of the message (0 .. numThreads)*/
int type; /* its type */
int value1; /* first value */
int value2; /* second value */
};
struct msg mailboxes[MAXTHREAD + 1];
pthread_t threads[MAXTHREAD + 1];
sem_t semaphores[MAXTHREAD + 1];
int SendMsg(int iTo, struct msg &Msg);
int RecvMsg(int iFrom, struct msg &Msg);
bool safeToCall(int location);
#endif
I am compiling the code with the command
g++ -o addem addem.cpp mailbox.cpp -lpthread
I have tried commenting out all of the function bodies in the source code to leave them as stub functions, and the same error occurs. The only way I have been able to compile the file is if I comment out the function bodies, and remove
#include "mailbox.h"
From at least one of the files. I feel it has to do with how I am initializing the arrays? But I cannot figure out a workaround.

CAN identifier message sync issue

I am struggling with a CAN code. with Arduino I am sending two signals with 2 different identifiers and my code checks the identifier id and then interprets the message as eithr state-of-charge or a Voltage message. The code works fine with a single SOC or volt message.
The problem im getting is that when there are multiple message, the code reads the identifier once and then reads all messages given. This means, it reads id 0x140, then reads all signals even the ones that are associated with other ids.
I don't know if its problem with my code or have to activate some flags or something.
//WORKS FINE FOR A SINGLE CAN MESSAGE, BUT HAVE ID - MESSAGE SYN ISSUES
//WITH MULTIPLE MESSAGES//
#include "pin_info.h"
#include <stdio.h>
#include <stdlib.h>
#include <Time.h>
#include <SPI.h> //for CAN
#include "mcp_can.h"
//#include "canLib.h"
#include "FreeMono9pt7b.h"
const int spiCSPin = 3;
MCP_CAN CAN(spiCSPin);
unsigned char len = 0;
unsigned char temp_buf[8];
unsigned char soc_buf[8]={0};
unsigned char volt_buf[8]={0};
unsigned char soc_mean[2], soc_min[2], soc_max[2] ={0,0};
float s_mean, s_min, s_max;
unsigned char volt_mean[2], volt_max[2], volt_min[2]= {0,0};
float v_mean, v_min, v_max;
int len_= sizeof(soc_mean);
const char Message[]= "CAN Message: " ;
const char Name[]= "foxBMS";
//enum type{soc,SOC, volt, VOLT};
void setup()
{
/*FOR CAN*/
Serial.begin(115200);
pinMode(LED_BUILTIN,OUTPUT);
while (CAN_OK != CAN.begin(CAN_500KBPS))
{
Serial.println("CAN BUS Init Failed");
delay(100);
}
Serial.println("CAN BUS Init OK!");
/* set mask, set both the mask to 0x3ff*/
CAN.init_Mask(0, 0, 0x3ff); // there are 2 mask in mcp2515, you need to set both of them
CAN.init_Mask(1, 0, 0x3ff);
/*set filter, we can receive id from 0x140 & 0x170 */
CAN.init_Filt(0, 0, 0x140); // there are 6 filter in mcp2515
CAN.init_Filt(1, 0, 0x170); // there are 6 filter in mcp2515
}
void loop()
{
if(CAN_MSGAVAIL == CAN.checkReceive())
{
unsigned long canId = CAN.getCanId();
CAN.readMsgBuf(&len, temp_buf);
assign(temp_buf,canId);
serialDisplay(canId);
//CAN.checkClearRxStatus(temp_buf);
CAN.clearBufferTransmitIfFlags();
}
else
{ Serial.print("No message received \n");
}
}
void assign(unsigned char buf[], unsigned long id)
{
if(id==0x00)
{}
else if(id==0x140)
{
for (int i=0; i<len; i++)
{
if (i<2)
soc_mean[i]= buf[i];
else if (i<4 && i>=2)
soc_min[i-2]= buf[i];
else if (i<6 && i>=4)
soc_max[i-4]= buf[i];
}
}
else if(id==0x170)
{
for (int i=0; i<len; i++)
{
if (i<2)
volt_mean[i]= buf[i];
else if (i<4 && i>=2)
volt_min[i-2]= buf[i];
else if (i<6 && i>=4)
volt_max[i-4]= buf[i];
}
}
}
void serialDisplay(unsigned long id)
{
Serial.println("-----------------------------");
Serial.print("Data from ID: ");
Serial.print(id,HEX); Serial.println("- CAN0_MSG");
for(int i = 0; i<len; i++)
{
Serial.print(temp_buf[i], HEX); Serial.print("\t");
}
Serial.print("\n");
}

How to avoid global semaphores and queues when using threads

I have a problem with my code. It works, but I cannot avoid using global semaphores. I have 3 thread functions. the first is run by 10 threads. The second and third are run by 2 threads each. These threads should run without having race conditions. In addition, they should communicate with each other. I use a user defined queue class for communications between threads and between the threads and main. Also, I use the semaphores to achieve mutual exclusion between the threads. Since I declare the instance of the queue class and the semaphores in a global manner, I do not have to pass them to any function. They are accessible to any function in this program. However, this is not a healthy way to write programs. Therefore, I ask you, how to declare the queue and the semaphores locally, and what is the best way to pass them between threads.
// queueString header
#include <string>
#include <queue>
#include <semaphore.h>
using namespace std;
class queueString
{
public:
queueString();
~queueString();
void qPush(string str);
string qPop();
private:
sem_t queueSem;
queue <string> q;
};
//queueString class
#include "queueString.h"
using namespace std;
// queue class that will enqueue and dequeue atomically.
queueString::queueString(){
sem_init(&queueSem, 0, 1);
}
queueString::~queueString(){}
void queueString::qPush(string str){
sem_wait(&queueSem);
this->q.push(str);
sem_post(&queueSem);
}
string queueString::qPop(){
sem_wait(&queueSem);
string str = this->q.front();
q.pop();
sem_post(&queueSem);
return str;
}
//The three threads with main
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <iostream>
#include "queueString.h"
using namespace std;
//My question is here, How to declare the variables below locally, and where
// is the right place to declare them, and how to pass them to threads?
sem_t s12, s13, s21, s31, sthr1, sthr2[2], sthr3[2], printSem;
sem_t idInitializationSemMainToThread, idInitializationSemThreadToMain;
queueString q = queueString();
#define THR1NUM 10
#define THR2NUM 2
#define THR3NUM 2
void printString(string str);
void *thread1(void* arg){
sem_wait(&idInitializationSemMainToThread);
int *pnum = (int *)arg;
int thr_1_ID = *pnum;
sem_post(&idInitializationSemThreadToMain);
sem_wait(&sthr1);
string value= "THR1 ";
value.append(to_string(thr_1_ID));
q.qPush(value);
sem_post(&s12);
sem_wait(&s21);
value= "2nd Iteration THR1 ";
value.append(to_string(thr_1_ID));
q.qPush(value);
sem_post(&s13);
sem_wait(&s31);
sem_post(&sthr1);
}
void *thread2(void* arg){
sem_wait(&idInitializationSemMainToThread);
int *pnum = (int *)arg;
int thr_2_ID = *pnum;
sem_post(&idInitializationSemThreadToMain);
while (true)
{
sem_wait(&sthr2[thr_2_ID]);
sem_wait(&s12);
string readVal = q.qPop();
printString(readVal + ", THR2 "+ to_string(thr_2_ID));
if (thr_2_ID==0)
sem_post(&sthr2[1]);
else
sem_post(&sthr2[0]);
sem_post(&s21);
}
}
void *thread3(void* arg){
sem_wait(&idInitializationSemMainToThread);
int *pnum = (int *)arg;
int thr_3_ID = *pnum;
sem_post(&idInitializationSemThreadToMain);
while (true)
{
sem_wait(&sthr3[thr_3_ID]);
sem_wait(&s13);
string readVal = q.qPop();
printString(readVal + " THR3 " + to_string(thr_3_ID));
if (thr_3_ID == 0)
sem_post(&sthr3[1]);
else
sem_post(&sthr3[0]);
sem_post(&s31);
}
}
int main(){
pthread_t thr1[THR1NUM], thr2[THR2NUM], thr3[THR3NUM];
sem_init(&s12, 0, 0);
sem_init(&s13, 0, 0);
sem_init(&s31, 0, 0);
sem_init(&s21, 0, 0);
sem_init(&printSem, 0, 1);
sem_init(&sthr1, 0, 0);
for (int i = 0; i < 2;i++)
sem_init(&sthr2[i], 0, 0);
for (int i = 0; i < 2;i++)
sem_init(&sthr3[i], 0, 0);
sem_init(&idInitializationSemMainToThread, 0, 0);
sem_init(&idInitializationSemThreadToMain, 0, 0);
int *pnum =(int *) malloc(sizeof(int));
for (int j = 0; j < THR2NUM;j++){
*pnum = j;
pthread_create(&thr2[j], NULL, thread2, (void *)pnum);
sem_post(&idInitializationSemMainToThread);
printString("thr2 "+to_string(j)+ " created");
sem_wait(&idInitializationSemThreadToMain);
}
for (int k = 0; k < THR3NUM;k++){
*pnum = k;
pthread_create(&thr3[k], NULL, thread3,(void *) pnum);
sem_post(&idInitializationSemMainToThread);
printString("thr3 "+to_string(k)+ " created");
sem_wait(&idInitializationSemThreadToMain);
}
for (int i = 0; i < THR1NUM;i++){
*pnum = i;
pthread_create(&thr1[i], NULL, thread1,(void *) pnum);
sem_post(&idInitializationSemMainToThread);
printString("thr1 "+to_string(i)+ " created");
sem_wait(&idInitializationSemThreadToMain);
}
sem_post(&sthr2[0]);
sem_post(&sthr3[0]);
sem_post(&sthr1);
for (int i = 0; i < THR1NUM;i++){
pthread_join(thr1[i], NULL);
printString("thr1 "+to_string(i)+ " joined");
}
for (int i = 0; i < THR2NUM; i++){
pthread_cancel(thr2[i]);
printString("thr2 "+to_string(i)+ " exited");
}
for (int i = 0; i < THR3NUM;i++){
pthread_cancel(thr3[i]);
printString("thr3 "+to_string(i)+ " exited");
sem_post(&printSem);
}
sem_destroy(&s12);
sem_destroy(&s21);
sem_destroy(&s13);
sem_destroy(&s31);
sem_destroy(&sthr1);
free(pnum);
}
// function to print strings atomically.
void printString(string str){
sem_wait(&printSem);
printf("%s\n", str.c_str());
sem_post(&printSem);
}

Segmentation fault (core dumped), storing char * to string vector of struct

#include <iostream>
#include <fstream>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <vector>
#include <sstream>
#define SHMSIZE 1024
using namespace std;
namespace patch
{
template < typename T > std::string to_string( const T& n )
{
std::ostringstream stm ;
stm << n ;
return stm.str() ;
}
}
struct process
{
int r;
string name;
vector<string> lines;
};
int main(int argc, char * argv[])
{
int firstRun = 1; //Skipping First Line of Assign-1.ip.
int quantum = 0; //For taking input of quantum.
int count = 0; //For number of processes.
int pchtoint;
string c;
char * pch; //For tokenization.
string reading_file; //Reading a line from file.
char * readarr; //Converting "reading_file" to readarr for tokenization.
process * p;
//=== Quantum Input ===//
cout<<"Enter Quantum size [1-1000]: ";
cin>>quantum;
while(quantum < 1 || quantum > 1000)
{
cout<<"Wrong input!!! Enter Again [1-1000]: ";
cin>>quantum;
}
//=====================//
//===Filing===//
ifstream read("Assign-2.ip");
if(read.is_open())
{
while(!read.eof())
{
getline(read, reading_file);
readarr = new char[reading_file.size() + 1];
for(int i = 0; i < reading_file.length(); i++)
{
readarr[i] = reading_file[i];
}
if(firstRun > 1)
{
int countingline = 0; //counting the number of lines in a process.
pch = strtok (readarr," ,");
while (pch != NULL)
{
c = pch[1];
pchtoint = atoi(c.c_str());
p[pchtoint-1].r++;
p[pchtoint-1].lines.push_back(pch);
for(int i = 0; i < p[pchtoint-1].lines.size(); i++)
cout<<p[pchtoint-1].name<<"=="<<p[pchtoint-1].lines.at(i)<<endl;
pch = strtok (NULL, " ,");
}
}
else
{
pch = strtok (readarr,",.-");
while (pch != NULL)
{
count++;
pch = strtok (NULL, ",.-");
}
p = new process[count];
string s = "p";
for(int i = 0; i < count; i++)
{
s = s + patch::to_string(i+1);
p[i].name = s;
s = s[0];
}
firstRun++;
}
}
}
else
{
cout<<"Cannot open file!!!"<<endl;
}
read.close();
return 0;
}
Enter Quantum size [1-1000]: 2
p1==p1-l1
p2==p2-l1
p3==p3-l1
p1==p1-l1
p1==p1-l2
p2==p2-l1
p2==p2-l2
p3==p3-l1
p3==p3-l2
p1==p1-l1
p1==p1-l2
p1==p1-l3
p3==p3-l1
p3==p3-l2
p3==p3-l3
p1==p1-l1
p1==p1-l2
p1==p1-l3
p1==p1-l4
Segmentation fault (core dumped)
I am reading data from a cvs file. and storing it in struct that is p here. but I don't know why it is giving segmentation fault. I am compiling it on ubuntu terminal.
The input file contains data:
P1, P2, P3,
p1-l1, p2-l1, p3-l1
p1-l2, p2-l2, p3-l2
p1-l3, , p3-l3
p1-l4, ,

Run C library from Node.js

I'm completely new to C, but have a small program (interfacing with hardware on RaspberryPi) that I'd like to be able to run from Node.js. From what I can make out in the Node.js docs, I can run a C++ program by exporting the program as a NODE_MODULE http://nodejs.org/api/addons.html
I've been trying to figure out the differences between C and C++, but am unsure if I can just export the code I want to run as a C++ file (maybe by changing the file extension to .cc?) Or if there is another way to use the C code in node.js.
Also, I don't understand if I need to 'build' the C file, or if I can provide node.js with the .c file extension.
I do not want to run the C code using the Node's child process, though I know that is possible. I would much prefer to export the C code as a module, as the Node.js documents describe.
Here's the code I'm looking to run in node.js
// How to access GPIO registers from C-code on the Raspberry-Pi
// Example program
// 15-January-2012
// Dom and Gert
//
// Access from ARM Running Linux
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
// WOULD I INCLUDE NODE.js HERE?? ##define BUILDING_NODE_EXTENSION
#include <node.h>
using namespace v8;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <bcm2835.h>
#include <unistd.h>
#define MAXTIMINGS 100
//#define DEBUG
#define DHT11 11
#define DHT22 22
#define AM2302 22
int readDHT(int type, int pin);
int main(int argc, char **argv)
{
if (!bcm2835_init())
return 1;
if (argc != 3) {
printf("usage: %s [11|22|2302] GPIOpin#\n", argv[0]);
printf("example: %s 2302 4 - Read from an AM2302 connected to GPIO #4\n", argv[0]);
return 2;
}
int type = 0;
if (strcmp(argv[1], "11") == 0) type = DHT11;
if (strcmp(argv[1], "22") == 0) type = DHT22;
if (strcmp(argv[1], "2302") == 0) type = AM2302;
if (type == 0) {
printf("Select 11, 22, 2302 as type!\n");
return 3;
}
int dhtpin = atoi(argv[2]);
if (dhtpin <= 0) {
printf("Please select a valid GPIO pin #\n");
return 3;
}
printf("Using pin #%d\n", dhtpin);
readDHT(type, dhtpin);
return 0;
} // main
int bits[250], data[100];
int bitidx = 0;
int readDHT(int type, int pin) {
int counter = 0;
int laststate = HIGH;
int j=0;
// Set GPIO pin to output
bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_write(pin, HIGH);
usleep(500000); // 500 ms
bcm2835_gpio_write(pin, LOW);
usleep(20000);
bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
// wait for pin to drop?
while (bcm2835_gpio_lev(pin) == 1) {
usleep(1);
}
// read data!
for (int i=0; i< MAXTIMINGS; i++) {
counter = 0;
while ( bcm2835_gpio_lev(pin) == laststate) {
counter++;
//nanosleep(1); // overclocking might change this?
if (counter == 1000)
break;
}
laststate = bcm2835_gpio_lev(pin);
if (counter == 1000) break;
bits[bitidx++] = counter;
if ((i>3) && (i%2 == 0)) {
// shove each bit into the storage bytes
data[j/8] <<= 1;
if (counter > 200)
data[j/8] |= 1;
j++;
}
}
#ifdef DEBUG
for (int i=3; i<bitidx; i+=2) {
printf("bit %d: %d\n", i-3, bits[i]);
printf("bit %d: %d (%d)\n", i-2, bits[i+1], bits[i+1] > 200);
}
#endif
printf("Data (%d): 0x%x 0x%x 0x%x 0x%x 0x%x\n", j, data[0], data[1], data[2], data[3], data[4]);
if ((j >= 39) &&
(data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) {
// yay!
if (type == DHT11)
printf("Temp = %d *C, Hum = %d \%\n", data[2], data[0]);
if (type == DHT22) {
float f, h;
h = data[0] * 256 + data[1];
h /= 10;
f = (data[2] & 0x7F)* 256 + data[3];
f /= 10.0;
if (data[2] & 0x80) f *= -1;
printf("Temp = %.1f *C, Hum = %.1f \%\n", f, h);
}
return 1;
}
return 0;
}
If you're completely new to C, it might actually be less of a headache to do this all from javascript-land instead, using one of several modules on npm for interacting with GPIO (on the Pi). One such module is the onoff module.