zynq_7010/zynq_7010_code/Sensor.cpp

353 lines
8.0 KiB
C++
Raw Permalink Normal View History

2023-07-17 03:29:37 +00:00
#include "Sensor.h"
#include "DevUtil.h"
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <thread>
#include <vector>
#include <iostream>
#include <stdio.h>
2023-11-18 03:48:39 +00:00
#include "StopWatch.h"
2023-07-17 03:29:37 +00:00
//FileTools ftt("/home/linaro/scanpin.log");
Sensor::Sensor(BlockingQueue<ScanEvent> &sysEvents)
:events(sysEvents),
2024-02-23 07:29:14 +00:00
screw_pwm1(3,0),
screw_pwm2(3,1),
2023-07-17 03:29:37 +00:00
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),
2023-09-01 01:51:35 +00:00
double_out0_Pin(PIN_PORT_7010::ULTRASONIC_SENSORS_OUT1),
double_out1_Pin(PIN_PORT_7010::ULTRASONIC_SENSORS_OUT0),
2024-02-05 06:55:03 +00:00
sensor_power(PIN_PORT_7010::SENSOR_POWER),
screw_detect(PIN_PORT_7010::SCREW_DETECTION),
2024-02-23 07:29:14 +00:00
width_detect(PIN_PORT_7010::WIDTH_DETECTION),
is_width_enable(false)
2023-07-17 03:29:37 +00:00
{
2024-02-23 07:29:14 +00:00
screw_pwm1.enable(false);
screw_pwm2.enable(false);
2023-08-31 08:37:05 +00:00
2023-07-17 03:29:37 +00:00
sensor_power.setValue(Gpio::High); //默认打开电源
2024-02-05 06:55:03 +00:00
doubleEnablePin.setValue(Gpio::Low);
screw_detect.setValue(Gpio::Low);
width_detect.setValue(Gpio::Low);
2023-07-17 03:29:37 +00:00
2023-08-31 08:37:05 +00:00
///////输入输出模式//////
2023-07-17 03:29:37 +00:00
coverPin.setDirection(Gpio::in);
paperPin.setDirection(Gpio::in);
2023-08-31 08:37:05 +00:00
scanPin.setDirection(Gpio::in);
2023-07-17 03:29:37 +00:00
double_out0_Pin.setDirection(Gpio::in);
double_out1_Pin.setDirection(Gpio::in);
2023-08-31 08:37:05 +00:00
sensor_power.setDirection(Gpio::in);
2024-02-05 06:55:03 +00:00
screw_detect.setDirection(Gpio::in);
width_detect.setDirection(Gpio::in);
2023-07-17 03:29:37 +00:00
doubleEnablePin.setDirection(Gpio::out);
2023-08-31 08:37:05 +00:00
2024-02-23 07:29:14 +00:00
set_screw_Freq(2580); //test
2023-08-31 08:37:05 +00:00
//////////中断模式///////
double_out0_Pin.setEdge(Gpio::both);
double_out1_Pin.setEdge(Gpio::both);
doubleEnablePin.setEdge(Gpio::both);
2023-07-17 03:29:37 +00:00
coverPin.setEdge(Gpio::both);
paperPin.setEdge(Gpio::both);
2023-08-31 08:37:05 +00:00
scanPin.setEdge(Gpio::both);
2024-02-22 06:05:17 +00:00
width_detect.setEdge(Gpio::both);
2024-02-23 07:29:14 +00:00
screw_detect.setEdge(Gpio::both);
2023-07-17 03:29:37 +00:00
//std::cout<<"scanPin "<< scanPin.getValue()<<std::endl;
thread_monitor = std::thread(&Sensor::monitor, this);
thread_monitor2 = std::thread(&Sensor::monitor2, this);
enableDoubleSensor(false);
screw_detect_enable(false);
2023-07-17 03:29:37 +00:00
}
Sensor::~Sensor()
{
bMonitor = false;
bMonitor2 = false;
if(thread_monitor.joinable())
thread_monitor.join();
if(thread_monitor2.joinable())
thread_monitor2.join();
}
bool Sensor::isCoverClosed()
{
return coverPin.getValue() == Gpio::Low;
}
2024-02-22 06:05:17 +00:00
bool Sensor::isWidthDetect()
{
return coverPin.getValue() == Gpio::High;
}
2023-07-17 03:29:37 +00:00
void Sensor::resetPaperPin()
{
scanPin.setDirection("in");
}
bool Sensor::isPaperStandby()
{
return paperPin.getValue();
}
bool Sensor::isPaperAtScan()
{
return scanPin.getValue();
}
bool Sensor::isDoublePaper()
{
return doubleEnablePin.getValue();
}
bool Sensor::waitPaperIn(int timeout_ms)
{
std::unique_lock<std::mutex> lck(cv_m);
2024-02-05 06:55:03 +00:00
bool b = cv_scan_at.wait_for(lck, std::chrono::milliseconds(timeout_ms)) == std::cv_status::no_timeout;
return b;
2023-07-17 03:29:37 +00:00
}
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;
2023-11-18 03:48:39 +00:00
return isPaperIn();
2023-07-17 03:29:37 +00:00
}
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;
2023-09-04 03:28:08 +00:00
StopWatch sw1;
StopWatch sw2;
2023-07-17 03:29:37 +00:00
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;
2023-11-18 03:48:39 +00:00
bool b = false;
2023-07-17 03:29:37 +00:00
while (bMonitor)
{
ret = poll(&pfd, 1, 1000);
2023-09-19 02:40:47 +00:00
if (ret <= 0)
2023-07-17 03:29:37 +00:00
{
2024-02-05 06:55:03 +00:00
sw2.reset();
2023-09-19 02:40:47 +00:00
continue;
}
if (pfd.revents & POLLPRI)
{
2023-11-04 01:38:17 +00:00
if(sw.elapsed_ms() < 10)
{
indx++;
if (indx % 10 == 0)
{
printf("扫描传感器消抖数:%d\r\n",indx);
2023-11-16 06:49:01 +00:00
}
2023-11-04 01:38:17 +00:00
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;
}
2023-09-19 02:40:47 +00:00
lseek(pfd.fd, 0, SEEK_SET);
num = read(pfd.fd, buf, 8);
buf[num - 1] = '\0';
ret = atoi(buf);
2023-11-18 03:48:39 +00:00
2023-09-19 02:40:47 +00:00
if (ret)
2023-07-17 03:29:37 +00:00
{
2023-11-04 01:38:17 +00:00
b = true;
//printf("检测纸张进入 time%f\r\n",sw2.elapsed_ms());
2023-09-19 02:40:47 +00:00
sw1.reset();
}
else
{
//printf("检测纸张出去 time%f\r\n",sw1.elapsed_ms());
2023-09-19 02:40:47 +00:00
sw2.reset();
2023-11-04 01:38:17 +00:00
if (!b) //理论上来说
{
printf("没有检测到纸张进入\r\n");
2023-11-04 01:38:17 +00:00
continue;
2023-11-18 03:48:39 +00:00
}
b = false;
2023-09-19 02:40:47 +00:00
}
2023-11-18 03:48:39 +00:00
2023-09-19 02:40:47 +00:00
edges[ret]->notify_all();
2023-09-04 03:28:08 +00:00
2023-11-04 01:38:17 +00:00
sw.reset();
2023-09-19 02:40:47 +00:00
}
2023-07-17 03:29:37 +00:00
}
close(pfd.fd);
}
void Sensor::monitor2()
{
2024-02-23 07:29:14 +00:00
ScanEvent evts[] = {HG_EVT_COVER_CLOSED , HG_EVT_COVER_OPENED ,
HG_EVT_PAPER_NOT_STANDBY, HG_EVT_PAPER_STANDBY,
HG_EVT_NOT_DOUBLEPAPER , HG_EVT_DOUBLEPAPER,
HG_EVT_NOT_DOUBLEPAPER , HG_EVT_DOUBLEPAPER,
HG_EVT_NOT_OUT_BOUNDS , HG_EVT_OUT_BOUNDS,
HG_EVT_SCREW_NOT_DETECTION , HG_EVT_SCREW_DETECTION};
2023-07-17 03:29:37 +00:00
std::vector<Gpio *> gpios;
gpios.push_back(&coverPin);
gpios.push_back(&paperPin);
2023-08-31 08:37:05 +00:00
gpios.push_back(&double_out0_Pin);
gpios.push_back(&double_out1_Pin);
2024-02-22 06:05:17 +00:00
gpios.push_back(&width_detect);
2024-02-23 07:29:14 +00:00
gpios.push_back(&screw_detect);
2023-07-17 03:29:37 +00:00
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);
2023-09-19 02:40:47 +00:00
if (ret < 0)
{
continue;
}
2024-02-22 06:05:17 +00:00
2023-09-19 02:40:47 +00:00
for (size_t i = 0; i < pollfds.size(); ++i)
2023-07-17 03:29:37 +00:00
{
2023-09-19 02:40:47 +00:00
if (pollfds[i].revents)
2023-07-17 03:29:37 +00:00
{
2023-09-19 02:40:47 +00:00
ret = readfile(pollfds[i].fd,num,buf);
if (i == 2)
2023-07-17 03:29:37 +00:00
{
2023-09-19 02:40:47 +00:00
double_1 = ret;
2024-01-05 08:20:44 +00:00
printf("2 double_1 :%d double_2:%d\r\n",double_1,double_2);
2023-09-19 02:40:47 +00:00
if (double_2 && double_1 && enbale_double_)
2023-07-17 03:29:37 +00:00
{
2024-02-22 06:05:17 +00:00
events.Put(ScanEvent(HG_EVT_DOUBLEPAPER));
2023-09-19 02:40:47 +00:00
enableDoubleSensor(false);
2023-07-17 03:29:37 +00:00
}
2023-09-19 02:40:47 +00:00
}
if (i == 3)
{
double_2 = ret;
2024-01-05 08:20:44 +00:00
printf("3 double_1 :%d double_2:%d\r\n",double_1,double_2);
2023-09-19 02:40:47 +00:00
if (double_2 && double_1 && enbale_double_)
2023-08-31 08:37:05 +00:00
{
2024-02-22 06:05:17 +00:00
events.Put(ScanEvent(HG_EVT_DOUBLEPAPER));
2023-09-19 02:40:47 +00:00
enableDoubleSensor(false);
2023-07-17 03:29:37 +00:00
}
2023-08-31 08:37:05 +00:00
2023-09-19 02:40:47 +00:00
}
2023-09-19 02:40:47 +00:00
if (i != 2 && i != 3)
{
int val = i * 2 + ret;
if (is_open_cover && (val == 1 || val == 2 ||val == 3)) //这个地方主要作用是在开盖以防其他状态消息发送
break;
if (val == 8 || val == 9) //边界检测没有使能脚,所以这里通过条件来进行处理
{
if (val == 8 || !is_width_enable)
{
continue;
}
is_width_enable = false;
events.Put(ScanEvent(HG_EVT_OUT_BOUNDS));
continue;
}
if(val == 1)
2023-09-19 02:40:47 +00:00
{
is_open_cover = true;
2023-09-19 02:40:47 +00:00
cv_paper_on.notify_all();
}
if(val == 0)
is_open_cover = false;
2024-02-22 06:05:17 +00:00
if (HG_EVT_SCREW_DETECTION == evts[val])
{
screw_detect_enable(false);
}
if (val == 10)
2024-02-22 06:05:17 +00:00
{
2024-02-23 07:29:14 +00:00
continue;
2024-02-22 06:05:17 +00:00
}
//printf("i:%d val :%d evts[val]:%d\r\n",i,val,evts[val]);
events.Put(evts[val]);
2023-07-17 03:29:37 +00:00
}
}
2023-09-19 02:40:47 +00:00
}
2023-07-17 03:29:37 +00:00
}
}
for (size_t i = 0; i < pollfds.size(); ++i)
{
close(pollfds[i].fd);
}
}
2023-08-31 08:37:05 +00:00
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);
}