没想到在有生之年自己能用esp8266制作一个万能红外遥控,两天时间经历种种失败终于成功。命令敲完回车的那一刹那是最惊心动魄的,成败的验证就在那一刹那,然后的结局是沮丧或兴奋的二者之一,最痛苦的事是找不到问题的原因,最恐怖的事情是害怕永远找不到原因。
首先为什么用c语言,因为前边已经说了,不想再学arduino,nodemcu的lua实现微秒定时不准,nodemcu可以自己写c库,然后用lua调用,经过摸索,写简单库很容易。
百度搜esp8266的微秒定时,说有什么软件定时,硬件定时,硬件定时又有重复和不重复,重复定时最小50微秒,但是遥控需要13微秒,并且用lua调用c库,c库里又有回调,我也不知道怎样去实现。所以我用的os_delay_us定时。百度里万能遥控一般都是ardruino调用库或者使用硬件模块,我这种方式可能是蝎子拉屎独一份。因为遥控信号是38khz的红外,所以一个正弦波26微秒左右。细节问题一言难尽,都在代码里。lua调用 a,b=aaa.rcv()录制遥控码,aaa.snd(a,b)发送遥控码,可以用lua把变量a里的数据写到文件或转成字符串。
我又想起一个问题,nodemcu里还有个softuart库,需要更精确的定时,我看了一下源代码,定时用的是asm_ccount()
#include "module.h"
#include "lauxlib.h"
#include "platform.h"
#define DIRECT_READ(pin) (0x1 & GPIO_INPUT_GET(GPIO_ID_PIN(pin_num[pin])))
#define DIRECT_MODE_INPUT(pin) GPIO_DIS_OUTPUT(pin_num[pin])
#define DIRECT_MODE_OUTPUT(pin)
#define DIRECT_WRITE_LOW(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 0))
#define DIRECT_WRITE_HIGH(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 1))
#define strsize 300
static uint16_t aabytes[strsize];
char caiyanglv = 13;
char pin = 3;
static int aaa_rcv(lua_State *L)
{
do
{
system_soft_wdt_feed();
os_delay_us(caiyanglv);
} while (DIRECT_READ(pin));
memset(aabytes, 0, sizeof(uint16_t) * strsize);
ets_intr_lock();
uint16 count = 64000;
int chaoshi = 3200;
char pre = 0;
uint16_t shijian = 0;
int n = 0;
for (uint16 i = 0; i < count; i++)
{
os_delay_us(caiyanglv);
char thi = DIRECT_READ(pin);
if (thi == pre)
{
shijian++;
if (shijian > chaoshi)
{
break;
}
}
else
{
pre = thi;
aabytes[n] = shijian;
n++;
if (n > strsize)
break;
shijian = 0;
}
// system_get_time()
}
lua_pushlstring(L, (char *)aabytes, sizeof(uint16_t) * strsize);
lua_pushinteger(L, n);
// lua_pushinteger(L, 11);
ets_intr_unlock();
return 2;
}
static int aaa_snd(lua_State *L)
{
const uint16_t *aa = (uint16_t *)lua_tostring(L, 1);
int nn = lua_tointeger(L, 2);
char pin = 2;
ets_intr_lock();
DIRECT_MODE_OUTPUT(pin);
char a1 = 0;
for (int i = 0; i < nn; i++)
{
uint16 nnn = aa[i];
if (a1 == 0)
{
// printf("nnnnnnn%d\n", nnn);
char a2 = 0;
for (int16_t i = 0; i < nnn; i++)
{
if (a2 == 0)
{
DIRECT_WRITE_HIGH(pin);
os_delay_us(caiyanglv);
a2 = 1;
}
else
{
DIRECT_WRITE_LOW(pin);
os_delay_us(caiyanglv);
a2 = 0;
}
}
a1 = 1;
}
else
{
for (int16_t i = 0; i < nnn; i++)
{
DIRECT_WRITE_LOW(pin);
os_delay_us(caiyanglv);
}
a1 = 0;
}
}
DIRECT_WRITE_LOW(pin);
ets_intr_unlock();
lua_pushinteger(L, nn);
return 1;
}
LROT_BEGIN(aaa, NULL, 0)
LROT_FUNCENTRY(rcv, aaa_rcv)
LROT_FUNCENTRY(snd, aaa_snd)
LROT_END(aaa, NULL, 0)
NODEMCU_MODULE(AAA, "aaa", aaa, NULL);