zynq_7010/zynq_7010_code/Sensor.cpp

287 lines
6.5 KiB
C++
Raw 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 "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_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);
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;
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;
while (bMonitor)
{
ret = poll(&pfd, 1, 1000);
if (ret <= 0)
{
continue;
}
if (pfd.revents & POLLPRI)
{
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");
if (ret)
{
printf("检测纸张进入 time%f\r\n",sw2.elapsed_ms());
sw1.reset();
}
else
{
printf("检测纸张出去 time%f\r\n",sw1.elapsed_ms());
sw2.reset();
}
edges[ret]->notify_all();
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);
}
}
}
}
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)
{
if(i == 1)
{
cv_paper_on.notify_all();
}
events.Put(evts[i * 2 + ret]);
}
}
}
}
}
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);
}