Java教程

基于Arduino ATmega328人脸识别IOT演示开关

本文主要是介绍基于Arduino ATmega328人脸识别IOT演示开关,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

 

§01 Arduino ATmega328 测试电路


根据 Arduino门禁人机接口调试 Version 1.0 基于Groove Beginner的背板的设计基础上,按照 从0 开始 DIY你的Arduino UNO 设计方法,将ATmega328直接与接口电路设计成一个单一的电路板,便可以大大简化系统的构成了。

1、电路设计

▲ 图1-1 最小系统原理图

▲ 图1-1 最小系统原理图

▲ 图1-2 ESP8266子系统电路

▲ 图1-2 ESP8266子系统电路

▲ 图1-3 接口电路

▲ 图1-3 接口电路

▲ 图1-4 USB下载电路接口

▲ 图1-4 USB下载电路接口

2、接口说明

根据下图所示的Arduino管脚的定义,结合前面的原理图设计,可以分别确定按键LED模块舵机语音模块人脸模块ESP8266模块的接口

▲ 图2-1 Arduino 管脚定义

▲ 图2-1 Arduino 管脚定义

(1)按键接口

按键的行扫描与列扫描分别使用 D4D5D6D7D8D9D18D19。键盘的读取参考程序参见:

/*
**==============================================================================
** TESTKEY.C:             -- by Dr. ZhuoQing, 2021-05-25
**
**==============================================================================
*/

//------------------------------------------------------------------------------

#define KEYLINE_1       4
#define KEYLINE_2       5
#define KEYLINE_3       6
#define KEYLINE_4       7
#define KEYCODE_1       8
#define KEYCODE_2       9
#define KEYCODE_3       18
#define KEYCODE_4       19

#define KEY_NULL        0xff
#define KEY_1           0x47
#define KEY_2           0x4B
#define KEY_3           0x4D
#define KEY_4           0x37
#define KEY_5           0x3B
#define KEY_6           0x3D
#define KEY_7           0x27
#define KEY_8           0x2B
#define KEY_9           0x2D
#define KEY_0           0x17
#define KEY_A           0x4E
#define KEY_B           0x3E
#define KEY_C           0x2E
#define KEY_D           0x1E
#define KEY_E           0x1D
#define KEY_F           0x1B

void keyLineSet(unsigned char ucLine) {
    if(ucLine & 0x1)    digitalWrite(KEYLINE_1, HIGH);
    else digitalWrite(KEYLINE_1, LOW);
    
    if(ucLine & 0x2)    digitalWrite(KEYLINE_2, HIGH);
    else digitalWrite(KEYLINE_2, LOW);
    
    if(ucLine & 0x4)    digitalWrite(KEYLINE_3, HIGH);
    else digitalWrite(KEYLINE_3, LOW);
    
    if(ucLine & 0x8)    digitalWrite(KEYLINE_4, HIGH);
    else digitalWrite(KEYLINE_4, LOW);        
}

void keySetup(void) {
    pinMode(KEYLINE_1, OUTPUT);
    pinMode(KEYLINE_2, OUTPUT);
    pinMode(KEYLINE_3, OUTPUT);
    pinMode(KEYLINE_4, OUTPUT);
    pinMode(KEYCODE_1, INPUT_PULLUP);
    pinMode(KEYCODE_2, INPUT_PULLUP);
    pinMode(KEYCODE_3, INPUT_PULLUP);
    pinMode(KEYCODE_4, INPUT_PULLUP);        
    
    keyLineSet(0x0);
}

unsigned char keyReadCode(void) {
    keyLineSet(0xe);
    if(keyCode() != 0xf) return 0x10 | keyCode();
    
    keyLineSet(0xd);
    if(keyCode() != 0xf) return 0x20 | keyCode();
    
    keyLineSet(0xb);
    if(keyCode() != 0xf) return 0x30 | keyCode();
    
    keyLineSet(0x7);
    if(keyCode() != 0xf) return 0x40 | keyCode();
    
    return 0xff;
}

unsigned char keyCode(void) {
    unsigned char ucCode;
    ucCode = 0x0;
    if(digitalRead(KEYCODE_1) == HIGH) ucCode |= 0x1;
    if(digitalRead(KEYCODE_2) == HIGH) ucCode |= 0x2;
    if(digitalRead(KEYCODE_3) == HIGH) ucCode |= 0x4;
    if(digitalRead(KEYCODE_4) == HIGH) ucCode |= 0x8;
    return ucCode;
}

