第四集:c

作者分享了使用ESP8266模块和C语言编写代码,克服了微秒定时的挑战,成功创建了一个万能红外遥控器。通过lua调用C库函数aaa.rcv()录制和aaa.snd()发送遥控码,实现了独特的38kHz红外信号控制。
摘要由CSDN通过智能技术生成

没想到在有生之年自己能用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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值