tag 标签: ardunio

相关博文
  • 热度 3
    2022-5-10 08:32
    2320 次阅读|
    1 个评论
    H桥马达控制器(H-Bridge Motor Controlle)非常简单,用起来也非常有趣,像小时候玩风车一样。但是,马达是工业应用的基础,用起来并不简单。 本项目电路中的 NPN 晶体管可为马达提供更大电流,这样我们就可以使用较小电压来切换马达,使用较大电压驱动马达,让马达获得更高转速和更大力矩。但是,一定要确保马达工作于安全功率和要求电压范围内。 该电路中的开关可由微型控制器取代,可通过PWM技术控制马达的转速。当然,也可以控制马达让其在一个方向旋转。 也可以再增加一个晶体管,这次我们使用 P-N-P 型,并通过一个二极管来保护这两个晶体管,免受来自马达的感性负载影响。 晶体管与二极管组合可消除马达的感性负载影响 为电路正常工作,需下拉引脚2为 LOW,并为引脚3加上一个PWM信号。电路中,两个晶体管通过推、拉电流,为马达提供更大的力矩,实现更高的效率。 这下,我们开始提到的问题出现了,那就是如何让让马达转向。这也不难,把电路复制一下,再增加几个元件就解决了。不过,电路看起来有些复杂。 这个电路中,Q1、Q2为P-N-P晶体管,Q3、Q4为N-P-N晶体管,P-N-P晶体管导通时基极的R1 or R2必须下拉为 LOW,N-P-N晶体管工作时基极的R3 or R4必须上拉为 HIGH。 这里,PNP和NPN晶体管必须为匹配良好的对管,电流和电压大小要根据马达尺寸来选择,这取决于马达是用于小玩具或者个人爱好,而2N2222A NPN晶体管、2N2907A PNP晶体管可提供中等性能。也可以使用NPN型2N3904晶体管和PNP型2N3906晶体管, 但是性能表现不佳,而ZTX1049A NPN型晶体管和ZTX968 PNP型晶体管的表现最佳。 对于像RC类的较大型DC马达,NPN型的TIP120、TIP121和TIP122,PNP型的TIP125、TIP126、TIP127能够承受5A工作电流,以及高达8A的峰值电流。但是一定要使用散热片,这些晶体管的外形也非常大,封装形式TO-220。 通过下拉为LOW(接地),D2、D4可打开或关断一个指定的 PNP 晶体管(Q1 or Q2 )。 D3、D5为PWM或常态数字输出,将其上拉为HIGH(接VCC)可打开晶体管(Q3 or Q4 )。 如果想让马达转向,这也简单。上拉D4为HIGH,下拉D5为LOW,D2也为LOW,为D3施加一个PWM信号,或者将其上拉为HIGH,看看发生了什么? 上拉D2为LOW开关Q1,上拉D5为High,或为其加上一个PWM信号,打开Q4、Q2、Q3并保持关闭。 现在,电路就开始向Q1推、拉电流,经过马达,再经过Q4流向地,使马达按照一定方向转圈,我们称之为正向。 相反,如果D2 HIGH,D4 LOW, D5 LOW,D3 HIGH或者添加一个PWM信号,使电流从Q2流出,再通过马达的流向Q3,这就有效的改变了马达的方向。 不过,有些情况会导致电池短路,例如: D2 LOW,D5 High 或PWM状态 D4 LOW,D3 High 或PWM状态 这两种状态会导致电池电压直接与“地”短路,因此千万别使用这两个组合。 下面是Arduino开发板代码: /* * Example code to use with DIY H-Bridge ( One Motor ) * Another second motor will need another H-Bridge, and control pins * * Maker and IOT Ideas 2020 (MakerIOT2020) */ /* Define control pins */ const int fwd_enable=2; const int fwd_pwm=3; const int rev_enable=4; const int rev_pwm=5; void setup() { // Set pin Modes, while preventing accidental short of supply digitalWrite(fwd_enable,HIGH); digitalWrite(rev_enable,HIGH); // force PNP transistors to stay off; digitalWrite(fwd_pwm,LOW); digitalWrite(rev_pwm,LOW); // force NPN transistors to stay off; // now set the pin mode. pinMode(fwd_enable,OUTPUT); pinMode(rev_enable,OUTPUT); pinMode(fwd_pwm,OUTPUT); pinMode(rev_pwm,OUTPUT); } void stop_all() { /* This will stop everything, * allowing the motor to run free or coast) * */ digitalWrite(fwd_pwm,LOW); digitalWrite(rev_pwm,LOW); digitalWrite(fwd_enable,HIGH); digitalWrite(rev_enable,HIGH); } void motor_fwd() { /* * Makes the motor run “forward” * If you find that it actually reverses your motor, * please swap the physical wiring at the motor once. * It should now work correctly forever … */ digitalWrite(rev_enable,HIGH); digitalWrite(rev_pwm,LOW); // Make sure about the states of the other side of the // H-Bridge, to prevent shorts digitalWrite(fwd_enable,LOW); digitalWrite(fwd_pwm,HIGH); // Motor will now be on and running, at a fixed speed } void motor_fwd_pwm(int motor_speed) { digitalWrite(rev_enable,HIGH); digitalWrite(rev_pwm,LOW); // Make sure about the states of the other side of the // H-Bridge, to prevent shorts digitalWrite(fwd_enable,LOW); analogWrite(fwd_pwm,motor_speed); } void motor_rev() { digitalWrite(fwd_enable,HIGH); digitalWrite(fwd_pwm,LOW); // Make sure about the states of the other side of the // H-Bridge, to prevent shorts digitalWrite(rev_enable,LOW); digitalWrite(rev_pwm,HIGH); // Motor will now be on and running, at a fixed speed } void motor_rev_pwm(int motor_speed) { digitalWrite(fwd_enable,HIGH); digitalWrite(fwd_pwm,LOW); // Make sure about the states of the other side of the // H-Bridge, to prevent shorts digitalWrite(rev_enable,LOW); analogWrite(rev_pwm,motor_speed); } void motor_brake() { /* * This will brake the motor, or make it slow down */ digitalWrite(fwd_enable,HIGH); digitalWrite(rev_enable,HIGH); digitalWrite(fwd_pwm,HIGH); digitalWrite(rev_pwm,HIGH); } void motor_brake_intervals(int brakes = 2) { // this will brake the motor x times, default of 2 // delay used here for ease of explanation, feel free to change // this to millis for (int i = 0; i < brakes; i++) { motor_brake; delayMicroseconds(10); stop_all(); delayMicroseconds(10); } // and allow motor to run free stop_all(); } void loop() { // Sample use // Start with a stopped motor stop_all(); // go forwards motor_fwd(); delay(2000); // brake and stop motor_brake_intervals(5); // reverse direction motor_rev(); delay(2000); // brake and stop motor_brake_intervals(5); // PWM slow to fast for (int i = 155; i < 255; i+=10) { motor_fwd_pwm(i); delay(100); } // brake and stop motor_brake_intervals(5); delay(500); // Reverse fast to slow 155 ; i-=10) { motor_rev_pwm(i); } // brake and stop motor_brake_intervals(5); delay(500); stop_all; }
  • 热度 3
    2022-5-6 09:13
    2131 次阅读|
    0 个评论
    遥控器是LCD智能电视的开机必备,如果家里的电视遥控器坏了,那就只能错过好节目了,这时有个备品那该多好啊。 本项目教大家自己动手DIY一个万能电视遥控器。项目采用IR遥控技术,工作时遥控器将代码发送给电视机,再由电视的MCU解码并处理,来改变电视频道。 项目开始前,我们首先须了解IR遥控的工作原理,知道遥控器发射的代码,并制作自己的遥控解码系统,再写下所有按钮(例如 CH+, CH-, VOL+, VOL-, POWER, Settings)的所有解码值。然后,将这些值发送给Arduino来实现万能遥控,并完成本项目。 项目元器件清单: 1) Arduino 2) IR LED 3) 轻触开关 4) 1k欧姆电阻器 x11 5) 220欧姆电阻器 6) PCB和引线 7) 电池(3.7V) Arduino电视遥控器电路非常简单,如果使用的是Arduino Atmega328p芯片,就需要按照图示电路进行时钟和复位连接,图中的ICSP可编程串行引脚用以上传项目代码,改变控制信号。 电路中,IR发光二极管的正极通过1k/220欧姆电阻器,连接于D3(数字引脚3);负极接地。11个轻触开关用来处理11个不同的指令,它们的一端分别连接于D2-D13的不同数字引脚,另一端则分别通过一个1k欧姆电阻器接地。两引脚插头用来为电路和Arduino供电。 代码如下: #include #include "LowPower.h" IRsend irsend; const int b1 = 2; const int b2 = 4; const int b3 = 5; const int b4 = 6; const int b5 = 7; const int b6 = 8; const int b7 = 9; const int b8 = 10; const int b9 = 11; const int b10 = 12; int timer; int modeCounter = 0; void wakeUp() { timer = 0; } void setup() { pinMode(b1, INPUT); pinMode(b2, INPUT); pinMode(b3, INPUT); pinMode(b4, INPUT); pinMode(b5, INPUT); pinMode(b6, INPUT); pinMode(b7, INPUT); pinMode(b8, INPUT); pinMode(b9, INPUT); pinMode(b10, INPUT); } void loop() { attachInterrupt(0, wakeUp, HIGH); while (timer < 10000) { if (digitalRead(b1) == HIGH) { timer = 0; delay(50); irsend.sendNEC(0x0000, 32); //Enter Remote Hex Value } if (digitalRead(b2) == HIGH) { timer = 0; delay(50); irsend.sendNEC(0x0000, 32); //Enter Remote Hex Value } if (digitalRead(b3) == HIGH) { timer = 0; delay(50); irsend.sendNEC(0x0000, 32); //Enter Remote Hex Value } if (digitalRead(b4) == HIGH) { timer = 0; delay(50); irsend.sendNEC(0x0000, 32); //Enter Remote Hex Value } if (digitalRead(b5) == HIGH) { timer = 0; delay(50); irsend.sendNEC(0x0000, 32); //Enter Remote Hex Value } if (digitalRead(b6) == HIGH) { timer = 0; delay(50); irsend.sendNEC(0x0000, 32); //Enter Remote Hex Value } if (digitalRead(b7) == HIGH) { timer = 0; delay(50); irsend.sendNEC(0x0000, 32); //Enter Remote Hex Value } if (digitalRead(b8) == HIGH) { timer = 0; delay(50); irsend.sendNEC(0x0000, 32); //Enter Remote Hex Value } if (digitalRead(b9) == HIGH) { timer = 0; delay(50); irsend.sendNEC(0x0000, 32); //Enter Remote Hex Value } if (digitalRead(b10) == HIGH) { timer = 0; delay(50); irsend.sendNEC(0x0000, 32); //Enter Remote Hex Value } delay(1); timer = timer + 1; } LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); } 上述代码采用低功耗模式库,以提高电池寿命,一次充电后可使用3-4个月。
  • 热度 9
    2022-4-29 09:31
    2092 次阅读|
    0 个评论
    本项目是一个采用Traffic LED模块、Arduino Uno/Nano,以及TOF10120飞行时间传感器的工业级智能停车系统。项目采用一块切边的垫子作为停车区,先测量垫子长度,再根据这个数值定义不同距离的代码,一个接一个的点亮(ON)和熄灭(OFF)这些LEDs,以帮助司机安全停车: 当汽车即将进入停车区域时,绿色LED点亮。然后,黄色LED点亮,提醒司机即将接近目标停车位置,这表明汽车车身已经有一半位于停车区域。 当红色LED开始闪烁时,警告司机缓慢行驶并留意,到达停车点后关闭汽车,或者继续移动直到红色LED停止闪烁。 作为一个用以理解停车系统的原型,项目使用的均为廉价元件。读者可对电路进行升级,如改变代码中的测量距离数值,甚至替换电路中的传感器等,使项目更加实用。 ToF10120飞行时间传感器 tof10120激光模块最大的优势在于测距远、操作简单,程序中仅仅需要通过单片机给模块串口发送命令字符串,就可以向单片机发送回距离数据。如果发送自动测距的字符串命令,则模块会按照一定频率自动回送数据,相关物理量都可以通过命令字符串设置。传感器仅需要串口就可以实现。 TOF10120基于Sharp低成本标准CMOS工艺和SPAD技术,可为自动对焦(AF)提供精确、可重复的长距离测量,测量结果不受物体反射的影响。主要特点包括: ・采用940nm激光; ・小型陶瓷封装(20×13.2×2.0mm); ・ 可在室内测量长达1.8m长度,精度5%; ・测量距离不受姆堡反射的影响; ・先进广促俄串扰补偿技术; ・30ms高速测量; ・单电源供电; ・Txd接口用于设备控制和数据传送; ・无铅,符合RoHS指令。 TOF10120典型测距范围为100-1800mm,电源电压3-5v,消耗电流35mA,兼容Arduino、ESP8266、ESP32等5V和3.3V控制板,适合-20°C to +70°C等室内外环境。 TOF10120支持UART、I2C通讯,1#引脚、2#引脚、3#引脚、4#引脚、5#引脚、6#引脚分别为GND、VDD、RXD、TXD、SDA、SCL。在六个引脚中,本项目只使用了其中的GND, VDD, SDA, and SCL四个脚。 根据数据表,TOF10120的I2C地址为0xA4,但寻址采用高7bit即0x52,这相当于82。 交通LED模块 该模块为司机提供指示,本身带有限流电阻,无需额外连接电阻器。 模块共有4个公头,GND引脚链接与控制器的GND引脚,或数字引脚。这样,5v信号将熄灭模块,GND or LOW电平信号将启动模块。其中,R标号代表红色LED, Y标号代表黄色LED,G标号代表绿色LED,高电平信号时LED点亮。 连接电路 首先,按照电路图,5V电源由LM7805三端稳压器提供给Arduino Nano,后面需要连接一个470uF的去耦铝电解电容器。 其中,5v稳压连接到Arduino Nano的VIN引脚,TOF10120激光测距模块的SCL、SDA引脚分别连接于Arduino板子的A5、A4引脚,电源线链接于Arduino板子的5V和接地引脚。 信号灯LED模块的GND引脚链接到Arduino板子的5号引脚,红色LED链接到Arduino的4号引脚,黄色LED连接到3号引脚,绿色LED连接到2号引脚。 PCB设计 接下来,设计Arduino Nano PCB开发板,母头用于3.3V、12V、5V和接地,左侧作为Vero板用来焊接其他电子元件,Arduino Nano的左右两侧都设计母头来连接跳线,也可连接传感器和电子元器件,例如TOF10120传感器和OLED显示模块的I2C引脚。 最后,将Traffic LED模块连接于Arduino板子的5、4、3、2引脚,再用公头连来连接TOF10120传感器的GND、Vdd、SCL、SDA引线。 做完上述连接后,就使用下述代码进行I2C寻址: #include void setup() { Wire.begin(); Serial.begin(115200); Serial.println("\nI2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 0; address <= 127; address++ ) { Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address, HEX); Serial.println(" !"); nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(30000); } #include void setup() { Wire.begin(); Serial.begin(115200); Serial.println("\nI2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 0; address <= 127; address++ ) { Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address, HEX); Serial.println(" !"); nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(30000); } 上述代码上传完成后,打开serial monitor就会看到TOF10120激光传感器的I2C地址。按照数据手册,TOF10120模块的I2C地址为0xA4,由于其寻址采用了高7 bits,这样就变成了0x52,相当于82。 至此,大家已经知道了i2c地址,可以把TOF10120测距传感器模块固定到板子上了。该传感器须固定到适当的高度,以检测车辆和距离。这当然不难,你可以竖一个底部带有螺丝的胶块,我为了方便站了一个充电器的外壳,只要高度满足即可。 下面是本项目的代码,我是按照裁剪的垫子大小来写的,这个尺寸正好就是停车区域的大小。 /* Smart Car Parking system Code * In this project the TOF10120 Laser Distance Sensor is used for measuring the distance. */ #include // Traffic LED Module interfacing with Arduino Uno or Arduino Nano int GND_PIN = 5; int RED_PIN = 4; int YELLOW_PIN = 3; int GREEN_PIN = 2; unsigned char ok_flag; unsigned char fail_flag; unsigned short lenth_val = 0; unsigned char i2c_rx_buf ; unsigned char dirsend_flag=0; int x_mm; // distance in millimeters float y_inches; // distance in inches void setup() { Wire.begin(); Serial.begin(9600,SERIAL_8N1); printf_begin(); pinMode(GND_PIN, OUTPUT); pinMode(RED_PIN, OUTPUT); pinMode(YELLOW_PIN, OUTPUT); pinMode(GREEN_PIN, OUTPUT); digitalWrite(GND_PIN, LOW); digitalWrite(RED_PIN, LOW); digitalWrite(YELLOW_PIN, LOW); digitalWrite(GREEN_PIN, LOW); } void loop() { x_mm = ReadDistance(); // Serial.print(x_mm); // Serial.println(" mm"); // You can convert millimeters to inches in one of two ways: divide the number of millimeters by 25.4, or multiply the number of millimeters by 0.0394 y_inches = x_mm * 0.0394; // Serial.print(y_inches); // Serial.println(" inches"); 0) && (y_inches <= 3) ) { digitalWrite(RED_PIN, HIGH); digitalWrite(YELLOW_PIN, LOW); digitalWrite(GREEN_PIN, LOW); } 3) && (y_inches <= 6) ) { digitalWrite(RED_PIN, HIGH); delay(200); digitalWrite(RED_PIN, LOW); delay(200); digitalWrite(YELLOW_PIN, LOW); digitalWrite(GREEN_PIN, LOW); } 6) && (y_inches <= 10) ) { digitalWrite(RED_PIN, LOW); digitalWrite(YELLOW_PIN, HIGH); digitalWrite(GREEN_PIN, LOW); } 10) && (y_inches <= 20) ) { digitalWrite(RED_PIN, LOW); digitalWrite(YELLOW_PIN, LOW); digitalWrite(GREEN_PIN, HIGH); } 20 ) { digitalWrite(RED_PIN, LOW); digitalWrite(YELLOW_PIN, LOW); digitalWrite(GREEN_PIN, LOW); } if ( y_inches < 0 ) { digitalWrite(RED_PIN, LOW); digitalWrite(YELLOW_PIN, LOW); digitalWrite(GREEN_PIN, LOW); } } int serial_putc( char c, struct __file * ) { Serial.write( c ); return c; } void printf_begin(void) { fdevopen( &serial_putc, 0 ); } void SensorRead(unsigned char addr,unsigned char* datbuf,unsigned char cnt) { unsigned short result=0; // step 1: instruct sensor to read echoes Wire.beginTransmission(82); // transmit to device #82 (0x52), you can also find this address using the i2c_scanner code // the address specified in the datasheet is 164 (0xa4) // but i2c adressing uses the high 7 bits so it's 82 Wire.write(byte(addr)); // sets distance data address (addr) Wire.endTransmission(); // stop transmitting // step 2: wait for readings to happen delay(1); // datasheet suggests at least 30uS // step 3: request reading from sensor Wire.requestFrom(82, cnt); // request cnt bytes from slave device #82 (0x52) // step 5: receive reading from sensor if (cnt <= Wire.available()) { // if two bytes were received *datbuf++ = Wire.read (); // receive high byte (overwrites previous reading) *datbuf++ = Wire.read (); // receive low byte as lower 8 bits } } int ReadDistance(){ SensorRead(0x00,i2c_rx_buf,2); lenth_val=i2c_rx_buf ; lenth_val=lenth_val<<8; lenth_val|=i2c_rx_buf ; delay(300); return lenth_val; } /* Smart Car Parking system Code * In this project the TOF10120 Laser Distance Sensor is used for measuring the distance. */ #include // Traffic LED Module interfacing with Arduino Uno or Arduino Nano int GND_PIN = 5; int RED_PIN = 4; int YELLOW_PIN = 3; int GREEN_PIN = 2; unsigned char ok_flag; unsigned char fail_flag; unsigned short lenth_val = 0; unsigned char i2c_rx_buf ; unsigned char dirsend_flag=0; int x_mm; // distance in millimeters float y_inches; // distance in inches void setup() { Wire.begin(); Serial.begin(9600,SERIAL_8N1); printf_begin(); pinMode(GND_PIN, OUTPUT); pinMode(RED_PIN, OUTPUT); pinMode(YELLOW_PIN, OUTPUT); pinMode(GREEN_PIN, OUTPUT); digitalWrite(GND_PIN, LOW); digitalWrite(RED_PIN, LOW); digitalWrite(YELLOW_PIN, LOW); digitalWrite(GREEN_PIN, LOW); } void loop() { x_mm = ReadDistance(); // Serial.print(x_mm); // Serial.println(" mm"); // You can convert millimeters to inches in one of two ways: divide the number of millimeters by 25.4, or multiply the number of millimeters by 0.0394 y_inches = x_mm * 0.0394; // Serial.print(y_inches); // Serial.println(" inches"); 0) && (y_inches <= 3) ) { digitalWrite(RED_PIN, HIGH); digitalWrite(YELLOW_PIN, LOW); digitalWrite(GREEN_PIN, LOW); } 3) && (y_inches <= 6) ) { digitalWrite(RED_PIN, HIGH); delay(200); digitalWrite(RED_PIN, LOW); delay(200); digitalWrite(YELLOW_PIN, LOW); digitalWrite(GREEN_PIN, LOW); } 6) && (y_inches <= 10) ) { digitalWrite(RED_PIN, LOW); digitalWrite(YELLOW_PIN, HIGH); digitalWrite(GREEN_PIN, LOW); } 10) && (y_inches <= 20) ) { digitalWrite(RED_PIN, LOW); digitalWrite(YELLOW_PIN, LOW); digitalWrite(GREEN_PIN, HIGH); } 20 ) { digitalWrite(RED_PIN, LOW); digitalWrite(YELLOW_PIN, LOW); digitalWrite(GREEN_PIN, LOW); } if ( y_inches < 0 ) { digitalWrite(RED_PIN, LOW); digitalWrite(YELLOW_PIN, LOW); digitalWrite(GREEN_PIN, LOW); } } int serial_putc( char c, struct __file * ) { Serial.write( c ); return c; } void printf_begin(void) { fdevopen( &serial_putc, 0 ); } void SensorRead(unsigned char addr,unsigned char* datbuf,unsigned char cnt) { unsigned short result=0; // step 1: instruct sensor to read echoes Wire.beginTransmission(82); // transmit to device #82 (0x52), you can also find this address using the i2c_scanner code, which is available on electroniclinic.com // the address specified in the datasheet is 164 (0xa4) // but i2c adressing uses the high 7 bits so it's 82 Wire.write(byte(addr)); // sets distance data address (addr) Wire.endTransmission(); // stop transmitting // step 2: wait for readings to happen delay(1); // datasheet suggests at least 30uS // step 3: request reading from sensor Wire.requestFrom(82, cnt); // request cnt bytes from slave device #82 (0x52) // step 5: receive reading from sensor if (cnt <= Wire.available()) { // if two bytes were received *datbuf++ = Wire.read (); // receive high byte (overwrites previous reading) *datbuf++ = Wire.read (); // receive low byte as lower 8 bits } } int ReadDistance(){ SensorRead(0x00,i2c_rx_buf,2); lenth_val=i2c_rx_buf ; lenth_val=lenth_val<<8; lenth_val|=i2c_rx_buf ; delay(300); return lenth_val; } 上面是编程代码,前提是已经下载了 Wire.h 库文件,代码中的距离单位为英寸,欢迎实践和分享。
  • 热度 4
    2022-4-21 13:14
    2410 次阅读|
    0 个评论
    本项目是一个高灵敏的测光系统,以BH1750环境光传感器为数据源,用Arduino作为控制板,用OLED/LCD屏幕显示结果,可用于手机、汽车头灯、电脑显示器、手电筒、摄影灯光等测光。 项目的关键——BH1750环境光传感器内置16位的模数转换器,能够直接输出数字信号,不需要再做复杂的计算。BH1750技术规格: • 供电电压:+3-5V • 接口:I2C • 量程和精度:1~65535 lx • 可以选择I2C地址的两种形式 • 微小的测量变化(+/-20%) • 尺寸:0.85x0.63x0.13"(21x16x3.3mm) 光强度的单位是流明"lx",光亮度数据参考如下: • 晚上: 0.001-0.02 • 月夜: 0.02-0.3 • 多云室内: 5-50 • 多云室外: 50-500 • 晴天室内: 100-1000 • 夏天中午光照下: 大约10*6能量 • 阅读书籍时的照明度:50-60 • 家庭录像标准照明度:1400 现在,就让我们开始连接 BH1750和 Arduino,接口如下: BH1750 SDA引脚 ---- Arduino 模拟引脚 A4。 BH1750 SCL引脚 ---- Arduino 模拟引脚 A5。 BH1750 VCC引脚 ---- 5V 引脚。 BH1750 接地 ---- Arduino 接地(GND)引脚。 BH1750 ADDR引脚 ---- Arduino接地(GND)引脚。 接下来进行编程。 首先,点选“项目”菜单下的“上传库”,再选择“管理库”:sketch Menu ---- include library ---- manage library 在搜索框中输入“BH1750”,将出现多个选项,按图示点选“install”按钮。 安装完成后,上传BH1750环境光传感器的Arduino代码: #include #include BH1750 lightMeter; void setup(){ Wire.begin(); Serial.begin(9600); lightMeter.begin(); Serial.println("Sensing started!..."); delay(500); } 连接传感器与OLED显示器 如果需要OLED来显示传感器数据,那就把它们连接起来吧。这很简单,总共只需四根线: 将OLED显示器和BH1750传感器的 SDA 引脚,一同连接到Arduino板的模拟引脚 A4。 将OLED显示器和BH1750传感器的 SCL 引脚,一同连接到Arduino板的模拟引脚 A5。 将OLED显示器和BH1750传感器的 VCC 引脚,一同连接到Arduino板的 5V引脚。 将OLED显示器和BH1750传感器的 GND 引脚,一同连接到Arduino板的 GND引脚。 接着,我们把OLED显示器和BH1750传感器代码上传到Arduino: #include "U8glib.h" #include U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); int BH17_add = 0x23; byte buff ; void setup() { Wire.begin(); BH750_Init(BH17_add); delay(200); } void light(){ float valf=0; u8g.setFont(u8g_font_unifont); u8g.setPrintPos(0, 50); if (BH1750_Read(BH17_add)==2){ valf=((buff <<8)|buff )/1.2; if (valf 65535"); else u8g.setPrintPos(0, 20); u8g.print("BH11750 sensor with the OLED"); u8g.setPrintPos(0, 30); u8g.print("--------------"); u8g.setPrintPos(0, 40); u8g.print("Flux Meter"); u8g.setPrintPos(0, 60); u8g.print((int)valf,DEC); u8g.print(" LX/SI"); } delay(100); } void loop() { u8g.firstPage(); do { light(); }while (u8g.nextPage()); } void BH750_Init(int address){ Wire.beginTransmission(address); Wire.write(0x10); Wire.endTransmission(); } byte BH1750_Read(int address){ byte i=0; Wire.beginTransmission(address); Wire.requestFrom(address, 2); while(Wire.available()){ buff = Wire.read (); i++; } Wire.endTransmission(); return i; } 上传完成后,我们就在OLED显示器上看到了BH1750传感器的数据。将手指放在传感器上面,我们可以改变传感器检测到的光照强度。 连接BH1750传感器与5110 LCD显示器 上面我们熟悉了几个硬件的连接效果。接下来,我们把传感器、Nokia 5110 LCD显示器、Arduino UNO三者连接,这才是一个像样的照度计。 具体连接方式如下: BH1750 VCC ---- Arduino 5V。 BH1750 GND ---- Arduino GND。 BH1750 SCL ---- Arduino 模拟引脚A5。 BH1750 SDA ---- Arduino 模拟引脚A4。 Nokia 5110 VCC引脚 ---- Arduino 3.3v引脚。 Nokia 5110 GND接地 ---- Arduino GND接地引脚。 Nokia 5110 led out接地 ---- Arduino GND接地引脚,这时LCD又背光。如果不需要背光,就将Nokia 5110 led out接地引脚连接到Arduino板子的5V引脚。 Nokia 5110 SCE引脚 ---- Arduino 数字引脚 11。 Nokia 5110 RS引脚 ---- Arduino 数字引脚 12。 Nokia 5110 D/C引脚 ---- Arduino 数字引脚 10。 Nokia 5110 DN引脚 ---- dArduino 数字引脚 9。 Nokia 5110 SCLK引脚 ---- Arduino 数字引脚 8。 连接无误后,我们开始上传代码。 #include #include #include LCD5110 lcd(8,9,10,12,11); extern unsigned char BigNumbers ; extern uint8_t ui[]; BH1750 lightSensor; String light; void setup() { lightSensor.begin(); lcd.InitLCD(); lcd.setFont(BigNumbers); lcd.clrScr(); lcd.drawBitmap(0, 0, splash, 84, 48); lcd.update(); delay(3000); } void loop() { int stringLength=0; uint16_t lux = lightSensor.readLightLevel(); light = String(lux); stringLength = light.length(); lcd.clrScr(); lcd.drawBitmap(0, 0, ui, 84, 48); printLight(stringLength); lcd.update(); delay(150); } void printLight(int length) { switch(length) { case 1: lcd.print(light,68,22); break; case 2: lcd.print(light,54,22); break; case 3: lcd.print(light,40,22); break; case 4: lcd.print(light,26,22); break; case 5: lcd.print(light,12,22); break; default: lcd.print(light,0,22); break; } } 将代码上传到Arduino UNO后,我们就在Nokia 5110 LCD看到了传感器的测量结果。
  • 热度 11
    2022-4-19 10:11
    2140 次阅读|
    0 个评论
    本项目采用Arduino开发板、火焰传感器(Flame Sensor)、蜂鸣器,构建了一个简单的火感检测器系统。一旦探测到火焰出现,蜂鸣器就发出警报,可用作火警车、IoT火灾警报器、智能联网火灾报警器的原型。 IR火焰传感器 IR火焰传感器主要由双电压比较器IC、IR传感器和一个电位器组成,4个引脚功能如下: A0:模拟输出引脚 G:接地引脚,使用时与Arduino开发板的的GND连接。 +:电源输入引脚,连接于Arduino开发板的3.3v or 5v引脚。 D0:数字输出信号引脚,连接Arduino开发板的任意 i/o引脚。或者,直接连接到支持TTL的电路,用来直接控制等名气和继电器等。 该火焰传感器对760-1100nm范围的IR光线非常敏感,对3英尺内的火焰高度灵敏,适合短距离火焰检测,或者作为检测项目和安全预防设备的控制器,以切断设备的 OFF / ON ,或者开启蜂鸣器,或者发送SMS信号。主要特点如下: 检测角度:大约60度。 电源:0-15VDC 内孔直径:大约3mm 外形尺寸:大约36 x 16mm 火焰传感器模块带有一个电位器,可调节火焰检测的灵敏度。两个LED灯中的一个在接通传感器后点亮,另一个仅在检测到火焰后才点亮。 继电器版火情警报方案 本方案是一个最简单、最廉价的火焰检测系统,通过传感器直接控制继电器的动作。 当传感器检测达火焰出现时,打开继电器,并控制各类AC/DC蜂鸣器。也可以使用5V蜂鸣器,只是这样的电压级实在是太低了,最好是采用一个12V的蜂鸣器。 在检测到火焰后,蜂鸣器一直保持“ON”。在火情消失后,继电器会立即蜂鸣器。 如果需要执行多重任务,例如启动蜂鸣器并发送文本信息,或者激励伺服马达等,这个房就显得力不从心了,这需要采用Arduino控制板了。 Arduino版火情警报方案 Arduino控制板有Arduino UNO、Arduino Nano、Arduino Mega等,本项目采用Arduino Uno。用12V DC电源为Arduino和一个12V的单孔双执(SPDT)继电器供电。 实验时,将IR火焰传感器的“Do”引脚连接于Arduino Nano开发板的“2”引脚,传感器模块的VCC、GND引脚分别连接于Arduino Nano的5V、GND引脚,单通道继电器模块连接于Arduino Nano的8#引脚。 当传感器检测到火焰信号时,就发信号给Arduino Nano,由Arduino控制任何连接于继电器的电气负载。这需要对Arduino Nano进行编程,才能在检测到火焰时开启蜂鸣器,火情消失后关闭,如此反复…… #define F_Sensor 2 // connect DO pin of the flame sensor with the Arduino's digital pin 2 #define Relay_Buzzer 8 // A relay module is connected with the Arduino's pin number 8 void setup() { Serial.begin(9600); // Baud Rate Serial.println("Flame Sensor Project by Electronic Clinic"); pinMode(F_Sensor, INPUT);//define F_Sensor input pin pinMode(Relay_Buzzer, OUTPUT);//define Relay_Buzzer output pin } void loop() { int fire = digitalRead(F_Sensor);// read F_Sensor sensor if( fire == HIGH) { digitalWrite(Relay_Buzzer,HIGH);// set the buzzer ON Serial.println("Fire Detected"); } else { digitalWrite(Relay_Buzzer,LOW); // Set the buzzer OFF Serial.println("Peace"); } delay(1000); } 项目代码没有库,非常简单实用,朋友们可在此基础上修改以控制各种各样的继电器、蜂鸣器或者灯泡。
相关资源