毕业设计 单片机桌面智能坞小工具

201 篇文章 124 订阅
151 篇文章 44 订阅

0 前言

🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 毕业设计 单片机桌面智能坞小工具

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:4分

🧿 选题指导, 项目分享:

https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md

1 简介

基于中科蓝讯的AB32VG1单片机制作了一款桌面小工具一个小巧、功能丰富、具有实用价值的桌面物联网“控制中枢”。可以实现: 精灵播放音乐时内部有一颗呼吸灯的效果; 精灵可以通过OLED显示当前音乐名字、播放状态; 精灵可以自动连接到MQTT服务器,实现网络交互; 精灵可以通过红外遥控,实现音乐切换和暂停播放; 精灵可以通过手机连接热点配网,配置联网信息,连接 WIFI; 精灵连接有功放模块实现播放TF卡中的音乐; 精灵连接有一个rgb彩灯,在一个精致小夜灯中实现彩虹灯的效果; 精灵连接有一个灯管,实现联网控制灯管,冬天再也不用下床关灯了; 精灵配有自主设计的微信小程序端应用,通过MQTT服务器来实现和精灵的交互;

2 主要器件

  • 中科蓝讯的AB32VG1单片机
  • RT-Thread物联网操作系统
  • 连接到MQTT服务器,实现与微信小程序交互
  • 呼吸灯
  • 微信小程序
  • 红外接收

3 实现效果

在这里插入图片描述

4 硬件设计

原理图

在这里插入图片描述

5 软件说明

软件主要分为几个线程

  • 播放器线程:挂载sd卡、载入dfs文件系统,并搜索sd 卡中的音乐文件,检测接收队列来响应上一曲、下一曲、暂停、播放等消息

  • 红外接收线程:检测红外信号

  • 串口线程:连接到ESP-01S 实现网络交互

  • OLED线程:对当前的播放状态和文件名进行显示

  • 呼吸灯、rgb 彩灯线程:控制呼吸灯和rgb彩灯

代码树

几个硬件设备都是分模块编写、耦合度较低,也较容易理解代码的用途。

整个软件的流程如下,主要是分为几个线程,通过RT-Thread来实现多线程的交互。网络端使用MQTT服务器来实现人机交互。

流程图

在这里插入图片描述
微信小程序

在这里插入图片描述

6 部分核心代码

mqtt_output_send(struct mqtt_ringbuf_t *rb, struct tcp_pcb *tpcb)
{
  err_t err;
  u8_t wrap = 0;
  u16_t ringbuf_lin_len = mqtt_ringbuf_linear_read_length(rb);
  u16_t send_len = tcp_sndbuf(tpcb);
  LWIP_ASSERT("mqtt_output_send: tpcb != NULL", tpcb != NULL);

  if (send_len == 0 || ringbuf_lin_len == 0) {
    return;
  }

  LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_output_send: tcp_sndbuf: %d bytes, ringbuf_linear_available: %d, get %d, put %d\n",
                                send_len, ringbuf_lin_len, ((rb)->get & MQTT_RINGBUF_IDX_MASK), ((rb)->put & MQTT_RINGBUF_IDX_MASK)));

  if (send_len > ringbuf_lin_len) {
    /* Space in TCP output buffer is larger than available in ring buffer linear portion */
    send_len = ringbuf_lin_len;
    /* Wrap around if more data in ring buffer after linear portion */
    wrap = (mqtt_ringbuf_len(rb) > ringbuf_lin_len);
  }
  err = tcp_write(tpcb, mqtt_ringbuf_get_ptr(rb), send_len, TCP_WRITE_FLAG_COPY | (wrap ? TCP_WRITE_FLAG_MORE : 0));
  if ((err == ERR_OK) && wrap) {
    mqtt_ringbuf_advance_get_idx(rb, send_len);
    /* Use the lesser one of ring buffer linear length and TCP send buffer size */
    send_len = LWIP_MIN(tcp_sndbuf(tpcb), mqtt_ringbuf_linear_read_length(rb));
    err = tcp_write(tpcb, mqtt_ringbuf_get_ptr(rb), send_len, TCP_WRITE_FLAG_COPY);
  }

  if (err == ERR_OK) {
    mqtt_ringbuf_advance_get_idx(rb, send_len);
    /* Flush */
    tcp_output(tpcb);
  } else {
    LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_output_send: Send failed with err %d (\"%s\")\n", err, lwip_strerr(err)));
  }
}



/*--------------------------------------------------------------------------------------------------------------------- */
/* Request queue */

/**
 * Create request item
 * @param r_objs Pointer to request objects
 * @param pkt_id Packet identifier of request
 * @param cb Packet callback to call when requests lifetime ends
 * @param arg Parameter following callback
 * @return Request or NULL if failed to create
 */
static struct mqtt_request_t *
mqtt_create_request(struct mqtt_request_t *r_objs, u16_t pkt_id, mqtt_request_cb_t cb, void *arg)
{
  struct mqtt_request_t *r = NULL;
  u8_t n;
  LWIP_ASSERT("mqtt_create_request: r_objs != NULL", r_objs != NULL);
  for (n = 0; n < MQTT_REQ_MAX_IN_FLIGHT; n++) {
    /* Item point to itself if not in use */
    if (r_objs[n].next == &r_objs[n]) {
      r = &r_objs[n];
      r->next = NULL;
      r->cb = cb;
      r->arg = arg;
      r->pkt_id = pkt_id;
      break;
    }
  }
  return r;
}


