Skip to content

Commit

Permalink
rewrote ir_reader to be more optimal via gpio callbacks, still requir…
Browse files Browse the repository at this point in the history
…es cleaning up
  • Loading branch information
chutasano committed Apr 19, 2018
1 parent 9f323b4 commit a261789
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 94 deletions.
2 changes: 1 addition & 1 deletion ir_reader/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FLAGS=--std=c++11 -g
FLAGS=--std=c++11 -g -lpigpio -lm -lpthread -lrt

all: recorder

Expand Down
130 changes: 52 additions & 78 deletions ir_reader/ir_reader.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// based off http://hertaville.com/introduction-to-accessing-the-raspberry-pis-gpio-in-c.html

#include <chrono>
#include <condition_variable>
#include <mutex>
#include <fstream>
#include <iostream>
#include <list>
Expand All @@ -11,6 +13,11 @@
#include <unistd.h>
#include "ir_reader.h"

extern "C"
{
#include "pigpio.h"
}

const int LED_ON = 0; // for my system, LOW -> receiver detected infrared
const int LED_OFF = 1;
const int TIMEOUT_MS = 2000; // 2 seconds of no change seems reasonable
Expand All @@ -24,102 +31,69 @@ IrReader::IrReader(int num)
cout << "Bad GPIO val\n";
exit(1);
}
this->gpionum = to_string(num);
string export_str = "/sys/class/gpio/export";
ofstream exportgpio(export_str);
if (!exportgpio){
cout << "Unable to export GPIO"<< this->gpionum <<"\n";
exit(1);
}
exportgpio << this->gpionum; //write GPIO number to export
exportgpio.close();
string setdir_str ="/sys/class/gpio/gpio" + this->gpionum + "/direction";
ofstream setdirgpio(setdir_str); // open direction file for gpio
if (!setdirgpio){
cout << "Unable to set direction of GPIO"<< this->gpionum << "\n";
exit(1);
}
setdirgpio << "in";
setdirgpio.close();
if (getvalgpio)
{
getvalgpio.close(); //close the value file
}
this->gpionum = num;
}

IrReader::~IrReader()
{
string unexport_str = "/sys/class/gpio/unexport";
ofstream unexportgpio(unexport_str);
if (!unexportgpio){
cout << "Unable to unexport GPIO."<< this->gpionum <<"\n";
exit(1);
}
unexportgpio << this->gpionum ; //write GPIO number to unexport
unexportgpio.close(); //close unexport file
}

int IrReader::get_val()
vector<int> tmp;
bool init;
bool timed_out;
condition_variable cv;
mutex mtx;

void cb_get_code(int gpio, int level, uint32_t tick)
{
if (!getvalgpio)
cout << "Tick, " << level << endl;
static uint32_t last_tick;
static const uint32_t tick_wrap = 0xFFFFFFFF;
if (!init && level != PI_TIMEOUT)
{
string getval_str = "/sys/class/gpio/gpio" + this->gpionum + "/value";
getvalgpio.open(getval_str);
if (!getvalgpio)
{
cout << "Unable to get value of GPIO"<< this->gpionum <<"\n";
return -1;
}
init = true;
last_tick = tick;
gpioSetWatchdog(gpio, TIMEOUT_MS);
return;
}
int val;
getvalgpio >> val ; //read gpio value
return val;
}

