用“懒惰”的手为“富人”准备的智能灯,“简单”且方便



介绍


他根据arduino控制的LED灯带(称为灯1)在厨房里为水槽,火炉和切割台制作了“现代”照明。这种设计工作了2年,直到“大脑”的功率部分变坏为止。这是再次从“即兴垃圾”(轮子2)重新发明轮子的绝佳机会。没错,这一次的“垃圾”将非常昂贵,并且与Z-wave智能家居兼容。以下是有关使用ZUNo(用于创建Z-wave设备的与arduino兼容的模块)替换arduino的故事,该代码最大程度地节省了代码,并说明了必要的更改。

我出现在那之前发生了什么


从前,为了洗碗或做饭,有必要打开水槽上方的灯。这是一个重做的台灯。

我不喜欢用湿手按下小开关,因为它已将220伏特的电压切换到白炽灯。



另外,灯泡发出的光主要落在水槽上,但我想更好地照亮饭桌和炉灶。

目标:

  • 使厨房的开/关灯不接触;
  • 均匀照亮水槽,餐桌和炉灶;
  • 通过用LED替换白炽灯泡来节省能源。

他组装了灯1。灯由一个2米长的铝制盒子和一个用于RGB磁带的扩散器组成。在商店里买了一个盒子和一个扩散器,现成的,有一条胶带,控制单元早就在角落里,在机翼旁等候。

外壳是工业用的(防尘,防水)。由于磁带是12伏,因此电源单元位于220 V至12 V之间,基于TLP250(光耦合器)的用于控制磁带的电流隔离板也以紧凑的设计控制了所有这些arduino。
我从旧项目中获得了电流隔离。一次,我在床头柜上为迷你吧做背光灯。当门打开时,触摸板记录到容量的变化并打开柔和的微光。也就是说,该板非常适合当前项目,剩下的就是切断所有不必要的东西。板上有一个5伏线性转换器,由ZUNo供电。

计划用手持托盘将灯打开到超声波测距仪上。他把它装在盖子上,其他所有零件都装进盒子里。全部“可靠地”用热熔胶固定。在测试时,我在电灯开关到控制单元电源旁边的旁边做了一个按钮,用于外部安装。



开灯变得更加方便和安全。它上下颠倒地固定在厨柜的底部,很难从湿手内部取水。

上一个控制单元的结论


由于我的LED灯带色彩不自然,厨房工作区的照明变得更加均匀宜人,一些产品的颜色也发生了变化。例如:由于颜色较亮,胡萝卜似乎更具开胃性。但这并没有太大的干扰,我希望它不会造成太大的伤害。

在非接触式开/关的情况下,一切都变得更糟。有效。但是在关闭状态下5分钟后,LED灯条开始闪烁。我没有开始重做光耦合器上的电路,而是保留了一切。只有打开和关闭才开始使用新开关。每个人都喜欢它的位置和形状。
经过两年的使用,烹饪过程中分泌的脂肪和其他化合物积聚在体内和体内。该噬菌斑通过孔部分地渗入壳体中,以用于电线的进入。但是由于身体的光滑表面,该物质凝结成凝胶状物质。触感令人愉悦,无味,而且...(我没尝到)。我以龙芽的形式拍了些照片。





在墙壁上,这种物质变成了可怕的袭击,而不仅仅是洗劫。

变成了什么


翻遍垃圾箱后,我发现ZUNo的未完成扩展模块。ZUNo是一种类似于arduino的板,用于设计与Z-Wave智能家居兼容的自己的设备。它是从arduino环境编程的。

制造商规格:
  • 28 kB Flash memory for your sketches
  • 2 kB RAM available
  • Z-Wave RF transmitter at 9.6/40/100 kbps
  • 26 GPIO (overlaps with special hardware controllers)
  • 4 ADC
  • 5 PWM
  • 2 UART
  • 1 USB (serial port)
  • 16 kB EEPROM
  • 1 SPI (master or slave)
  • 4 IR controllers, 1 IR learn capability
  • 1 TRIAC/ZEROX to control dimmer
  • 3 Interrupts
  • 1 Timer 4 MHz
  • I2C (software)
  • 1-Wire (software)
  • 8x6 Keypad Scanner (software)
  • 2 service LED, 1 service button
  • 1 user test LED


扩展模块使ZUNo成为了完整的调试板,在调试了原型之后,它可以用作完整的设备。

来自制造商的一些信息:
  • One 0-10 V analog output — control industrial dimmers
  • Up to four PWM or switch outputs (up to 5 A per channel) — control contactors, switches, halogen bulbs or LED strips
  • Up to eight digital 0/3 V inputs or outputs — connect various low voltage digital senors and actors
  • Up to four digital 0/3, 0/5 or 0/12 V digital or analog inputs — connect industrial 10 V sensors or any Arduino-compatible sensor
  • RS485 or UART — for industial meters
  • OneWire — for DS18B20 or other sensors


对于我的项目,我需要3个功能强大的晶体管来将12伏切换到LED灯条,并需要一个从12伏到5伏的转换器为ZUNo供电。扩展模块外围的其余部分未焊接或测试。



