在全志XR806开发板使用编码器进行调光

news2024/11/18 21:49:40

XR806识别编码器和PWM输出

基于FreeRTOS开发,旋转编码器移植了Arduino Rotary库,注意这个库是GPL协议的,使用效果不错,首先奉上源码链接。

全志XR806开发板

之前做过一个LED调光的项目(https://oshwhub.com/czx951002/ChargeablePWMDimmingLEDDriver) ,这次想拿XR806来实现,后续打算加入远程控制的功能。这个项目使用旋转编码器来调节LED的亮度,基本原理是MCU识别编码器的旋转方向和步数,调节PWM输出占空比,从而实现亮度调节。
旋转编码器如下图所示:

在这里插入图片描述

识别其旋转方向和步数,要考虑消除抖动,否则会出现识别错误,导致系统不稳定,这和按键是类似的。具体原理可以参考这篇博客。
Github上有对应的Arduino库,注意它的开源协议是GNU GPL V3!本人曾经移植到STM32,现已移植到XR806,效果良好,源码链接。旋转编码器相关代码如下:
头文件re.h源码:

/*
 * Rotary encoder library for Arduino.
 * Port to XR806 by Zixun Chen.
 */

#ifndef _ROTARY_ENCODER_H_
#define _ROTARY_ENCODER_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "main.h"

// 根据编码器的输出类型来选择是否定义RE_HALF_STEP
#define RE_HALF_STEP

// 旋转编码器通常外接上拉电阻,对应空闲电平是00B。如果外接电阻是下拉的,需要定义RE_PINS_PULL_DOWN
// #define RE_PINS_PULL_DOWN

#define DIR_NONE 0    // 尚无完整有效的步进
#define DIR_CW   0x10 // 顺时针步进
#define DIR_CCW  0x20 // 逆时针步进

typedef struct {
    // 定义编码器A端所连的GPIO引脚
    GPIO_Port GPIO_A;
    GPIO_Pin PIN_A;
    // 定义编码器B端所连的GPIO引脚
    GPIO_Port GPIO_B;
    GPIO_Pin PIN_B;
    uint8_t RetVal; // 保存返回值
    uint8_t State; // 内部变量,保存状态机状态
} REHandle_t;

void RotaryEncoderInit(REHandle_t *REVal); // 初始化
void RotaryEncoderProcess(REHandle_t *REVal); // 读取步进

#ifdef __cplusplus
}
#endif

#endif // _ROTARY_ENCODER_H_

源文件re.c:

/* Rotary encoder handler for arduino.
 *
 * Copyright 2011 Ben Buxton. Licenced under the GNU GPL Version 3.
 * Contact: bb@cactii.net
 *
 * Port to XR806 by Zixun Chen.
 */

#include "re.h"

/*
 * The below state table has, for each state (row), the new state
 * to set based on the next encoder output. From left to right in,
 * the table, the encoder outputs are 00, 01, 10, 11, and the value
 * in that position is the new state to set.
 */

#define R_START 0x0

#ifdef RE_HALF_STEP
// Use the half-step state table (emits a code at 00 and 11)
#define R_CCW_BEGIN 0x1
#define R_CW_BEGIN 0x2
#define R_START_M 0x3
#define R_CW_BEGIN_M 0x4
#define R_CCW_BEGIN_M 0x5
const unsigned char ttable[6][4] = {
    // R_START (00)
    {R_START_M,           R_CW_BEGIN,    R_CCW_BEGIN,  R_START},
    // R_CCW_BEGIN
    {R_START_M | DIR_CCW, R_START,       R_CCW_BEGIN,  R_START},
    // R_CW_BEGIN
    {R_START_M | DIR_CW,  R_CW_BEGIN,    R_START,      R_START},
    // R_START_M (11)
    {R_START_M,           R_CCW_BEGIN_M, R_CW_BEGIN_M, R_START},
    // R_CW_BEGIN_M
    {R_START_M,           R_START_M,     R_CW_BEGIN_M, R_START | DIR_CW},
    // R_CCW_BEGIN_M
    {R_START_M,           R_CCW_BEGIN_M, R_START_M,    R_START | DIR_CCW},
};
#else
// Use the full-step state table (emits a code at 00 only)
#define R_CW_FINAL 0x1
#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6