list<string> IrReader::get_code()
{
list<int64_t> codes;
while (get_val() != LED_ON) // LOW -> IR detected
else if (level == PI_TIMEOUT)
{
// keep spinning until we get a LOW
timed_out = true;
cv.notify_one();
}
// we can assume IR is on right now because we just exitted the loop
// pair <on/off, time when detected>
auto stat = make_pair(LED_ON, chrono::high_resolution_clock::now());
bool loop = true;
while (loop)
else
{
int val = get_val();
if (val != get<0>(stat)) //status changed, we should record
int64_t time_diff_us = tick - last_tick;
if (time_diff_us < 0) time_diff_us += tick_wrap;
if (level == LED_ON)
{
auto now = chrono::high_resolution_clock::now();
auto diff = now - get<1>(stat);
if (get<0>(stat) == LED_ON) // means record positive number
{
codes.push_back(chrono::duration_cast<chrono::microseconds>(diff).count());
}
else
{
codes.push_back(-(chrono::duration_cast<chrono::microseconds>(diff).count()));
}
stat = make_pair(1-get<0>(stat), now);
tmp.push_back(-time_diff_us);
last_tick = tick;
}
// check if LED remains off for a while, if so break
if (val == LED_OFF)
else if (level == LED_OFF)
{
auto now = chrono::high_resolution_clock::now();
auto diff = now - get<1>(stat);
if (chrono::duration_cast<chrono::milliseconds>(diff).count() > TIMEOUT_MS)
{
loop = false;
}
tmp.push_back(time_diff_us);
last_tick = tick;
}
}
list<string> stringed_codes;
for (int64_t c : codes)
}

vector<int> IrReader::get_code()
{
if (gpioInitialise() < 0)
{
stringed_codes.push_back(to_string(c));
cerr << "Can't initialize pigpiod\n";
exit(1);
}
return stringed_codes;
gpioSetMode(gpionum, PI_INPUT);
unique_lock<mutex> lk(mtx);
tmp = vector<int>();
init = false;
timed_out = false;
gpioSetAlertFunc(gpionum, cb_get_code);
cv.wait(lk, [] {return timed_out;
});
gpioTerminate();
return tmp;
}

10 changes: 3 additions & 7 deletions ir_reader/ir_reader.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
// based off http://hertaville.com/introduction-to-accessing-the-raspberry-pis-gpio-in-c.html

#pragma once

#include <fstream>
#include <list>
#include <vector>
#include <string>

class IrReader
{
public:
IrReader(int num);
~IrReader();
std::list<std::string> get_code();
std::vector<int> get_code();

private:
int get_val();
std::string gpionum;
std::ifstream getvalgpio;
int gpionum;
};

8 changes: 4 additions & 4 deletions ir_reader/recorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@
#include <fstream>
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include "ir_reader.h"

#define GPIO_PIN 23

IrReader r(GPIO_PIN);

using namespace std;

int main(int argc, char* argv[])
{
IrReader r(GPIO_PIN);
if (argc > 2 || argc < 1)
{
cout << "Usage: " << argv[0] << " [filename: default = ircodes.txt]\n]";
exit(1);
}
cout << "Press a button to record on the remote\n";
list<string> codes = r.get_code();
vector<int> codes = r.get_code();
string filename;
if (argc == 2)
{
Expand All @@ -34,7 +34,7 @@ int main(int argc, char* argv[])
cin >> name;
ofstream w(filename, ofstream::out | ofstream::app);
w << "name: " << name << "\n";
for (string s : codes)
for (int s : codes)
{
w << s << " ";
}
Expand Down
9 changes: 5 additions & 4 deletions mqtt-sub.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
import subprocess as s

#change these based on your setup
muser="username"
mpass="password"
murl="public ip of ec2"
mport=1234 # port number as an int
muser="user"
mpass="user"
murl="ec2-18-218-182-153.us-east-2.computer.amazonaws.com"
mport=8883 # port number as an int

#called while client tries to establish connection with the server
def on_connect(mqttc, obj, flags, rc):
Expand Down Expand Up @@ -40,6 +40,7 @@ def on_message(mqttc, obj, msg):
mqttc.on_connect = on_connect
mqttc.on_subscribe = on_subscribe
mqttc.on_message = on_message
mqttc.tls_set(ca_certs="/home/pi/key/ca.crt")

#connecting to aws-account-specific-iot-endpoint
mqttc.connect(murl, port=mport) #AWS IoT service hostname and portno
Expand Down

0 comments on commit a261789

Please sign in to comment.