zynq_7010/Sensor.cpp

257 lines
6.5 KiB
C++

#include "Sensor.h"
#include "DevUtil.h"
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <thread>
#include <vector>
#include <iostream>
#include <stdio.h>
#include "filetools.h"
//FileTools ftt("/home/linaro/scanpin.log");
Sensor::Sensor(BlockingQueue<ScanEvent> &sysEvents)
:events(sysEvents),
pwm2(2),
coverPin(PIN_PORT_7010::OPEN_COVER_SENSOR),
paperPin(PIN_PORT_7010::HAVE_OR_NO_PAPER),
scanPin (PIN_PORT_7010::SCAN_SENSOR),
doubleEnablePin(PIN_PORT_7010::ULTRASONIC_SENSORS_ON),
double_out0_Pin(PIN_PORT_7010::ULTRASONIC_SENSORS_OUT0),
double_out1_Pin(PIN_PORT_7010::ULTRASONIC_SENSORS_OUT1),
sensor_power(PIN_PORT_7010::SENSOR_POWER)
{
pwm2.enable(Gpio::High);
pwm2.setFreq(2583);
sensor_power.setDirection(Gpio::in);
sensor_power.setValue(Gpio::High); //默认打开电源
coverPin.setDirection(Gpio::in);
paperPin.setDirection(Gpio::in);
double_out0_Pin.setDirection(Gpio::in);
double_out1_Pin.setDirection(Gpio::in);
//paperJamPin.setDirection(Gpio::in);
scanPin.setDirection(Gpio::in);
scanPin.setEdge(Gpio::both);
doubleEnablePin.setDirection(Gpio::out);
coverPin.setEdge(Gpio::both);
paperPin.setEdge(Gpio::both);
double_out0_Pin.setEdge(Gpio::both);
double_out1_Pin.setEdge(Gpio::both);
//std::cout<<"scanPin "<< scanPin.getValue()<<std::endl;
thread_monitor = std::thread(&Sensor::monitor, this);
thread_monitor2 = std::thread(&Sensor::monitor2, this);
enableDoubleSensor(true);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
enableDoubleSensor(false);
LOG(" init sensor done \n");
}
Sensor::~Sensor()
{
bMonitor = false;
bMonitor2 = false;
if(thread_monitor.joinable())
thread_monitor.join();
if(thread_monitor2.joinable())
thread_monitor2.join();
}
bool Sensor::isCoverClosed()
{
std::cout<<"isCoverClosed "<< coverPin.getValue()<<std::endl;
return coverPin.getValue() == Gpio::Low;
}
void Sensor::resetPaperPin()
{
scanPin.setDirection("in");
}
bool Sensor::isPaperStandby()
{
std::cout<<"isPaperStandby "<< paperPin.getValue()<<std::endl;
return paperPin.getValue();
}
bool Sensor::isPaperAtScan()
{
//std::cout<<"scanPin "<< scanPin.getValue()<<std::endl;
return scanPin.getValue();
}
bool Sensor::isDoublePaper()
{
return doubleEnablePin.getValue();
}
bool Sensor::waitPaperIn(int timeout_ms)
{
std::unique_lock<std::mutex> lck(cv_m);
return cv_scan_at.wait_for(lck, std::chrono::milliseconds(timeout_ms)) == std::cv_status::no_timeout;
}
bool Sensor::waitPaperOut(int timeout_ms)
{
std::unique_lock<std::mutex> lck(cv_m);
if (!isPaperIn())
{
LOG("scanPin Value is low! \n");
return true;
}
cv_scan_not_at.wait_for(lck, std::chrono::milliseconds(timeout_ms)) == std::cv_status::no_timeout;
return !isPaperIn();
}
bool Sensor::waitPaperStandBy(int timeout_ms)
{
if(!paperPin.getValue()) {
return true;
}
if(timeout_ms <= 0) {
return isPaperStandby();
}
std::unique_lock<std::mutex> lck(cv_m);
return cv_paper_on.wait_for(lck, std::chrono::milliseconds(timeout_ms)) == std::cv_status::no_timeout;
}
void Sensor::cancelWaitPaper()
{
cv_paper_on.notify_all();
}
void Sensor::monitor()
{
std::condition_variable *edges[] = {&cv_scan_not_at, &cv_scan_at};
pollfd pfd;
int ret = 0;
pfd.fd = -1;
char buf[8];
int num;
pfd.fd = open(scanPin.getValuePath().c_str(), O_RDONLY);
if (pfd.fd < 0)
{
ret = -1;
}
pfd.events = POLLPRI;
StopWatch sw;
num = read(pfd.fd, buf, 8); // This is to clear the avaible read
std::cout<<"read time "<< sw.elapsed_ms()<<std::endl;
while (bMonitor)
{
ret = poll(&pfd, 1, 1000);
if (ret > 0)
{
if (pfd.revents & POLLPRI)
{
LOG(" ------------------------ scanpin running--------------------- \n");
lseek(pfd.fd, 0, SEEK_SET);
num = read(pfd.fd, buf, 8);
buf[num - 1] = '\0';
ret = atoi(buf);
//ftt.append_log(ret?"in":"out");
edges[ret]->notify_all();
LOG("\n *************scanpin %d time = %s ********* \n",ret,GetCurrentTimeStamp(2).c_str());
//sw.reset();
while(sw.elapsed_ms() < 10)
{
ret = poll(&pfd, 1, 1);
if (ret > 0)
{
num = read(pfd.fd, buf, 8);
buf[num - 1] = '\0';
ret = atoi(buf);
//printf("pMonitor nread = %d ret val = %d \n",num,ret);
}
}
}
}
}
close(pfd.fd);
}
void Sensor::monitor2()
{
ScanEvent evts[] = {S_EVT_COVER_CLOSED, S_EVT_COVER_OPENED , S_EVT_PAPER_STANDBY, S_EVT_PAPER_NOT_STANDBY,
S_EVT_NOT_DOUBLEPAPER, S_EVT_DOUBLEPAPER, S_EVT_JAM_OUT, S_EVT_NORES};
std::vector<Gpio *> gpios;
gpios.push_back(&coverPin);
gpios.push_back(&paperPin);
//gpios.push_back(&double_out0_Pin);
//gpios.push_back(&double_out1_Pin);
std::vector<pollfd> pollfds;
pollfd pfd;
int ret = 0;
int fd = -1;
char buf[8];
int num;
LOG(" ------------------------ monitor2 running \n");
for (size_t i = 0; i < gpios.size(); ++i)
{
fd = open(gpios[i]->getValuePath().c_str(), O_RDONLY);
LOG(" ------------------------ monitor2 open gpio[%d]=%s \n",i,gpios[i]->getValuePath().c_str());
if (fd < 0)
{
ret = -1;
LOG(" ------------------------ monitor2 open break \n");
break;
}
pfd.fd = fd;
pfd.events = POLLPRI;
num = read(fd, buf, 8); // This is to clear the avaible read
pollfds.push_back(pfd);
}
LOG(" ------------------------ monitor2 while running \n");
if (ret >= 0)
{
bMonitor2 = true;
while (bMonitor2)
{
static int poll_t = 0;
ret = poll(&pollfds[0], pollfds.size(), 1000);
//LOG(" ------------------------ monitor2 while running poll_t=%d ret=%d \n",++poll_t,ret);
if (ret > 0)
{
for (size_t i = 0; i < pollfds.size(); ++i)
{
if (pollfds[i].revents)
{
fd = pollfds[i].fd;
lseek(fd, 0, SEEK_SET);
num = read(fd, buf, 8);
buf[num - 1] = '\0';
ret = atoi(buf);
LOG("event id : %d i= %d \n",evts[i * 2 + ret] , i );
if(evts[i * 2 + ret] == 272)
{
LOG("\n\n---------------double paper ----------------:%s \n\n", GetCurrentTimeStamp(2).c_str());
enableDoubleSensor(false);
}
if(i == 1)
{
LOG("paper sensor ret:%d \n", ret);
cv_paper_on.notify_all();
}
events.Put(evts[i * 2 + ret]);
}
}
}
}
}
for (size_t i = 0; i < pollfds.size(); ++i)
{
close(pollfds[i].fd);
}
}