本文將測試近期製作的遙控器及接收器之間無線數據傳輸。
實現功能:
遙控器端按下按鍵,LCD顯示相應的鍵名,同時發送鍵值到接收器;
接收器在接到鍵值後,相應在其LCD上顯示鍵名。
遙控器和接收器合影:
發射器及按鍵說明
接收器:
發射器代碼如下:
//LCD控制的頭文件
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//無線需要的頭文件
#include <SPI.h>
#include <RF24.h>
#include <RF24_config.h>
#include <nRF24L01.h>
//旋轉編碼器接線
#define clk A2
#define data A3
#define sw 8
#define A 2
#define B 3
#define C 4
#define D 5
#define E 6
#define F 7
#define X A0
#define Y A1
//無線接口定義如下:
/*nRF24L01 Arduino UNO
VCC <-> 3.3V
GND <-> GND
CE <-> D9
CSN <-> D10
MOSI<-> D11
MISO<-> D12
SCK <-> D13
IRQ <-> 不接
*/
//按鍵定義如下
/*
• Button A – Connects to D2
• Button B – Connects to D3
• Button C – Connects to D4
• Button D – Connects to D5
• Button E – Connects to D6
• Button F – Connects to D7
*/
//LCD接口定義如下
/*
• GND – Connects to GND
• VCC – Connects to 5V
• SDA – Connects to A4
• SCL – Connects to A5
*/
//Joystick接口定義如下
/*
• X axis – Connects to A0
• Y axis – Connects to A1
• SW2 – Connects to D8
*/
volatile boolean TurnDetected;//編碼器檢測標識
volatile boolean up;//編碼器檢測
int State;
int counter;
int LastState;
LiquidCrystal_I2C lcd(0x27, 16, 2);
RF24 radio(9, 10); // CE, CSN
const byte address[6] = "00001";//無線發射器配碼,需要接收及發射使用相同的六位字符
void setup() {
int x,y;
int z=1;
//LCD 初始化
lcd.init();
lcd.backlight();
lcd.begin(16, 2);
//串口初始化,用於測試,成功後去除
Serial.begin(9600);
//旋轉編碼器接口定義
pinMode(clk, INPUT);
pinMode(data, INPUT);
pinMode(sw, INPUT);
pinMode(A, INPUT);
pinMode(B, INPUT);
pinMode(C, INPUT);
pinMode(D, INPUT);
pinMode(E, INPUT);
pinMode(F, INPUT);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
//變量定義
LastState=digitalRead(clk);//旋轉編碼器變化檢測標識
//初始界面顯示內容
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" WELCOME! ");
delay(1000);
lcd.setCursor(0,0);
lcd.print("Wireless Control");
lcd.setCursor(0,1);
lcd.print(" Design By Wen ");
delay(2000);
//復位後,顯示準備就緒內容
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" READY! ");
delay(1000);
lcd.clear();
//無線發射器初始化
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
//旋轉編碼器檢測函數
int Rotary_encoder()
{
State = digitalRead(clk); // 讀取CLK的狀態
// 如果現在的狀態和之前的不一樣,說明旋鈕轉了一格
if (State != LastState){
TurnDetected = true;
//delay (100);
if (digitalRead(data) != State) { //如果data的狀態和clock的狀態不一樣,說明編碼器順時針旋轉
counter ++;
return 1;
//delay (100);
} else { //如果data的狀態和clock的狀態一樣,說明編碼器逆時針旋轉
counter --;
return 0;
//delay (100);
}
//以下代碼用於測試編碼器是否正常工作,最終需要刪掉,避免佔用資源和增加功耗
Serial.print("Position: ");
Serial.println(counter);
}
LastState = State; //更新編碼器標識狀態
}
void loop() {
int x=49;
int y=49;
int z=1;
//const char tex[] = "Hello World";
// radio.write(&tex, sizeof(tex));
Serial.println("finsh sending 'Hello World'");
up=Rotary_encoder();//檢測旋轉編碼器的變化
if (TurnDetected) { // 編碼器有旋轉
// Rotary_encoder();
if (TurnDetected) {
lcd.clear();
// up=Rotary_encoder();
if (up) {//順時針操作
//arrow = !arrow;
Serial.println("clockwise");//串口輸出按鍵操作
const char text[] = "clockwise";
radio.write(&text, sizeof(text));//無線發射出去按鍵操作
Serial.println("finsh sending 'clockwise'");//串口輸出完成無線發送
lcd.setCursor(1, 0);//LCD顯示
lcd.print("clockwise");
lcd.setCursor(1, 1);
lcd.print("FINISH SENDING");
//delay(100);
}
else {//逆時針操作
//arrow = !arrow;
Serial.println("anticlockwise");//串口輸出按鍵操作
const char text[] = "anticlockwise";
radio.write(&text, sizeof(text));//無線發射出去按鍵操作
Serial.println("finsh sending 'anticlockwise'");//串口輸出完成無線發送
lcd.setCursor(1, 0);//LCD顯示
lcd.print("anticlockwise");
lcd.setCursor(1, 1);
lcd.print("FINISH SENDING");
//delay(100);
}
TurnDetected = false;
}
}
if (!(digitalRead(sw))) {
delay(100);
while (!(digitalRead(sw))) {//編碼器按鍵按下
lcd.clear();
Serial.println("SW PRESSED");//串口輸出按鍵操作
const char text[] = "SW PRESSED";
radio.write(&text, sizeof(text));//無線發射出去按鍵操作
Serial.println("finsh sending 'SW PRESSED'");//串口輸出完成無線發送
lcd.setCursor(1, 0);//LCD顯示
lcd.print("SW PRESSED");
lcd.setCursor(1, 1);
lcd.print("FINISH SENDING");
z=1;
// delay(100);
}
}
/* if (!((analogRead(X)==49)&&(analogRead(Y)==49)) ){
//搖桿變化
delay(100);
while (!((analogRead(X)==49)&&(analogRead(Y)==49)) ){
x=analogRead(X);
y=analogRead(Y);
z=digitalRead(sw);
x=map(x,0,679,0,99);
y=map(y,0,679,0,99);
Serial.println("Joystick changed");//串口輸出按鍵操作
Serial.print("X:");
Serial.print(x);
Serial.print(":Y:");
Serial.print(y);
Serial.print(":B:");
Serial.print(z);
lcd.clear();
const char text[] = "X";
radio.write(&text, sizeof(text));//無線發射出去按鍵操作
Serial.println("finsh sending 'X'");//串口輸出完成無線發送
radio.write(x, sizeof(x));//無線發射出去按鍵操作
Serial.println("finsh sending value of x");//串口輸出完成無線發送
const char text1[] = "Y";
radio.write(&text1, sizeof(text1));//無線發射出去按鍵操作
Serial.println("finsh sending 'Y'");//串口輸出完成無線發送
radio.write(y, sizeof(y));//無線發射出去按鍵操作
Serial.println("finsh sending value of y");//串口輸出完成無線發送
const char text2[] = "Z";
radio.write(&text2, sizeof(text2));//無線發射出去按鍵操作
Serial.println("finsh sending 'B'");//串口輸出完成無線發送
radio.write(z, sizeof(z));//無線發射出去按鍵操作
Serial.println("finsh sending value of z");//串口輸出完成無線發送
lcd.setCursor(1, 0);//LCD顯示
lcd.print("X:");
lcd.setCursor(3, 0);
lcd.print(x);
lcd.setCursor(6, 0);
lcd.print(":Y:");
lcd.setCursor(9, 0);
lcd.print(y);
lcd.setCursor(12, 0);
lcd.print(":B:");
lcd.setCursor(15, 0);
lcd.print(z);
lcd.setCursor(1, 1);
lcd.print("FINISH SENDING");
delay(100);
}
}
*/
if (!(digitalRead(A))) {//編碼器按鍵按下
delay(100);
while (!(digitalRead(A))) {
lcd.clear();
Serial.println("A PRESSED");//串口輸出按鍵操作
const char text[] = "A PRESSED";
radio.write(&text, sizeof(text));//無線發射出去按鍵操作
Serial.println("finsh sending 'A PRESSED'");//串口輸出完成無線發送
lcd.setCursor(1, 0);//LCD顯示
lcd.print("A PRESSED");
lcd.setCursor(1, 1);
lcd.print("FINISH SENDING");
//delay(100);
}
}
if (!(digitalRead(B))) {//編碼器按鍵按下
delay(100);
while (!(digitalRead(B))) {
lcd.clear();
Serial.println("B PRESSED");//串口輸出按鍵操作
const char text[] = "B PRESSED";
radio.write(&text, sizeof(text));//無線發射出去按鍵操作
Serial.println("finsh sending 'B PRESSED'");//串口輸出完成無線發送
lcd.setCursor(1, 0);//LCD顯示
lcd.print("B PRESSED");
lcd.setCursor(1, 1);
lcd.print("FINISH SENDING");
//delay(100);
}
}
if (!(digitalRead(C))) {//編碼器按鍵按下
delay(100);
while (!(digitalRead(C))) {
lcd.clear();
Serial.println("C PRESSED");//串口輸出按鍵操作
const char text[] = "C PRESSED";
radio.write(&text, sizeof(text));//無線發射出去按鍵操作
Serial.println("finsh sending 'C PRESSED'");//串口輸出完成無線發送
lcd.setCursor(1, 0);//LCD顯示
lcd.print("C PRESSED");
lcd.setCursor(1, 1);
lcd.print("FINISH SENDING");
//delay(100);
}
}
if (!(digitalRead(D))) {//編碼器按鍵按下
delay(100);
while (!(digitalRead(D))) {
lcd.clear();
Serial.println("D PRESSED");//串口輸出按鍵操作
const char text[] = "D PRESSED";
radio.write(&text, sizeof(text));//無線發射出去按鍵操作
Serial.println("finsh sending 'D PRESSED'");//串口輸出完成無線發送
lcd.setCursor(1, 0);//LCD顯示
lcd.print("D PRESSED");
lcd.setCursor(1, 1);
lcd.print("FINISH SENDING");
//delay(100);
}
}
if (!(digitalRead(E))) {//編碼器按鍵按下
delay(100);
while (!(digitalRead(E))) {
lcd.clear();
Serial.println("E PRESSED");//串口輸出按鍵操作
const char text[] = "E PRESSED";
radio.write(&text, sizeof(text));//無線發射出去按鍵操作
Serial.println("finsh sending 'E PRESSED'");//串口輸出完成無線發送
lcd.setCursor(1, 0);//LCD顯示
lcd.print("E PRESSED");
lcd.setCursor(1, 1);
lcd.print("FINISH SENDING");
//delay(100);
}
}
if (!(digitalRead(F))) {//編碼器按鍵按下
delay(100);
while (!(digitalRead(F))) {
lcd.clear();
Serial.println("F PRESSED");//串口輸出按鍵操作
const char text[] = "F PRESSED";
radio.write(&text, sizeof(text));//無線發射出去按鍵操作
Serial.println("finsh sending 'F PRESSED'");//串口輸出完成無線發送
lcd.setCursor(1, 0);//LCD顯示
lcd.print("F PRESSED");
lcd.setCursor(1, 1);
lcd.print("FINISH SENDING");
//delay(100);
}
}
}
接收器代碼如下:
#include <Keyboard.h>
//LCD控制的頭文件
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//無線需要的頭文件
#include <SPI.h>
#include <RF24.h>
#include <RF24_config.h>
#include <nRF24L01.h>
#include <string.h>
//旋轉編碼器接線
//無線接口定義如下:
/*nRF24L01 Arduino UNO
VCC <-> 3.3V
GND <-> GND
CE <-> D9
CSN <-> D10
MOSI<-> D11
MISO<-> D12
SCK <-> D13
IRQ <-> 不接
*/
//LCD接口定義如下
/*
• GND – Connects to GND
• VCC – Connects to 5V
• SDA – Connects to A4
• SCL – Connects to A5
*/
LiquidCrystal_I2C lcd(0x27, 16, 2);
RF24 radio(9, 10); // CE, CSN
const byte address[6] = "00001";//無線發射器配碼,需要接收及發射使用相同的六位字符
void setup() {
int x,y;
int z=1;
//無線發射器初始化
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
//LCD 初始化
lcd.init();
lcd.backlight();
lcd.begin(16, 2);
//串口初始化,用於測試,成功後去除
Serial.begin(9600);
char oldtext[]="";
//變量定義
//初始界面顯示內容
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" WELCOME! ");
delay(1000);
lcd.setCursor(0,0);
lcd.print("Wireless Control");
lcd.setCursor(0,1);
lcd.print(" Design By Wen ");
delay(2000);
//復位後,顯示準備就緒內容
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" READY! ");
delay(1000);
lcd.clear();
}
void loop() {
if (radio.available()) {
char text[32] = "";
char oldtext[32]="old";
radio.read(&text, sizeof(text));
lcd.clear();
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
// lcd.setCursor(0, 1);
// lcd.print(text);
//delay(500);
//lcd.clear();
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
//lcd.setCursor(4, 1);
//lcd.print("RCEIVED");
// Serial.println(text);
//Serial.println("Received");
//delay(500);*/
if(strcmp(text,"clockwise")==0&&strcmp(text,oldtext)!=0){
lcd.clear();
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(0, 1);
lcd.print(" clockwise");
//delay(1000);
// Serial.print("Received:");
//Serial.println(text);
//delay(100);
strcpy(oldtext,text);
}
if(strcmp(text,"anticlockwise")==0&&strcmp(text,oldtext)!=0){
lcd.clear();
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(0, 1);
lcd.print("anticlockwise");
//delay(1000);
// Serial.print("Received:");
// Serial.println(text);
//delay(100);
strcpy(oldtext,text);
}
if(strcmp(text,"SW PRESSED")==0&&strcmp(text,oldtext)!=0){
lcd.clear();
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(0, 1);
lcd.print(" SW PRESSED");
//delay(1000);
//Serial.print("Received:");
//Serial.println(text);
//delay(100);
strcpy(oldtext,text);
}
if(strcmp(text,"A PRESSED")==0&&strcmp(text,oldtext)!=0){
lcd.clear();
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(0, 1);
lcd.print(" A PRESSED");
//delay(1000);
// Serial.print("Received:");
//Serial.println(text);
//delay(100);
strcpy(oldtext,text);
}
if(strcmp(text,"B PRESSED")==0&&strcmp(text,oldtext)!=0){
lcd.clear();
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(0, 1);
lcd.print(" B PRESSED");
//delay(1000);
//Serial.print("Received:");
//Serial.println(text);
//delay(100);
strcpy(oldtext,text);
}
if(strcmp(text,"C PRESSED")==0&&strcmp(text,oldtext)!=0){
lcd.clear();
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(0, 1);
lcd.print(" C PRESSED");
//delay(1000);
//Serial.print("Received:");
//Serial.println(text);
//delay(100);
strcpy(oldtext,text);
}
if(strcmp(text,"D PRESSED")==0&&strcmp(text,oldtext)!=0){
lcd.clear();
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(0, 1);
lcd.print(" D PRESSED");
//delay(1000);
//Serial.print("Received:");
//Serial.println(text);
//delay(100);
strcpy(oldtext,text);
}
if(strcmp(text,"E PRESSED")==0&&strcmp(text,oldtext)!=0){
lcd.clear();
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(0, 1);
lcd.print(" E PRESSED");
//delay(1000);
//Serial.print("Received:");
//Serial.println(text);
//delay(100);
strcpy(oldtext,text);
}
if(strcmp(text,"F PRESSED")==0&&strcmp(text,oldtext)!=0){
lcd.clear();
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(0, 1);
lcd.print(" F PRESSED");
//delay(1000);
//Serial.print("Received:");
//Serial.println(text);
//delay(100);
strcpy(oldtext,text);
}
if(strcmp(text,"X")==0&&strcmp(text,oldtext)!=0){
if (radio.available()) {
char value[32] = "";
radio.read(&value, sizeof(value));
lcd.clear();
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(0, 1);
lcd.print("X:");
lcd.setCursor(2, 1);
lcd.print(value);
//delay(500)
strcpy(oldtext,text);
}
}
if(strcmp(text,"Y")==0&&strcmp(text,oldtext)!=0){
if (radio.available()) {
char value[32] = "";
radio.read(&value, sizeof(value));
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(5, 1);
lcd.print(":Y:");
lcd.setCursor(8, 1);
lcd.print(value);
//delay(500)
strcpy(oldtext,text);
}
}
if(strcmp(text,"Z")==0&&strcmp(text,oldtext)!=0){
if (radio.available()) {
char value[32] = "";
radio.read(&value, sizeof(value));
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(11, 1);
lcd.print(":B:");
lcd.setCursor(14, 1);
lcd.print(value);
//delay(1000);
strcpy(oldtext,text);
}
}
}
/*else{
char text[32] = " GET NOTHING";
char oldtext[32]="";
lcd.setCursor(0, 0);//LCD顯示
lcd.print(" LISTENING");
lcd.setCursor(0, 1);
lcd.print(text);
} */
}
目前可以實現按鍵的傳輸,但是仍然有兩個問題需要解決:
1 旋轉編碼器旋轉識別總是出錯;
2 Joystick搖桿值的顯示和傳輸存在問題;
在完成最終的作品前這兩個問題必須解決。