const unsigned char ttable[7][4] = {
  // R_START
  {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
  // R_CW_FINAL
  {R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
  // R_CW_BEGIN
  {R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
  // R_CW_NEXT
  {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
  // R_CCW_BEGIN
  {R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
  // R_CCW_FINAL
  {R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
  // R_CCW_NEXT
  {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};
#endif

static uint8_t ReadPinLevel(GPIO_Port GPIOx, GPIO_Pin PINy); // 内部函数,读取引脚电平

void RotaryEncoderInit(REHandle_t *REVal) {
    GPIO_InitParam GPIO_InitVal={0};
    // 初始化GPIO引脚
    GPIO_InitVal.driving=GPIO_DRIVING_LEVEL_1;
    GPIO_InitVal.mode=GPIOx_Pn_F0_INPUT;
    GPIO_InitVal.pull=GPIO_PULL_NONE;
    HAL_GPIO_Init(REVal->GPIO_A, REVal->PIN_A, &GPIO_InitVal);
    HAL_GPIO_Init(REVal->GPIO_B, REVal->PIN_B, &GPIO_InitVal);
    // 初始化状态机
    REVal->State=R_START;
}

void RotaryEncoderProcess(REHandle_t *REVal) {
    uint8_t pinstate;
    // 读取AB端电平
    pinstate=(ReadPinLevel(REVal->GPIO_B, REVal->PIN_B)<<1) | 
              ReadPinLevel(REVal->GPIO_A, REVal->PIN_A);
    // 状态机操作
    REVal->State=ttable[REVal->State & 0xf][pinstate];
    // 返回编码器步进信息
    REVal->RetVal=REVal->State & 0x30;
}

static uint8_t ReadPinLevel(GPIO_Port GPIOx, GPIO_Pin PINy)
{
    GPIO_PinState RDPin;
    RDPin=HAL_GPIO_ReadPin(GPIOx, PINy);
    #ifdef RE_PINS_PULL_DOWN
    // 如果定义RE_PINS_PULL_DOWN,需要反转引脚电平
    if(GPIO_PIN_HIGH==RDPin) {
        return 0;
    } else {
        return 1;
    }
    #else // RE_PINS_PULL_DOWN
    if(GPIO_PIN_HIGH==RDPin) {
        return 1;
    } else {
        return 0;
    }
    #endif // RE_PINS_PULL_DOWN
}

编码器A端和B端分别连接PA12和PA13,使用板载LED即可,引脚是PA21,对应PWM_CH2。开发环境基于FreeRTOS,参考相关教程即可,XR806 SDK在 ~/tools/目录下。在 ~/tools/xr806_sdk/project/demo/ 目录下新建 tryre 文件夹,并在其中添加源代码,makefile等文件,然后按照教程编译链接下载即可。主要代码如下:
头文件main.h:

#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
extern "C" {
#endif

// 需要包含的头文件
#include <stdio.h>
#include "driver/chip/hal_gpio.h"
#include "driver/chip/hal_pwm.h"
#include "re.h"
#include "FreeRTOS.h"
#include "task.h"

#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H */

main.c:

#include "main.h"

// 定义编码器占用的GPIO引脚
static REHandle_t REVal={
    .GPIO_A=GPIO_PORT_A,
    .PIN_A=GPIO_PIN_12,
    .GPIO_B=GPIO_PORT_A,
    .PIN_B=GPIO_PIN_13
};
static const uint8_t STEPMAX=10, STEPMIN=0;
static uint8_t step=0; // 控制LED亮度等级
static void RotaryScan(void); // 编码器识别与处理
// PWM输出初始化
#define PWM_CHANNEL   PWM_GROUP1_CH2
#define PWM_MODE      PWM_CYCLE_MODE
#define PWM_GPIO_PORT GPIO_PORT_A
#define PWM_GPIO_PIN  GPIO_PIN_21
#define PWM_GPIO_MODE GPIOA_P21_F4_PWM2_ECT2
static int max_duty_ratio; // PWM计数上限
static void PWMCycleModeSet(void); // PWM重复输出模式初始化
static HAL_Status PWMDutyRatioSet(int val); // 设置PWM输出占空比
// FreeRTOS配置
#define TASK_RE_PRIO     1
#define TASK_RE_STK_SIZE 200
static TaskHandle_t TaskRE_Handler=NULL;
static void TaskCreation(void); // 创建任务
static void TaskRE(void *pvParameters); // 编码器识别任务

int main(void)
{
    printf("Rotary encoder & PWM demo.\r\n"); // 串口输出相关信息
    RotaryEncoderInit(&REVal); // 初始化编码器
    PWMCycleModeSet(); // 初始化PWM
    PWMDutyRatioSet(max_duty_ratio*step/STEPMAX); // 设置PWM输出占空比
    TaskCreation(); // 创建任务
    // 任务调度不需要用户指定
    return 0;
}

static void TaskCreation(void)
{
    BaseType_t xRet = NULL;
    taskENTER_CRITICAL();
    xRet = xTaskCreate((TaskFunction_t )TaskRE, (const char *)"TaskRE", (uint16_t)TASK_RE_STK_SIZE, 
                       (void *)NULL, (UBaseType_t)TASK_RE_PRIO, (TaskHandle_t *)&TaskRE_Handler);
    if(pdPASS == xRet) {
        printf("TaskRE created!\r\n"); // 任务创建成功
    }
    taskEXIT_CRITICAL();
}

static void TaskRE(void *pvParameters)
{
    while (1) {
        RotaryScan(); // 识别编码器步进
        vTaskDelay(10); // 延迟10(ms)
    }
}

static void RotaryScan(void)
{
    RotaryEncoderProcess(&REVal); // 识别编码器步进
    if(DIR_CW == REVal.RetVal) { // 顺时针步进
        if(step<STEPMAX) {
            step++; // 增大亮度,上限是STEPMAX
            PWMDutyRatioSet(max_duty_ratio*step/STEPMAX);
            printf("%d  ", step);
        }
    } else if(DIR_CCW == REVal.RetVal) {
        if(step>STEPMIN) {
            step--; // 减小亮度,下限是STEPMIN
            PWMDutyRatioSet(max_duty_ratio*step/STEPMAX);
            printf("%d  ", step);
        }
    }
}

static void PWMCycleModeSet(void)
{
    // 初始化硬件所需变量声明
    GPIO_InitParam io_param = {0};
    HAL_Status status = HAL_ERROR;
    PWM_ClkParam clk_param = {0};
    PWM_ChInitParam ch_param = {0};
    // 配置GPIO复用,官方例程里面缺了这一部分
    io_param.driving = GPIO_DRIVING_LEVEL_1;
    io_param.mode = PWM_GPIO_MODE;
    io_param.pull = GPIO_PULL_NONE;
    HAL_GPIO_Init(PWM_GPIO_PORT, PWM_GPIO_PIN, &io_param);
    // 配置PWM时钟源
    clk_param.clk = PWM_CLK_HOSC;
    clk_param.div = PWM_SRC_CLK_DIV_1;
    status = HAL_PWM_GroupClkCfg(PWM_CHANNEL / 2, &clk_param);
    if (status != HAL_OK) {
        printf("%s(): %d, PWM group clk config error\n", __func__, __LINE__);
    }
    // 配置PWM模式,频率和极性
    ch_param.hz = 1000;
    ch_param.mode = PWM_MODE;
    ch_param.polarity = PWM_HIGHLEVE;
    max_duty_ratio = HAL_PWM_ChInit(PWM_CHANNEL, &ch_param);
    if (max_duty_ratio == -1) {
        printf("%s(): %d, PWM ch init error\n", __func__, __LINE__);
    }
    // 设置占空比
    status = HAL_PWM_ChSetDutyRatio(PWM_CHANNEL, max_duty_ratio / 2);
    if (status != HAL_OK) {
        printf("%s(): %d, PWM set duty ratio error\n", __func__, __LINE__);
    }
    // 使能通道
    status = HAL_PWM_EnableCh(PWM_CHANNEL, PWM_MODE, 1);
    if (status != HAL_OK) {
        printf("%s(): %d, PWM ch enable error\n", __func__, __LINE__);
    }
}

static HAL_Status PWMDutyRatioSet(int val)
{
    return HAL_PWM_ChSetDutyRatio(PWM_CHANNEL, val);
}

基本思路:创建任务识别编码器,根据编码器正反转改变PWM输出,也可以实现其它的功能,附上效果演示。

#include <stdio.h>
#include "driver/chip/hal_gpio.h"
#include "driver/chip/hal_pwm.h"
#include "re.h" // 移植的编码器库
#include "FreeRTOS.h"
#include "task.h"

// 定义编码器占用的GPIO引脚
static REHandle_t REVal={
    .GPIO_A=GPIO_PORT_A,
    .PIN_A=GPIO_PIN_12,
    .GPIO_B=GPIO_PORT_A,
    .PIN_B=GPIO_PIN_13
};
static const uint8_t STEPMAX=10, STEPMIN=0;
static uint8_t step=0; // 控制LED亮度等级
// PWM输出初始化
#define PWM_CHANNEL   PWM_GROUP1_CH2
#define PWM_MODE      PWM_CYCLE_MODE
#define PWM_GPIO_PORT GPIO_PORT_A
#define PWM_GPIO_PIN  GPIO_PIN_21
#define PWM_GPIO_MODE GPIOA_P21_F4_PWM2_ECT2
static int max_duty_ratio; // PWM计数上限
// FreeRTOS配置
#define TASK_RE_PRIO     1
#define TASK_RE_STK_SIZE 200
static TaskHandle_t TaskRE_Handler=NULL;

static void TaskCreation(void) // 创建任务
{
    BaseType_t xRet = NULL;
    taskENTER_CRITICAL();
    xRet = xTaskCreate((TaskFunction_t )TaskRE, (const char *)"TaskRE", (uint16_t)TASK_RE_STK_SIZE, 
                       (void *)NULL, (UBaseType_t)TASK_RE_PRIO, (TaskHandle_t *)&TaskRE_Handler);
    if(pdPASS == xRet) {
        printf("TaskRE created!\r\n"); // 任务创建成功
    }
    taskEXIT_CRITICAL();
}

static void TaskRE(void *pvParameters) // 编码器识别任务
{
    while (1) {
        RotaryScan(); // 识别编码器步进
        vTaskDelay(10); // 延迟10(ms)
    }
}

static void RotaryScan(void) // 编码器识别与处理
{
    RotaryEncoderProcess(&REVal); // 识别编码器步进
    if(DIR_CW == REVal.RetVal) { // 顺时针步进
        if(step<STEPMAX) {
            step++; // 增大亮度,上限是STEPMAX
            PWMDutyRatioSet(max_duty_ratio*step/STEPMAX);
            printf("%d  ", step);
        }
    } else if(DIR_CCW == REVal.RetVal) {
        if(step>STEPMIN) {
            step--; // 减小亮度,下限是STEPMIN
            PWMDutyRatioSet(max_duty_ratio*step/STEPMAX);
            printf("%d  ", step);
        }
    }
}

static void PWMCycleModeSet(void) // PWM重复输出模式初始化
{
    // 初始化硬件所需变量声明
    GPIO_InitParam io_param = {0};
    HAL_Status status = HAL_ERROR;
    PWM_ClkParam clk_param = {0};
    PWM_ChInitParam ch_param = {0};
    // 配置GPIO复用,官方例程里面缺了这一部分
    io_param.driving = GPIO_DRIVING_LEVEL_1;
    io_param.mode = PWM_GPIO_MODE;
    io_param.pull = GPIO_PULL_NONE;
    HAL_GPIO_Init(PWM_GPIO_PORT, PWM_GPIO_PIN, &io_param);
    // 配置PWM时钟源
    clk_param.clk = PWM_CLK_HOSC;
    clk_param.div = PWM_SRC_CLK_DIV_1;
    status = HAL_PWM_GroupClkCfg(PWM_CHANNEL / 2, &clk_param);
    if (status != HAL_OK) {
        printf("%s(): %d, PWM group clk config error\n", __func__, __LINE__);
    }
    // 配置PWM模式,频率和极性
    ch_param.hz = 1000;
    ch_param.mode = PWM_MODE;
    ch_param.polarity = PWM_HIGHLEVE;
    max_duty_ratio = HAL_PWM_ChInit(PWM_CHANNEL, &ch_param);
    if (max_duty_ratio == -1) {
        printf("%s(): %d, PWM ch init error\n", __func__, __LINE__);
    }
    // 设置占空比
    status = HAL_PWM_ChSetDutyRatio(PWM_CHANNEL, max_duty_ratio / 2);
    if (status != HAL_OK) {
        printf("%s(): %d, PWM set duty ratio error\n", __func__, __LINE__);
    }
    // 使能通道
    status = HAL_PWM_EnableCh(PWM_CHANNEL, PWM_MODE, 1);
    if (status != HAL_OK) {
        printf("%s(): %d, PWM ch enable error\n", __func__, __LINE__);
    }
}

static HAL_Status PWMDutyRatioSet(int val) // 设置PWM输出占空比
{
    return HAL_PWM_ChSetDutyRatio(PWM_CHANNEL, val);
}

int main(void)
{
    printf("Rotary encoder & PWM demo.\r\n"); // 串口输出相关信息
    RotaryEncoderInit(&REVal); // 初始化编码器
    PWMCycleModeSet(); // 初始化PWM
    PWMDutyRatioSet(max_duty_ratio*step/STEPMAX); // 设置PWM输出占空比
    TaskCreation(); // 创建任务
    // 任务调度不需要用户指定
    return 0;
}

原贴链接:https://bbs.aw-ol.com/topic/4335/
资源获取、问题讨论可以到全志在线开发者社区进行:https://www.aw-ol.com
全志及开发者最新动态可以关注全志在线微信公众号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1066265.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

操作系统迁移难?Alibaba Cloud Linux 支持跨版本升级 | 龙蜥技术

背景 阿里云服务器迁移中心 SMC 操作系统迁移推出 Alibaba Cloud Linux 2 到 Alibaba Cloud Linux 3 的操作系统跨版本升级的功能。可以通过 SMC 控制台将 Alibaba Cloud Linux 2 一键原地升级为 Alibaba Cloud Linux 3。 Alibaba Cloud Linux 2 将会在 2024 年 3 月 31 日结…

ChatGPT是如何产生心智的?

一、前言 - ChatGPT真的产生心智了吗&#xff1f; 来自斯坦福大学的最新研究结论&#xff0c;一经发出就造成了学术圈的轰动&#xff0c;“原本认为是人类独有的心智理论&#xff08;Theory of Mind&#xff0c;ToM&#xff09;&#xff0c;已经出现在ChatGPT背后的AI模型上”…

ScheduledExecutorService的坑

参考文献 调度服务 ScheduledExecutorService 经常卡顿问题的排查及解决方法-腾讯云开发者社区-腾讯云 场景 一个安顿广播程序使用的ScheduledExecutorService来定时执行任务&#xff0c;当有一个任务出现异常后就会卡住&#xff0c;不会继续执行后续的任务。 解决方案 查找定…

完美解决 flex 实现一行三个,显示多行,左对齐

效果图 代码 <body><section class"content"><div class"item">元素</div><div class"item">元素</div><div class"item">元素</div><div class"item">元素</di…

121-宏免杀

CS生成宏&上线 生成宏 1.cs生成宏&#xff0c;如下图操作 2.点击复制宏代码&#xff0c;保存下来 cs上线 注&#xff1a;如下操作使用的是word&#xff0c;同样的操作也适用于Excel 1.新建一个word文档&#xff0c;使用word打开。点击文件—— 2.更多——选项—— 3.自定义…

如何自学(黑客)网络安全技术————(详细分析学习思路)方法

前言 前几天发布了一篇 网络安全&#xff08;黑客&#xff09;自学 没想到收到了许多人的私信想要学习网安黑客技术&#xff01;却不知道从哪里开始学起&#xff01;怎么学&#xff1f;如何学&#xff1f; 今天给大家分享一下&#xff0c;很多人上来就说想学习黑客&#xff0c…

电脑PC端有哪些好用的记笔记工具

在日常学习中&#xff0c;想要学好每一门学科&#xff0c;必定离不开使用笔记软件记录&#xff0c;如何高效记录学习笔记呢&#xff1f;电脑PC端记录学习笔记用哪一款工具比较好呢&#xff1f;今天给大家推荐一款功能比较齐全的多平台记笔记工具——敬业签。 学生们通常不仅在…

抖捧自动直播市场火热,实体行业如何实现高效开播?

在AI数字人热度之后&#xff0c;最近抖捧场景自动直播开始火遍全网&#xff0c;因为操作简单成本极低&#xff0c;只需要一部手机放在店里&#xff0c;就可以高效开播&#xff0c;深受广大实体行业老板的认可&#xff0c;那么抖捧实景自动直播的方式&#xff0c;具体是怎么实现…

亘古难题——前端开发or后端开发

一、引言 前端开发 前端开发是创建WEB页面或APP等前端界面呈现给用户的过程&#xff0c;通过HTML&#xff0c;CSS及JavaScript以及衍生出来的各种技术、框架、解决方案&#xff0c;来实现互联网产品的用户界面交互。 前端开发从网页制作演变而来&#xff0c;名称上有很明显的时…

【单调栈】下一个更大元素 II

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;单调栈循环数组 写在最后 Tag 【单调栈循环数组】【数组】 题目来源 503. 下一个更大元素 II 题目解读 在循环数组中找下一个更大的元素。循环数组指的是&#xff0c;数组的最后一个元素的下一个元素是数组首元素。 …

Windows 10 没有【休眠】选项的配置操作

目录 一、相关知识 1.1、名词解释 二、睡眠/休眠选项 三、睡眠/休眠配置 3.1 打开休眠配置 3.2 打开休眠功能 一、相关知识 1.1、名词解释 睡眠&#xff1a; 当Windows系统进入睡眠模式之后&#xff0c;将电脑当前的内存中的运行状态和数据存储在硬盘中&#xff0…

关于丢失msvcp71.dll的5个解决办法,msvcp71.dll丢失原因分析

计算机已经成为我们生活和工作中不可或缺的一部分&#xff0c;在使用计算机的过程中&#xff0c;我们经常遇到各种软件或应用程序崩溃的情况。其中&#xff0c;一个常见的错误提示是“MSVCP71.dll丢失”。这个错误通常出现在运行使用Visual C Redistributable for Visual Studi…

基于Springboot实现旧物置换网站平台演示【项目源码+论文说明】分享

基于Springboot实现旧物置换网站平台演示 摘要 随着时代在一步一步在进步&#xff0c;旧物也成人们的烦恼&#xff0c;许多平台网站都在推广自已的产品像天猫、咸鱼、京东。所以开发出一套关于旧物置换网站成为必需。旧物置换网站主要是借助计算机&#xff0c;通过对用户进行管…

Tauri | 新版2.0路线图:更强大的插件以及支持 iOS、Android 应用构建

Tauri官方在9月7号发布了新版2.0的路线图&#xff0c;该版本主要是对移动端进行升级&#xff0c;主要特性如下&#xff1a; 强大的插件系统&#xff0c;官方把常用的功能进行了插件化&#xff08;见下图&#xff09;支持使用 Swift、Kotlin 编程语言开发插件&#xff0c;对 iO…

CSP-J第二轮试题-2019年-1、2题

文章目录 参考&#xff1a;总结 [CSP-J2019] 数字游戏题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示答案答案2 [CSP-J 2019] 公交换乘题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示…

【@胡锡进】大模型量化分析- 福耀玻璃 600660.SH

SARIMA模型: import pandas as pd import numpy as np from statsmodels.tsa.statespace.sarimax import SARIMAX# 将日期转换为datetime格式 data[date] pd.to_datetime(data[date], format%Y%m%d)# 创建SARIMA模型 model SARIMAX(data[close], order(1, 0, 0), seasonal_o…

智慧空调插座:智控生活好伴侣,节能降耗好帮手

所谓“智能插座”&#xff0c;就是在普通插座上增加Wi-Fi模块&#xff0c;通过手机APP控制单个或整个插座的电源通断&#xff0c;并统计一段时间的用电量。 目前市面上所销售的智能插座&#xff0c;大多具备可连接Wi-Fi网路功能&#xff0c;如此一 来便不需要额外再购买定时控…

聊聊MySQL面试常问名词回表、索引覆盖,最左匹配

文章目录 1. 前言2. 回表操作 Index Lookup2.1 什么是回表2.2 回表的成本2.3 如何避免回表 3. 索引覆盖 Covering Index3.1 什么是索引覆盖3.2 索引覆盖的优点3.3 如何使用索引覆盖 4. 最左匹配原则&#xff08;Leftmost Prefix Match&#xff09;4.1 什么是最左匹配原则4.2 最…

扬尘监测:智能化解决方案让生活更美好

随着工业化和城市化的快速发展&#xff0c;扬尘污染问题越来越受到人们的关注。扬尘不仅影响城市环境&#xff0c;还会对人们的健康造成威胁。为了解决这一问题&#xff0c;扬尘监测成为了一个重要的手段。本文将介绍扬尘监测的现状、重要性以及智能化解决方案&#xff0c;帮助…

csdn问答混赏金的记录贴

本文只记录用户名称&#xff0c;证据详情请点击&#xff1a;证据详情传送门 文章目录 第一位——夜深人静的哝玛 (PS:与本人的头像和用户名大致一样&#xff0c;注意区分)第二位——代码调试大神&#xff08;惯犯&#xff0c;截不完&#xff09;第三位——这一次有糖 第一位——…