在电路的这一部分中,没有足够的二极管用于供电,以防止“极性反转”,并且功率场效应晶体管栅极上的电阻器必须连接到栅极,而不是在限流电阻器的前面。我将在结论中写更多有关此的内容。

该扩展模块在Gainta的外壳中提供。我以前的控制单元也来自该公司,但是大小不同。不幸的是,模块上的紧固件不适合旧外壳,并且我不想钻一个新的外壳,所以我离开了旧外壳。将该板“植入”在热熔粘合剂上。



关于编程Arduino和ZUNo的一些知识


Z-wave设备必须具有一定数量的类别。类描述设备功能和交互接口。例如,我的灯控制着由三种颜色(红色,绿色,蓝色)组成的LED灯条。这些功能由Switch多级类执行。如果将其添加到草图中,我们可以远程更改一种颜色的亮度。要控制三种颜色,您需要制作该类的三个实例。我不会更详细地讨论这一点。因为按“通道”的概念,常规的类操作对于ZUNo用户是隐藏的。例如,我需要三类Switch多级,因此在代码中应该出现3个Switch多级通道和几个用于无线电控制的回调函数。这个怎么做?您还需要添加Switch基本类,只需按一下按钮(通过网络控制器界面)即可打开和关闭指示灯,而不是每次都配置3个通道。

您需要访问开发者网站,该网站上提供了z-uno.z-wave.me/Reference/ZUNO_SWITCH_MULTILEVEL的示例ZUNo支持的每个类都有一个描述和一个示例。接下来,将建议的功能复制并粘贴到您的草图中。现在,在草图中,有3个开关多级通道和6个用于响应无线电命令的回调函数。我在Z-Wave类中不是很老练,因此我以前的LED灯带设备在这组类中工作。

通道声明如下:

扰流板方向
ZUNO_SETUP_CHANNELS(
      ZUNO_SWITCH_MULTILEVEL(getRed, setRed),
      ZUNO_SWITCH_MULTILEVEL(getGreen, setGreen),
      ZUNO_SWITCH_MULTILEVEL(getBlue, setBlue),
      ZUNO_SWITCH_BINARY(switch_getter, switch_setter)
);


添加到网络后,这导致在控制器中生成以下窗口小部件:



要调整颜色,必须分别在控制器菜单中打开和配置每种颜色。它既不方便又缓慢。但是,我很幸运。原来我并不孤单。他们想到了我们,并创建了频道z-uno.z-wave.me/Reference/ZUNO_SWITCH_COLOR现在,草图中只有一个通道和两个回调函数。在控制器菜单中,通过从调色板中进行选择,可以分别对每种颜色以及一次对所有颜色进行颜色设置。

ZUNO_SETUP_CHANNELS(ZUNO_SWITCH_COLOR(SWITCH_COLOR_FLAGS_RED|SWITCH_COLOR_FLAGS_GREEN|SWITCH_COLOR_FLAGS_BLUE, getterFunction, setterFunction));

并且在控制器菜单中看起来像这样:



下一个功能通过无线电响应请求。可能会要求读取颜色通道之一的状态。

BYTE getterFunction(BYTE component) {
  switch(component)
  {
    case SWITCH_COLOR_COMPONENT_RED:
      return pwmR;
      break;
    case SWITCH_COLOR_COMPONENT_GREEN:
      return pwmG;
      break;
    case SWITCH_COLOR_COMPONENT_BLUE:
      return pwmB;
      break;
  }
  return 3;
}

这是用于从控制器界面设置颜色的功能。

void setterFunction(BYTE component, BYTE newValue) 
{
  switch(component)
  {
    case SWITCH_COLOR_COMPONENT_RED:
      pwmR = newValue;
      break;
    case SWITCH_COLOR_COMPONENT_GREEN:
      pwmG = newValue;
      break;
    case SWITCH_COLOR_COMPONENT_BLUE:
      pwmB = newValue;
      break;
  }
  radio_action = 1;
}

这就是将arduino草图转换为ZUNo草图所需的全部代码。

结论


组装和安装后,所有声明的任务均已完成。但是,仍然有使用开关打开灯的习惯(事实证明这很方便)。非接触式包含选项也适用。在缺点中,我要指出的是,在给控制单元通电后,LED灯会闪烁一秒钟。这是由于ZUNo外设的长时间初始化。在这一点上,腿是不可预测的。我认为,如果将其放在限流电阻之后,则晶体管栅极上的上拉电阻会纠正这种情况。如果初始化代码将支路调整到输出并有目的地更改逻辑电平,则可以尝试使用RC滤波器,该滤波器不会通过短脉冲。我还没有做过,也许我永远不会做!

发现


ZUNo及其扩展模块极大地简化了“家庭技术创造力”。但是,我认为这些产品非常昂贵,如果我在其他地方工作并且Z-Wave设备不在附近,那么我将在ESP8266上进行所有操作。在开发过程中,我学习了一种新的“标准”,用于标记电源中的电线。



