Raspberry Pi LED亮度计算

时间:2019-08-20 21:35:20

标签: python python-3.x

我目前正在通过使用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()

1 个答案:

答案 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引脚。根据您的问题,这似乎是所需要的。

https://raspberrypi.stackexchange.com/questions/298/can-i-use-the-gpio-for-pulse-width-modulation-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!

}