310 lines
7.0 KiB
C++
310 lines
7.0 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 "StopWatch.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_OUT1),
|
||
double_out1_Pin(PIN_PORT_7010::ULTRASONIC_SENSORS_OUT0),
|
||
sensor_power(PIN_PORT_7010::SENSOR_POWER)
|
||
|
||
{
|
||
|
||
pwm2.setFreq(2583);
|
||
|
||
pwm2.enable(Gpio::High);
|
||
sensor_power.setValue(Gpio::High); //默认打开电源
|
||
doubleEnablePin.setValue(Gpio::High);
|
||
|
||
///////输入输出模式//////
|
||
coverPin.setDirection(Gpio::in);
|
||
paperPin.setDirection(Gpio::in);
|
||
scanPin.setDirection(Gpio::in);
|
||
double_out0_Pin.setDirection(Gpio::in);
|
||
double_out1_Pin.setDirection(Gpio::in);
|
||
sensor_power.setDirection(Gpio::in);
|
||
|
||
doubleEnablePin.setDirection(Gpio::out);
|
||
|
||
|
||
//////////中断模式///////
|
||
double_out0_Pin.setEdge(Gpio::both);
|
||
double_out1_Pin.setEdge(Gpio::both);
|
||
doubleEnablePin.setEdge(Gpio::both);
|
||
coverPin.setEdge(Gpio::both);
|
||
paperPin.setEdge(Gpio::both);
|
||
scanPin.setEdge(Gpio::both);
|
||
|
||
//std::cout<<"scanPin "<< scanPin.getValue()<<std::endl;
|
||
thread_monitor = std::thread(&Sensor::monitor, this);
|
||
thread_monitor2 = std::thread(&Sensor::monitor2, this);
|
||
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);
|
||
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;
|
||
StopWatch sw1;
|
||
StopWatch sw2;
|
||
num = read(pfd.fd, buf, 8); // This is to clear the avaible read
|
||
std::cout<<"read time "<< sw.elapsed_ms()<<std::endl;
|
||
int indx = 0;
|
||
bool b = false;
|
||
while (bMonitor)
|
||
{
|
||
ret = poll(&pfd, 1, 1000);
|
||
if (ret <= 0)
|
||
{
|
||
continue;
|
||
}
|
||
if (pfd.revents & POLLPRI)
|
||
{
|
||
if(sw.elapsed_ms() < 10)
|
||
{
|
||
indx++;
|
||
if (indx % 10 == 0)
|
||
{
|
||
printf("扫描传感器消抖数:%d\r\n",indx);
|
||
}
|
||
sw.reset();
|
||
ret = poll(&pfd, 1, 1);
|
||
if (ret > 0)
|
||
{
|
||
lseek(pfd.fd, 0, SEEK_SET);
|
||
num = read(pfd.fd, buf, 8);
|
||
buf[num - 1] = '\0';
|
||
ret = atoi(buf);
|
||
}
|
||
continue;
|
||
}
|
||
|
||
lseek(pfd.fd, 0, SEEK_SET);
|
||
num = read(pfd.fd, buf, 8);
|
||
buf[num - 1] = '\0';
|
||
ret = atoi(buf);
|
||
|
||
|
||
if (ret)
|
||
{
|
||
b = true;
|
||
printf("检测纸张进入 time:%f\r\n",sw2.elapsed_ms());
|
||
sw1.reset();
|
||
}
|
||
else
|
||
{
|
||
printf("检测纸张出去 time:%f\r\n",sw1.elapsed_ms());
|
||
sw2.reset();
|
||
if (!b) //理论上来说
|
||
{
|
||
printf("没有检测到纸张进入\r\n");
|
||
continue;
|
||
}
|
||
b = false;
|
||
}
|
||
|
||
edges[ret]->notify_all();
|
||
|
||
sw.reset();
|
||
}
|
||
}
|
||
|
||
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;
|
||
for (size_t i = 0; i < gpios.size(); ++i)
|
||
{
|
||
fd = open(gpios[i]->getValuePath().c_str(), O_RDONLY);
|
||
if (fd < 0)
|
||
{
|
||
ret = -1;
|
||
break;
|
||
}
|
||
|
||
pfd.fd = fd;
|
||
pfd.events = POLLPRI;
|
||
num = read(fd, buf, 8); // This is to clear the avaible read
|
||
pollfds.push_back(pfd);
|
||
}
|
||
|
||
if (ret >= 0)
|
||
{
|
||
bMonitor2 = true;
|
||
while (bMonitor2)
|
||
{
|
||
ret = poll(&pollfds[0], pollfds.size(), 1000);
|
||
if (ret < 0)
|
||
{
|
||
continue;
|
||
}
|
||
for (size_t i = 0; i < pollfds.size(); ++i)
|
||
{
|
||
if (pollfds[i].revents)
|
||
{
|
||
ret = readfile(pollfds[i].fd,num,buf);
|
||
|
||
if (i == 2)
|
||
{
|
||
double_1 = ret;
|
||
printf("2 double_1 :%d double_2:%d\r\n",double_1,double_2);
|
||
if (double_2 && double_1 && enbale_double_)
|
||
{
|
||
events.Put(ScanEvent(S_EVT_DOUBLEPAPER));
|
||
enableDoubleSensor(false);
|
||
}
|
||
|
||
}
|
||
if (i == 3)
|
||
{
|
||
double_2 = ret;
|
||
printf("3 double_1 :%d double_2:%d\r\n",double_1,double_2);
|
||
if (double_2 && double_1 && enbale_double_)
|
||
{
|
||
events.Put(ScanEvent(S_EVT_DOUBLEPAPER));
|
||
enableDoubleSensor(false);
|
||
}
|
||
|
||
}
|
||
if (i != 2 && i != 3)
|
||
{
|
||
int val = i * 2 + ret;
|
||
if (is_open_cover && (val == 1 || val == 2 ||val == 3)) //这个地方主要作用是在开盖以防其他状态消息发送
|
||
break;
|
||
if(val == 1)
|
||
{
|
||
is_open_cover = true;
|
||
cv_paper_on.notify_all();
|
||
}
|
||
if(val == 0)
|
||
is_open_cover = false;
|
||
|
||
events.Put(evts[val]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
for (size_t i = 0; i < pollfds.size(); ++i)
|
||
{
|
||
close(pollfds[i].fd);
|
||
}
|
||
}
|
||
|
||
int Sensor::readfile(int fd,int num , char* buf){
|
||
lseek(fd, 0, SEEK_SET);
|
||
num = read(fd, buf, 8);
|
||
buf[num - 1] = '\0';
|
||
return atoi(buf);
|
||
} |