//------------------------------------------------------------------------------
unsigned char Hex2Text(unsigned char ucCode) {
    if(ucCode < 10) {
        return '0' + ucCode;
    }
    
    return 'A' + ucCode - 10;

}

void SendHEX8(unsigned char ucCode) {
    Serial.write(Hex2Text(ucCode >> 4));
    Serial.write(Hex2Text(ucCode & 0xf));
}

//------------------------------------------------------------------------------
void setup(void) {
    Serial.begin(115200);
    keySetup();
    
}

//------------------------------------------------------------------------------
void loop(void) {
    delay(250);
    
    SendHEX8(keyReadCode());
    Serial.write("\r\n");
}

//==============================================================================
//                END OF THE FILE : TESTKEY.C
//------------------------------------------------------------------------------

(2)点阵LED模块接口

控制点阵LED模块的四个IO口分别为 D14D15D16D17

对于LED模块控制参考程序为:

/*
**==============================================================================
** TESTLED.C:             -- by Dr. ZhuoQing, 2021-05-25
**
**==============================================================================
*/

#define LED_DATA1       14
#define LED_DATA2       15
#define LED_CLK1        16
#define LED_CLK2        17

//------------------------------------------------------------------------------
unsigned char g_ucLEDBuffer[4][16];

void ledSetup(void) {
    int i, j;
    for(i = 0; i < 4; i ++) {
        for(j = 0; j < 16; j ++) {
            g_ucLEDBuffer[i][j] = 0x0;
        }

    }

    pinMode(LED_DATA1, OUTPUT);
    pinMode(LED_DATA2, OUTPUT);
    pinMode(LED_CLK1, OUTPUT);
    pinMode(LED_CLK2, OUTPUT);        
    
    digitalWrite(LED_CLK1, HIGH);
    digitalWrite(LED_CLK2, HIGH);
    digitalWrite(LED_DATA1, HIGH);
    digitalWrite(LED_DATA2, HIGH);
    
}

void ledSetData12(unsigned char ucData12) {
    if(ucData12 & 0x1) 
        digitalWrite(LED_DATA1, HIGH);
    else digitalWrite(LED_DATA1, LOW);
    
    if(ucData12 & 0x2) 
        digitalWrite(LED_DATA2, HIGH);
    else digitalWrite(LED_DATA2, LOW);
}

void ledClock1(void) {
    digitalWrite(LED_CLK1, HIGH);       // clock up 7us
    digitalWrite(LED_CLK1, LOW);
}

void ledClock2(void) {
    digitalWrite(LED_CLK2, HIGH);
    digitalWrite(LED_CLK2, LOW);
}

void ledStart(void) {
    digitalWrite(LED_DATA1, LOW);
    digitalWrite(LED_DATA2, LOW);
    digitalWrite(LED_CLK1, LOW);
    digitalWrite(LED_CLK2, LOW);
    
}

void ledStop(void) {
    digitalWrite(LED_DATA1, LOW);
    digitalWrite(LED_DATA2, LOW);

    digitalWrite(LED_CLK1, HIGH);
    digitalWrite(LED_CLK2, HIGH);
    digitalWrite(LED_DATA1, HIGH);
    digitalWrite(LED_DATA2, HIGH);
    
}

void ledWriteData(unsigned char ucChar1, unsigned char ucChar2,
                  unsigned char ucChar3, unsigned char ucChar4) {

    unsigned char i;
    unsigned char ucMask;
    
    ucMask = 0x1;
    
    for(i = 0; i < 8; i++) {
        if(ucChar1 & ucMask) digitalWrite(LED_DATA1, HIGH);
        else digitalWrite(LED_DATA1, LOW);            
        if(ucChar2 & ucMask) digitalWrite(LED_DATA2, HIGH);
        else digitalWrite(LED_DATA2, LOW);            
        
        digitalWrite(LED_CLK1, HIGH);       // clock up 7us
        digitalWrite(LED_CLK1, LOW);
        
        if(ucChar3 & ucMask) digitalWrite(LED_DATA1, HIGH);
        else digitalWrite(LED_DATA1, LOW);            
        if(ucChar4 & ucMask) digitalWrite(LED_DATA2, HIGH);
        else digitalWrite(LED_DATA2, LOW); 
                   
        digitalWrite(LED_CLK2, HIGH);       // clock up 7us
        digitalWrite(LED_CLK2, LOW);
        
        ucMask = ucMask << 1;
        
    }

}

