zynq_7010/zynq_7010_code/Sensor.cpp

310 lines
7.0 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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);
}