现在,不仅地球上标有黑色条纹,而且在我看来是“正极”线。对于扩展模块,这很重要。 5伏LM2594转换器出现故障(芯片和浸入式开关的价格约为200卢布)。我希望在扩展模块的下一版本中将有一个保护二极管,以防止“极性反转”。然后我将检查电源线的极性。另一个缺点与身体有关。外壳看起来不错,但是没有镊子,我无法将电线连接到接线盒。我希望会有一个带有其他接线端子的版本(用于从上方或倾斜角度连接电线)。

我不喜欢将照片存储在云服务上,并且经常进行备份。因此,与设计过程和灯1有关的大多数照片都被不可挽回地破坏了。



这就是组装和调试过程的所有剩余内容。

如果稍微弯曲一下,看起来背光灯就开始工作了。如果拉直,则该框和开关不可见。



ZUNo的草图。我附上,只是为了确认一切都是基本的
#include "EEPROM.h"
#include "EEPR.h"

int readPin = 9;
int triggerPin = 10;
byte controlState = 0;
word lastValue;
#define REDPIN   PWM1     // pin connection R 
#define GREENPIN PWM2     // pin connection G
#define BLUEPIN  PWM3     // pin connection B

ZUNO_SETUP_CHANNELS(ZUNO_SWITCH_COLOR(SWITCH_COLOR_FLAGS_RED|SWITCH_COLOR_FLAGS_GREEN|SWITCH_COLOR_FLAGS_BLUE, getterFunction, setterFunction));

#define ON 1
#define OFF 0
uint8_t switch_=OFF;

uint8_t pwmR=0;
uint8_t pwmG=0;
uint8_t pwmB=0;
uint8_t b_pwmR=0;
uint8_t b_pwmG=0;
uint8_t b_pwmB=0;

enum
{
  DEF_R = 255,
  DEF_G = 255,
  DEF_B = 255
};
uint8_t radio_action = 0;

void setup() 
{ 
  init_EEPROM();
  Serial.begin();
  pinMode(readPin, INPUT);
  pinMode(triggerPin, OUTPUT);
  digitalWrite(triggerPin, LOW);
  pinMode(REDPIN, OUTPUT);
  pinMode(GREENPIN, OUTPUT);
  pinMode(BLUEPIN, OUTPUT);
  analogWrite(REDPIN, pwmR & 0xff);
  analogWrite(GREENPIN, pwmG & 0xff);
  analogWrite(BLUEPIN, pwmB & 0xff);
  
} 
int act=1;
int actf = 0;
int cnt=57; 

void loop()
{
  int tmp;
  // trigger measurement
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(10);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  // read pulse width
  tmp = pulseIn(readPin, HIGH, 100000);
  lastValue = tmp / 58;
  Serial.print(" cm= ");
  Serial.println(lastValue);
  if (lastValue < 30)
  {
    cnt++;
  }
  else
  {
    cnt--;
  }
  if (cnt > 55)
  { 
    act=1;
  }
  if (cnt > 60)
    cnt= 60;
  if (cnt < 50)
  {
    act=0;
    actf=0;
  }
  if (cnt < 45 )
    cnt = 45;
  
  if ((act == 1) && (actf == 0))
  {  
    actf = 1;
    if (switch_ == OFF)
    {
      switch_=ON;
      b_pwmG = pwmG;
      b_pwmB = pwmB;
      b_pwmR = pwmR;
    }
    else
    {
      switch_=OFF;
      b_pwmR=0;
      b_pwmG=0;
      b_pwmB=0;
    }
    analogWrite(REDPIN, b_pwmR & 0xff);
    analogWrite(GREENPIN, b_pwmG & 0xff);
    analogWrite(BLUEPIN, b_pwmB & 0xff); 
  } 
  
  Serial.print("cnt = ");    
  Serial.print(cnt);  
  Serial.print(" || ");    
  Serial.print(pwmR);  
  Serial.print(" ");      
  Serial.print(pwmG);  
  Serial.print(" ");
  Serial.print(pwmB);  
  Serial.print(" ");
  Serial.println("");
 // delay(10);

 if(radio_action)
 {
    radio_action = 0;
    eepr_save_col();
    analogWrite(REDPIN, pwmR & 0xff);
    analogWrite(GREENPIN, pwmG & 0xff);
    analogWrite(BLUEPIN, pwmB & 0xff);
 }
}

BYTE getterFunction(BYTE component) {
  switch(component)
  {
    case SWITCH_COLOR_COMPONENT_RED:
      return pwmR;
      break;
    case SWITCH_COLOR_COMPONENT_GREEN:
      return pwmG;
      break;
    case SWITCH_COLOR_COMPONENT_BLUE:
      return pwmB;
      break;
  }
  return 3;
}

void setterFunction(BYTE component, BYTE newValue) 
{
  switch(component)
  {
    case SWITCH_COLOR_COMPONENT_RED:
      pwmR = newValue;
      break;
    case SWITCH_COLOR_COMPONENT_GREEN:
      pwmG = newValue;
      break;
    case SWITCH_COLOR_COMPONENT_BLUE:
      pwmB = newValue;
      break;
  }
  radio_action = 1;
}


All Articles