//------------------------------------------------------------------------------
#define LEDCMD_ADD_INC          0x40
#define LEDCMD_ADD_SET          0x44
#define LEDCMD_MODE_CLOSE       0x80
#define LEDCMD_MODE_OPEN        0x8a

//------------------------------------------------------------                  
void ledWriteByteAll(unsigned char ucChar) {
    ledWriteData(ucChar, ucChar, ucChar, ucChar);
}

void ledWriteData16All(unsigned char ucData) {
    unsigned char i;
    
    ledStart();
    ledWriteByteAll(LEDCMD_ADD_INC);
    ledStop();
    
    ledStart();
    ledWriteByteAll(0xc0);
    for(i = 0; i < 16; i ++) {
        ledWriteByteAll(ucData);
    }
    
    ledStop();
    
    ledStart();    
    ledWriteByteAll(LEDCMD_MODE_OPEN);
    ledStop();
}

//------------------------------------------------------------------------------
void ledWriteBuffer(void) {
    unsigned char i;
    
    ledStart();
    ledWriteByteAll(LEDCMD_ADD_INC);
    ledStop();
    
    ledStart();
    ledWriteByteAll(0xc0);
    for(i = 0; i < 16; i ++) {
        ledWriteData(g_ucLEDBuffer[0][i],
                     g_ucLEDBuffer[1][i],
                     g_ucLEDBuffer[2][i],
                     g_ucLEDBuffer[3][i]);
    }
    
    ledStop();    
    ledStart();    
    ledWriteByteAll(LEDCMD_MODE_OPEN);
    ledStop();
}

//------------------------------------------------------------------------------
#define LED_PIN         13
void setup(void) {
    ledSetup();
    
    pinMode(LED_PIN, OUTPUT);
    
}

//------------------------------------------------------------------------------
unsigned char ucCount = 0;
void loop(void) {
    int i, j;
    
    ucCount ++;
    if(ucCount & 0x1) digitalWrite(LED_PIN, HIGH);
    else digitalWrite(LED_PIN, LOW);

    for(i = 0; i < 4; i ++) {
        for(j = 0; j < 16; j ++) {
            g_ucLEDBuffer[i][j] = ucCount;
        }

    }

    ledWriteBuffer();
    delay(500);
}

//==============================================================================
//                END OF THE FILE : TESTLED.C
//------------------------------------------------------------------------------

将按键与LED模块符合在一起的测试程序,请参见 Arduino门禁人机接口调试 Version 1.0 最后的例程。

(3)舵机接口

使用ATmega328 的MOSI(PB3)接口,对应的Arduino接口 D11。

根据 Grove Beginner Kits基础实验 Arduino 对于IO口控制舵机的讨论,需要将定时器2的寄存器TCCR2B进行修改,才能够将输出的频率修改成122.5Hz,满足舵机控制所需。参考处贴上如下:

const int PWM_PIN   = 11;
void setup() {
    TCCR2B = TCCR2B & B11111000 | B00000110;
    pinMode(PWM_PIN, OUTPUT);
}
void loop() {
    delay(1000);
    analogWrite(PWM_PIN, 63);
    delay(1000);
    analogWrite(PWM_PIN, 31);
}

上述程序分别输出31(对应1ms)与63(对应2ms),可以控制舵机从最左边移动到最右边。

PWM脉宽PWM设置值实际输出时间(us)实测时间(us)
1ms310.992ms0.988
1.5ms471.504ms1.5ms
2ms632.016ms2.01ms
/*
**==============================================================================
** TESTPWM.C:             -- by Dr. ZhuoQing, 2021-05-30
**
**==============================================================================
*/

#define ON(pin)                 digitalWrite(pin, HIGH)
#define OFF(pin)                digitalWrite(pin, LOW)
#define VAL(pin)                digitalRead(pin)
#define IN(pin)                 pinMode(pin, INPUT)
#define OUT(pin)                pinMode(pin, OUTPUT)
const int LED_PIN = 13;

