我目前正在通过使用Grove光传感器来检索传感器值(光强度)来控制Grove LED插座套件亮度来进行智能照明,但我没有使用GPIO。 我遵循了所见维基http://wiki.seeedstudio.com/Grove-Light_Sensor/的代码,并修改了一些代码,但是当周围的光照强度很高时,我仍然无法将LED的亮度更改为暗淡,我只是继续使LED变亮。我正在尝试在周围光线强度较低时使LED的亮度变亮。这是我的代码。
import time
from grovepi import *
import datetime
from guizero import App, Text, PushButton, Box
# Connect the Grove Light Sensor to analog port A0
light_sensor = 0
# Connect the LED to digital port D3
led = 3
# Connect the Grove PIR Motion Sensor to digital port D8
pir_sensor = 8
# Turn on LED once sensor exceeds threshold resistance (light sensor gets covered will turn on the LED)
threshold = 20
pinMode(pir_sensor,"INPUT")
pinMode(light_sensor,"INPUT")
pinMode(led,"OUTPUT")
# Title and format
app = App(title="Smart Light")
Titletext = Text(app, text="Smart Light Controller", size=40,
font="Times New Roman", color="lightblue")
# define actions
def action1():
Statustext.value = "Light Turn On"
digitalWrite(led,1)
print ("Light ON!")
def action2():
Statustext.value = "Light Turn Off"
digitalWrite(led,0)
print ("Light OFF!")
def action3():
while True:
Statustext.value = "Light Auto"
# Get sensor value = light intensity
sensor_value = analogRead(light_sensor)
g = str(sensor_value)
a = analogRead(light_sensor)
max_pwn = 100
max_analog_read = 1023
pwn_desired = (float)(a * max_pwn) / max_analog_read
# Calculate resistance of sensor in K
resistance = (float)(1023 - sensor_value) * 10 / sensor_value
# Sense motion, usually human, within the target range
if digitalRead(pir_sensor) and resistance > threshold:
print ('Motion Detected')
print ('Light On')
# Send HIGH to switch on LED
digitalWrite(led,1)
analogWrite(led, pwn_desired)
time.sleep(3)
else :
# Send LOW to switch off LED
# NO motion but intensity low = off
# Motion detected but intensity high = off
digitalWrite(led,0)
print ('No Motion')
print ('Light Off')
print("sensor_value = %d resistance = %.2f" %(sensor_value, resistance))
time.sleep(2)
def line():
Text(app, "----------------------------------")
# Buttons' format
buttons_box = Box(app, layout="grid")
Onbutton = PushButton(buttons_box, action1, text="On",
width=20, height=10,grid=[0,0] )
Offbutton = PushButton(buttons_box, action2, text="Off",
width=20, height=10,grid=[1,0])
Autobutton = PushButton(buttons_box, action3, text="Auto",
width=20, height=10,grid=[2,0])
# Status title
Status = Text(app, text="Light Status", size = 30)
line()
# The status text will change when the each light button is clicked
Statustext = Text(app, text="Idle", color="red", size = 20)
line()
#all code must before app.display
app.display()
答案 0 :(得分:0)
脉冲宽度调制... PWM。
换句话说,在GPIO(LED)上施加占空比。
更亮的灯?使用更高的占空比。例如,当传感器值指示需要从LED发出更多的光时?
调光?使用较低的占空比。例如,当传感器值指示需要减少来自LED的光量时?
将ADC {模拟到数字转换} analogRead
输入到计算中以找到占空比。
您的方程式需要反映出最小analogRead
是最小占空比,最大analogRead
是最大占空比。
假设您的最大analogRead
是1023。
伪代码:
a = analogRead
max_pwm = 100
max_analog_read = 1023
pwm_desired = (a * max_pwm) / max_analog_read
如果用例是较低的模拟传感器读数需要较高的pwm,则计算补数:
// ...
pwm_desired = (a * max_pwm) / max_analog_read
inverted_pwm_desired = max_pwm - pwm_desired
无论哪种情况,我都相信在计算完之后,您可以将GPIO配置为输出PWM引脚。根据您的问题,这似乎是所需要的。
根据评论进行编辑:
它可以通过多种方式实现。让我们选择一个简单的。
另一种看待方法是:
想象方波。高或低。高电平持续时间是一个有效的高占空比。一个完整的周期是从上升沿到下一个上升沿。在一部分时间里,它是“高”,而在一部分时间里,它是“低”。我们需要模仿这个。
在循环中,您需要模拟一段时间内与传感器值成比例的高“值”。
当“值”为高时,您打开LED;当其为低时,您将其关闭。
过渡需要快速(上升沿的出现-周期的开始是快速的)..大约几毫秒的时间-这取决于您的硬件以及LED中有多少光扩散包等。“取决于”。
反正
通过将LED脉冲点亮一段经过计算的时间长度来模仿LED亮度。至少从这个角度来看,LED是数字组件。一旦偏置超过“二极管压降”,它将处于饱和状态。如果LED的偏置电压超过0.6V的下降电压,则它将点亮。这就是您的低电平LED驱动器代码的基本作用-串联一点电阻(大约10k Ohms左右)来使GIO(3.3V左右)有效,这样通过GIO的电流就不会太大。如果电压偏置发生变化,LED将不会改变亮度。它不是白炽灯泡,也不是模拟灯泡。
实验。
假设我们不知道您的循环迭代的频率。我们可以选择接近的指标和转化。在尝试了一组指标和转换因子后,您可以对其进行更改以实现正确的PWM效果。
让我们开始吧:
捕获模拟传感器的读数。如前所述,将其标准化为一个百分比(0到100%)。这个值是我们的占空比。
然后,打开LED。 然后等待,旋转循环等待一段与占空比成正比的时间。等待结束后(只需模拟一个延迟计数器) 然后关闭LED。 然后等待占空比的补码。 重复。
使用伪代码:
while (true)
{
pwm = computePercentageBasedOnAnalogSignal(analog_signal)
turn_on_led();
on_counter = MAX_LOOP * pwm
off_counter = MAX_LOOP - on_counter
// scale on/off counter values appropriately if you have a sleep()
// replace with a sleep(on_counter) function if you have it
while(on_counter) {
on_counter--
}
// now turn it off.
turn_off_led()
// same comment re: sleep. remember to scale the value as necessary
while (off_counter) {
off_counter--
}
// The LED is either on or off for a MAX_LOOP total time.
// If the LED was on 90% of the MAX_LOOP and off 10% of MAX_LOOP
// AND the LOOP iterates rapidly enough it will appear to be brighter
// than if the pwm were swtiched. The loop needs to iterate rapidly
// for best effect!
}