/**
 * Append request to pending request queue
 * @param tail Pointer to request queue tail pointer
 * @param r Request to append
 */
static void
mqtt_append_request(struct mqtt_request_t **tail, struct mqtt_request_t *r)
{
  struct mqtt_request_t *head = NULL;
  s16_t time_before = 0;
  struct mqtt_request_t *iter;

  LWIP_ASSERT("mqtt_append_request: tail != NULL", tail != NULL);

  /* Iterate trough queue to find head, and count total timeout time */
  for (iter = *tail; iter != NULL; iter = iter->next) {
    time_before += iter->timeout_diff;
    head = iter;
  }

  LWIP_ASSERT("mqtt_append_request: time_before <= MQTT_REQ_TIMEOUT", time_before <= MQTT_REQ_TIMEOUT);
  r->timeout_diff = MQTT_REQ_TIMEOUT - time_before;
  if (head == NULL) {
    *tail = r;
  } else {
    head->next = r;
  }
}


/**
 * Delete request item
 * @param r Request item to delete
 */
static void
mqtt_delete_request(struct mqtt_request_t *r)
{
  if (r != NULL) {
    r->next = r;
  }
}

/**
 * Remove a request item with a specific packet identifier from request queue
 * @param tail Pointer to request queue tail pointer
 * @param pkt_id Packet identifier of request to take
 * @return Request item if found, NULL if not
 */
static struct mqtt_request_t *
mqtt_take_request(struct mqtt_request_t **tail, u16_t pkt_id)
{
  struct mqtt_request_t *iter = NULL, *prev = NULL;
  LWIP_ASSERT("mqtt_take_request: tail != NULL", tail != NULL);
  /* Search all request for pkt_id */
  for (iter = *tail; iter != NULL; iter = iter->next) {
    if (iter->pkt_id == pkt_id) {
      break;
    }
    prev = iter;
  }

  /* If request was found */
  if (iter != NULL) {
    /* unchain */
    if (prev == NULL) {
      *tail= iter->next;
    } else {
      prev->next = iter->next;
    }
    /* If exists, add remaining timeout time for the request to next */
    if (iter->next != NULL) {
      iter->next->timeout_diff += iter->timeout_diff;
    }
    iter->next = NULL;
  }
  return iter;
}

/**
 * Handle requests timeout
 * @param tail Pointer to request queue tail pointer
 * @param t Time since last call in seconds
 */
static void
mqtt_request_time_elapsed(struct mqtt_request_t **tail, u8_t t)
{
  struct mqtt_request_t *r = *tail;
  LWIP_ASSERT("mqtt_request_time_elapsed: tail != NULL", tail != NULL);
  while (t > 0 && r != NULL) {
    if (t >= r->timeout_diff) {
      t -= (u8_t)r->timeout_diff;
      /* Unchain */
      *tail = r->next;
      /* Notify upper layer about timeout */
      if (r->cb != NULL) {
        r->cb(r->arg, ERR_TIMEOUT);
      }
      mqtt_delete_request(r);
      /* Tail might be be modified in callback, so re-read it in every iteration */
      r = *(struct mqtt_request_t * const volatile *)tail;
    } else {
      r->timeout_diff -= t;
      t = 0;
    }
  }
}

/**
 * Free all request items
 * @param tail Pointer to request queue tail pointer
 */
static void
mqtt_clear_requests(struct mqtt_request_t **tail)
{
  struct mqtt_request_t *iter, *next;
  LWIP_ASSERT("mqtt_clear_requests: tail != NULL", tail != NULL);
  for (iter = *tail; iter != NULL; iter = next) {
    next = iter->next;
    mqtt_delete_request(iter);
  }
  *tail = NULL;
}
/**
 * Initialize all request items
 * @param r_objs Pointer to request objects
 */
static void
mqtt_init_requests(struct mqtt_request_t *r_objs)
{
  u8_t n;
  LWIP_ASSERT("mqtt_init_requests: r_objs != NULL", r_objs != NULL);
  for (n = 0; n < MQTT_REQ_MAX_IN_FLIGHT; n++) {
    /* Item pointing to itself indicates unused */
    r_objs[n].next = &r_objs[n];
  }
}

/*--------------------------------------------------------------------------------------------------------------------- */
/* Output message build helpers */


static void
mqtt_output_append_u8(struct mqtt_ringbuf_t *rb, u8_t value)
{
  mqtt_ringbuf_put(rb, value);
}

static
void mqtt_output_append_u16(struct mqtt_ringbuf_t *rb, u16_t value)
{
  mqtt_ringbuf_put(rb, value >> 8);
  mqtt_ringbuf_put(rb, value & 0xff);
}

static void
mqtt_output_append_buf(struct mqtt_ringbuf_t *rb, const void *data, u16_t length)
{
  u16_t n;
  for (n = 0; n < length; n++) {
    mqtt_ringbuf_put(rb, ((const u8_t *)data)[n]);
  }
}

最后

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值