const int PWM_PIN       = 11;
const int SERVO_MID     = 47;
const int SERVO_LEFT    = 31;
const int SERVO_RIGHT   = 63;
void servoSetup(void) {

    TCCR2B = TCCR2B & B11111000 | B00000110;
    pinMode(PWM_PIN, OUTPUT);
    analogWrite(PWM_PIN, SERVO_MID);
}

//------------------------------------------------------------------------------
void setup(void) {
    pinMode(LED_PIN, OUTPUT);
    
    servoSetup();
    
}

//------------------------------------------------------------------------------
void loop(void) {
    analogWrite(PWM_PIN, SERVO_LEFT);
    delay(1000);
    analogWrite(PWM_PIN, SERVO_RIGHT);
    delay(1000);
    
}

//==============================================================================
//                END OF FILE : TESTPWM.C
//------------------------------------------------------------------------------

(4)语音模块接口

语音模块使用了SoftwareSerial。利用ATmega328 的 MISO,SCK两个管脚(分别对应)D12,D13作为RX,TX。

语音模块使用9600的波特率。通过软件串口发送对应文字的编码便可以发出声音。

#include <SoftwareSerial.h>
//------------------------------------------------------------------------------
SoftwareSerial mySerial(12, 13);
void setup() {
    mySerial.begin(9600);
}
//------------------------------------------------------------------------------
void loop() {
    mySerial.write('U');
    delay(10);
}

下面的程序发送“卓一康”的读音。

/*
**==============================================================================
** TESTSERIAL.C:             -- by Dr. ZhuoQing, 2021-05-30
**
**==============================================================================
*/

#include <SoftwareSerial.h>

//------------------------------------------------------------------------------
SoftwareSerial ttsPort(12, 13);

void setup(void) {
    ttsPort.begin(9600);
    
}

//------------------------------------------------------------------------------
void loop(void) {
    ttsPort.write("\xd7\xbf\xd2\xbb\xbf\xb5");
    
    delay(1000);
}

//==============================================================================
//                END OF FILE : TESTSERIAL.C
//------------------------------------------------------------------------------

(5)人脸识别模块接口

未完待续

(6)ESP8266接口

ESP8266有ATmega328 的SoftwareSerial相连接。使用到D2,D3两个端口。通讯的波特率为115200。

下面的示例程序显示了发送与接收的过程。

/*
**==============================================================================
** UNORECEIVE.C:             -- by Dr. ZhuoQing, 2021-05-30
**
**==============================================================================
*/

#include <SoftwareSerial.h>

#define ON(pin)                 digitalWrite(pin, HIGH)
#define OFF(pin)                digitalWrite(pin, LOW)
#define VAL(pin)                digitalRead(pin)
#define IN(pin)                 pinMode(pin, INPUT)
#define OUT(pin)                pinMode(pin, OUTPUT)

SoftwareSerial ttsPort(12, 13);
SoftwareSerial wifiPort(2, 3);

//------------------------------------------------------------------------------
void setup(void) {
    char c;
    
    ttsPort.begin(9600);
    wifiPort.begin(115200);
    wifiPort.listen();
    wifiPort.setTimeout(500);
    Serial.begin(115200);

    //----------------------------------------------------------------------

}

//------------------------------------------------------------------------------
int count = 0;
String str;
void loop(void) {

    char c;
    char buf[256];
    
    ttsPort.listen();
    wifiPort.print("http://192.168.4.2:8000/lock/update/?type=LOCK&detail=AAAA\r");
    wifiPort.listen();
    
    while(1) {
        str = wifiPort.readString();
        Serial.print(str);
        
        if(wifiPort.available() == 0) break;        
        
    }

    delay(2000);

}

//==============================================================================
//                END OF FILE : UNORECEIVE.C
//------------------------------------------------------------------------------

 

验总结 ※


未完待续


■ 相关文献链接:

  • Arduino门禁人机接口调试 Version 1.0
  • 从0 开始 DIY你的Arduino UNO
  • Grove Beginner Kits基础实验 Arduino

● 相关图表链接:

  • 图1-1 最小系统原理图
  • 图1-2 ESP8266子系统电路
  • 图1-3 接口电路
  • 图1-4 USB下载电路接口
  • 图2-1 Arduino 管脚定义
这篇关于基于Arduino ATmega328人脸识别IOT演示开关的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!