精华内容
下载资源
问答
  • 如何执行,是需要靠数控系统(或者PLC之类控制器)控制伺服或者步进电机来实现定位的,编码器好比人的眼睛,知道电机轴或者负载处于当前某个位置,工业上用的一般是光电类型编码器,下边简单说明一下。01简单说下...

    0e5f99892f4bcfc6cab3c34353c1ebc0.png

    严格来讲,编码器只会告诉你该如何定位,要如何执行,是需要靠数控系统(或者PLC之类控制器)控制伺服或者步进电机来实现定位的,编码器好比人的眼睛,知道电机轴或者负载处于当前某个位置,工业上用的一般是光电类型编码器,下边简单说明一下。

    bfff3c618a668666ae5924e22daa0126.png

    01

    简单说下编码原理和位置测量

    光电编码器是在一个很薄很轻的圆盘子上,通过紧密仪器来腐蚀雕刻了很多条细小的缝,相当于把一个360度,细分成很多等分,比如成1024组,这样每组之间的角度差是360/1024度=0.3515625度。

    9e0e83c69622823a420ba010ab69c174.png

    然后有个精密的发光源,安装在码盘的一面,码盘的另外一面,会有个接收器之类的,使用了光敏电阻这些元件加放大和整形电路组成,这样码盘转动时候,有缝隙的地方会透光过去,接收器会瞬间收到光脉冲,经过电路处理后,输出一个电脉冲信号,这样码盘旋转了一周,会对应输出1024个脉冲,第一个脉冲位置如果是0,第二个脉冲位置就是0.3515625°,第三个脉冲位置是0.3515625°*2,以此类推,这样只要有仪器能读到脉冲个数,就可以知道码盘对应在什么位置了,如果把编码器安装到电机的轴上,电机轴和码盘是刚性连接,两者的位置关系会一一对应,通过读编码器脉冲,就可以知道电机的轴位置。

    83eef9c5ee5272be4ed756a375a42e3c.png

    而电机轴,比如会通过同步带,齿轮,链条等带动一些负载,比如控制丝杆,这样会有个所谓电子齿轮比的关系,电机转一圈,丝杆会前进多少毫米,这样读到了对应编码器上输出多少给脉冲,通过脉冲数就可以反推出当前丝杆的位置。

    fbbcbc8e2575ac7e95a9e0f9b4ee75ea.png

    但是编码器是圆的,如果无限制旋转下去,角度会无穷大,所以设计了一种增量型的编码器,转一圈,会输出三组信号ABZ,其中AB是一样的脉冲,比如上边说的一圈有1024个脉冲,AB相脉冲对应一圈内的圆周角度,而且两种脉冲是处于正交状态的,如果是正反转,通过判断AB相脉冲的上升沿和下降沿的先后顺序,就可以知道编码器当前是顺时针还是逆时针方向旋转的。

    e9c0b8c7f399767c2d81c37076278182.png

    另外有个Z相脉冲,是因为圆周虽然会不停转下去,角度会无穷无尽,但是都是一周一周的重复而已,零相脉冲固定在圆周某个位置,编码器每转一圈,只输出一个零相脉冲,这样如果以Z相脉冲为基准点,这样每次读到这个脉冲时候,系统就清零一次,就可以让角度最大值控制在360°以内,相当于一个零基准点了。

    1a143f66567087c877fefcb68317b349.png

    这样即使系统断掉了,重新上电,只要能找到这个基准点,就可以知道丝杆的初始位置在什么地方了。

    8dcee48dcc388fa8a3093379f44e752f.png

    以上这种定位叫增量坐标系,所以编码器就是增量型编码器,应用比较广泛,因为灵活而且价格便宜。

    如果只设备只需要转一圈的,也就是角度在360°内的,编码器可以细分精密一点,比如有13位,相当于2^13次方个脉冲一圈,对应着360°,这种脉冲数和角度一一对应,不怕系统断电需要重新调整零位,这种编码器叫单圈绝对值编码器。如果负载需要转多圈的,但是这个圈数也不能非常多,比如5圈,相当于5*360°=1800°,这样脉冲和1800°一一对应,这些在一些高档的数控机床上应用比较多,可以知道丝杆或者一些旋转工作的当前精密位置,而且不用担心系统断电归零问题。

    079a5d053ebc5486092543999f117fbc.png

    此外,编码器还有磁电方式的,比如在码盘上加工了很多个南北间隔的小磁铁,通过霍尔去读小磁铁信号,输出信号,同样经过放大和整形变成了电脉冲,这点和光电编码器是类似的,而且价格会便宜点,可靠性会高,但是精度就比光电要差点。

    02

    PLC如何通过编码器判断位置

    PLC能输入开关量,也就是一高一低的电平电压,而编码器脉冲信号,可以理解一定时间内,用极快的速度完成的一组开关量。但是因为这种开关量的频率太高了,所以PLC的普通I/O口是无法准确读到这些脉冲的个数的,因为PLC工作过程中存在扫描周期,需要每个一段时间才去刷新一下普通I/O口的数据,而编码器的精度太高了,单位时间内输出的脉冲个数太多,普通I/O是无法胜任的。

    562bcfb31d34c8d0929bb4da2fb53810.png

    一般PLC会设计有高速计数端口,本质是利用了底层单片机的硬件逻辑来完成这些编码器计数的,避开了扫描周期问题,PLC都设计有专门的高速计数指令,使用的时候,直接调用这些指令就可以读到当前的脉冲值了。

    f8eb0d3bae19b4978923ec537a9e5138.png

    但是脉冲的计算和输出上,由于扫描周期存在,往往也会存在着滞后影响,如果用来控制一些执行机构,比如气缸来动作裁切动作,这样要考虑提前量的补偿问题。

    1d4a2812335ed83f4e6ed530db7086b9.png

    提醒一下,如果想用PLC来控制伺服或者步进系统,往往并不需要通过编码器反馈来判断位置,通过一些PLS指令之类的来发出位置脉冲给伺服驱动器,位置环在伺服驱动器内部构成就好,而PLC这边只是一个指令机构,并没有构成位置闭环,当然如果是专门定位模块控制,使用了NC之类的控制方式,是可以在里边构建位置闭环的。

    展开全文
  • ![图片说明](https://img-ask.csdn.net/upload/202003/23/1584934998_198487.png) 这是从网上找的程序,但是出问题了,不知道怎么解决。 有人能帮我写一下要实现这个目标的完整代码吗?
  • 1、什么是IOC和DIIOC的起源程序员的春天spring框架中的概念,IOC (inversion of control)其意思是反转控制;那么什么是反转控制呢...举个例说明:拿我们做饭买菜举例:没有IOC之前我们要做饭的话需要自己每天去菜市...

    1、什么是IOC和DI

    IOC的起源程序员的春天spring框架中的概念,IOC (inversion of control)其意思是反转控制;那么什么是反转控制呢,我们常见的回答就是说我们的对象创建都交给IOC了,程序员从我们平常代码中大量的NEW代码解脱出来,消除了大量冗余的代码;举个比较形象的例子说明IOC做了什么;

    举个例说明:拿我们做饭买菜举例:

    没有IOC之前我们要做饭的话需要自己每天去菜市场买菜、用了IOC之后呢 我们只需要告诉菜贩子今天要吃什么菜,然后菜贩子把菜准备好送上门;

    然而spring的IOC就相当于这个菜贩子,我们相当于当初要每天出门买菜的人,用了spring的IOC之后我们只需要告诉(通过配置xml 或注解)菜贩子我们需要什么菜(需要使用什么对象),然后它就会帮我们准备好(创建好对象);

    然后用了IOC之后就伴随着DI (depend injection 依赖注入),什么叫依赖注入呢,结合上面买菜的例子,在我们买菜的时候告诉菜贩子什么样的菜需要放什么佐料,然后菜贩子会帮我们把对应菜和对应的佐料(大蒜、葱、姜)打好包准备好给我们,我们拿着对应打好包的菜就可以只接炒了不需要再去整理;

    如何实现自己的IOC

    通过上面我们知道了IOC的理念之后那我们接下来尝试整理下思路实现IOC的功能的大概思路和相关技术;

    目标:把用户需要用到的对象实例化封装到一个容器中,提供容器公共的访问方法供开发人员使用;

    整理思路:实现这个目标的过程需要做些什么

    第一步:

    创建自定义的注解(带有我们自定义注解的类才进行对象的实例化和装配);

    第二步:

    需要读取用户配置文件;(用户可自定义哪些包需要进行扫描bean的装配);

    第三步:

    扫描文件进行类加载(根据用户的配置扫描对应的包加载对应包里面的class放到一个容器里面);

    第四步:

    把扫描出来的class中带有自定义注解的类和属性分别进行实例化和属性注入;

    第五步:

    把实例化好的对象放到一个容器里并提供调用方法;

    根据以上思路我们整理出来需要使用的技术有注解相关技术、配置文件加载技术、类加载技术、反射技术;

    自己用最简单的代码实现一个Spring 的IOC功能。

    按照上面的思路我们已经大概了解了实现一个IOC所需要的功能步骤如下:

    ea0928a97aaf705b47188eb45e18ae05.png

    1、前期准备

    1-1、新建application.properties 配置ioc.bean.scan属性,指定扫描哪个文件目录下的类。

    47fd6f3280b1d3719d85a527e3bd0235.png

    1-2定义MyComponet 注解 标注哪些类需要进行IOC管理

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    public @interface MyComponent {
    
        String value() default  "";
    
    } 

    1-3、定义MyAutowrite 注解 标注哪些属性进行依赖注入

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @Documented
    public @interface MyAutowired {
    
        String value() default  "";
    
    }

    1-4、读取Properties文件(读取ioc.bean.scan的值)、类名首字母转小写工具方法(bean的名称默认是类名首字母小写)。

    public class IocUtil {
    
     /**
         * 根据配置文件名加载配置文件
     *
         * @param fileName
     * @return
     */
     public static Properties getPropertyByName(String fileName) {
            InputStream is = null;
            Properties pro = null;
     try {
                is = IocUtil.class.getClassLoader().getResourceAsStream(fileName);
                pro = new Properties();
                pro.load(is);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
     if (is != null) {
     try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
     return pro;
        }
    
    
     /**
         * 首字母转小写
     *
         * @return
     */
     public static String toLowercaseIndex(String name) {
     if (StringUtils.isNotEmpty(name)) {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append(name.substring(0, 1).toLowerCase());
                stringBuilder.append(name.substring(1, name.length()));
     return stringBuilder.toString();
            }
     return null;
        }
    
    
    
    }

    1-5、定义需要进行IOC关联的类UserDao 、UserService

    @MyComponent
    public class UserDao {
    
     public void findUser(String userName) {
            System.out.println("找到了一个用户名字叫:"+userName);
        }
    }
    @MyComponent
    public class UserService {
    
        @MyAutowired
     private UserDao userDao;
    
     public void findUser(String userName) {
            userDao.findUser(userName);
        }
    
    
    }

    2、定位资源

    2-1、读取application.properties 文件的ioc.bean.scan属性,得到需要扫描的文件夹。

    /**
     * 定位需要进行实例化JAVA类
     */
    private String getBeanScanPath(String key) {
        Properties properties = IocUtil.getPropertyByName("application.properties");
     return properties.get(key).toString();
    
    }

    3、根据ioc.加载需要实例化的对象、并保存到classNameSet集合里。

     /**
         * 加载JAVAClass,后期根据class 的全路径名实例化bean
         */
        public void loadBeanClass(String packageName) {
            //com.cn.dp 转换成 com/cn/dp文件夹路径
            String filePath = packageName.replace(".", "/");
            URL url = this.getClass().getClassLoader().getResource(filePath);
            //得到根文件夹
            File rootFile = new File(url.getFile());
            //遍历所有文件夹
            if (rootFile != null) {
                for (File file : rootFile.listFiles()) {
                    if (file.isDirectory()) {
                        //如果是文件夹则递归继续往下扫描
                        loadBeanClass(packageName + "." + file.getName());
                    } else {
                        if (file.getName().indexOf(".class") > 0) {
                            //保存class类名
                            classNameSet.add(packageName + "." + file.getName().replace(".class", ""));
                        }
    
                    }
    
                }
    
            }
    
        }

    4、实例化对象保存到beanMap容器

    /**
     * 注册实例化Bean
     */
    private void registerBean() throws Exception {
    
     if (CollectionUtils.isNotEmpty(classNameSet)) {
     for (String className : classNameSet) {
     //实例化对象放入beanMap
     Class clazz = Class.forName(className);
    
     MyComponent myComponent = (MyComponent) clazz.getAnnotation(MyComponent.class);
     if (myComponent == null) continue;
    
     //定义bean key名称
     String beanName = (StringUtils.isEmpty(myComponent.value())) ? IocUtil.toLowercaseIndex(clazz.getSimpleName()) : myComponent.value();
     beanMap.put(beanName, clazz.newInstance());
    
            }
    
        }
    
    }

    1、对已经实例化的对象进行属性注入

    private void doInjection(Object o) throws Exception {
     //获取类的属性,进行依赖注入
     Field[] fields = o.getClass().getDeclaredFields();
     if (ArrayUtils.isNotEmpty(fields)) {
     for (Field file : fields) {
     MyAutowired autowired = file.getAnnotation(MyAutowired.class);
     if (autowired != null) {
     //得到beanName 验证该Bean是否已经实例化了
     String beanName = (StringUtils.isEmpty(autowired.value()))? IocUtil.toLowercaseIndex(file.getType().getSimpleName()):autowired.value();
     //如果bean已经被实例化了,否则创建对象
     if (!beanMap.containsKey(beanName)) {
                        Class clazz = file.getType();
     beanMap.put(beanName, clazz.newInstance());
                    }
     //调用对象set方法注入属性
     file.setAccessible(true);
                    file.set(o, beanMap.get(beanName));
     //递归当前实例化的对象的属性注入
     doInjection(beanMap.get(beanName));
                }
    
            }
        }
    
    }

    6、IOC容器整体代码如下

    public class MyApplicationContext {
    
    
     //存储实例后的Bean容器
     private Map<String, Object> beanMap = new ConcurrentHashMap<String, Object>();
     //需要实例化的对象Class全路径名
     private Set<String> classNameSet = new HashSet<String>();
    
     public MyApplicationContext() {
     try {
                init();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
     /**
         * 根据Bean名称获取对象实例
     *
         * @param name
     * @return
     */
     public Object getBean(String name) throws NotFountBeanException {
     return beanMap.get(name);
        }
    
    
     /**
         * 初始化IOC容器
     * @throws Exception
         */
     public void init() throws Exception {
     //1、定位资源
     String beanScanPath = getBeanScanPath("ioc.bean.scan");
     //2、加载需要实例化的Class
     loadBeanClass(beanScanPath);
     //3、实例化bean
     registerBean();
     //4、注入bean的属性
     dependenceInjection();
    
        }
    
     /**
         * 定位需要进行实例化JAVA类
     */
     private String getBeanScanPath(String key) {
            Properties properties = IocUtil.getPropertyByName("application.properties");
     return properties.get(key).toString();
    
        }
    
     /**
         * 加载JAVAClass
         */
     private void loadBeanClass(String packageName) {
            String filePath = packageName.replace(".", "/");
            URL url = this.getClass().getClassLoader().getResource(filePath);
     //得到根文件夹
     File rootFile = new File(url.getFile());
     //遍历所有文件夹
     if (rootFile != null) {
     for (File file : rootFile.listFiles()) {
     if (file.isDirectory()) {
     //文件夹则递归
     loadBeanClass(packageName + "." + file.getName());
                    } else {
     if (file.getName().indexOf(".class") > 0) {
     //保存class类
     classNameSet.add(packageName + "." + file.getName().replace(".class", ""));
                        }
    
                    }
    
                }
    
            }
    
        }
    
     /**
         * 注册实例化Bean
         */
     private void registerBean() throws Exception {
    
     if (CollectionUtils.isNotEmpty(classNameSet)) {
     for (String className : classNameSet) {
     //实例化对象放入beanMap
     Class clazz = Class.forName(className);
    
     MyComponent myComponent = (MyComponent) clazz.getAnnotation(MyComponent.class);
     if (myComponent == null) continue;
    
     //定义bean key名称
     String beanName = (StringUtils.isEmpty(myComponent.value())) ? IocUtil.toLowercaseIndex(clazz.getSimpleName()) : myComponent.value();
     beanMap.put(beanName, clazz.newInstance());
    
                }
    
            }
    
    
        }
    
    
     /**
         * 依赖注入
     */
     private void dependenceInjection() throws Exception {
     if (MapUtils.isEmpty(beanMap)) return;
     for (Object o : beanMap.values()) {
                doInjection(o);
            }
        }
    
    
     private void doInjection(Object o) throws Exception {
     //获取类的属性,进行依赖注入
     Field[] fields = o.getClass().getDeclaredFields();
     if (ArrayUtils.isNotEmpty(fields)) {
     for (Field file : fields) {
     MyAutowired autowired = file.getAnnotation(MyAutowired.class);
     if (autowired != null) {
     //得到beanName 验证该Bean是否已经实例化了
     String beanName = (StringUtils.isEmpty(autowired.value()))? IocUtil.toLowercaseIndex(file.getType().getSimpleName()):autowired.value();
     //如果bean已经被实例化了,否则创建对象
     if (!beanMap.containsKey(beanName)) {
                            Class clazz = file.getType();
     beanMap.put(beanName, clazz.newInstance());
                        }
     //调用对象set方法注入属性
     file.setAccessible(true);
                        file.set(o, beanMap.get(beanName));
     //递归当前实例化的对象的属性注入
     doInjection(beanMap.get(beanName));
                    }
    
                }
            }
    
        }
    
    }

    7、测试

    public class TestIOC {
    
     public static void main(String[] args) throws Exception {
            MyApplicationContext myApplicationContext=new MyApplicationContext();
             UserService userService =(UserService)myApplicationContext.getBean("userService");
            userService.findUser("张三");
    }
    
    }

    结果成功调用容器中Bean的方法

    a7cd8f52175ac71f69cb3777bc5a8ed1.png
    展开全文
  • c++,结构体成员的编码名称作为函数参数,如何实现(2012-04-10 02:03:34)标签:c结构体如何杂谈c++,结构体成员的编码名称作为函数参数,如何实现 本帖最后由 caohui8666 于 2011-01-30 18:31编辑先用例子说明我想问...

    c++,结构体成员的编码名称作为函数参数,如何实现

    (2012-04-10 02:03:34)

    标签:

    c

    结构体

    如何

    杂谈

    c++,结构体成员的编码名称作为函数参数,如何实现 本帖最后由 caohui8666 于 2011-01-30 18:31

    编辑

    先用例子说明我想问的问题:

    typedef struct{

    int aaa;

    int bbb;

    int ccc;

    }test_stu;

    int _fun(test_stu *_test, char *_str)

    {

    return 0;

    }

    int main()

    {

    test_stu test;

    memset(&test, 0, sizeof(test_stu ));

    test.aaa = 111;

    test.bbb = 222;

    test.ccc = 333;

    int result = _fun(&test,

    "aaa");

    printf("result[%d]\n",

    result);

    return 0;

    }

    总体描述的意思是,一个结构体(这个结构体成员的个数有可能还会增加,比如再增加一个int

    ddd),需要一个函数,给这个函数输入这个结构体的成员的变量名称,就能返回这个成员的取值。

    如何实现?请求高手指导,在线等。

    另外补充一点,offsetof是一个宏函数,第二个参数是成员的明细,不能是一个变量,无法最终实现需求。

    我需要传给_fun函数一个字符串变量,变量值为“aaa”,然后返回aaa的取值即111;输入“bbb”,返回222;而不能写死的offsetof(test_stu

    ,

    aaa).offsetof可以返回结构体成员的偏移,这样用首地址和这个偏移就可以计算出该成员的起始地址。但问题是成员的类型,如果能确定是一种类型,比如INT,那还是可以实现的,如果无法确定类型,就不好办了。

    如果能确定类型的话(比如INT),可以这样写

    int _fun(char *p, int a)

    {

    return *((int *)(p + a));

    }

    然后用的时候,比如

    int result= _fun(&test, offsetof(test_stu, aaa));回复

    2# liwangli1983

    这个结构体的成员类型是不确定的,可能是各种类型,

    分享:

    喜欢

    0

    赠金笔

    加载中,请稍候......

    评论加载中,请稍候...

    发评论

    登录名: 密码: 找回密码 注册记住登录状态

    昵   称:

    评论并转载此博文

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

    展开全文
  • 测调 西安.老雷子 2020年6月1日 软件平台 WINDOWS Keil uVision,STM32 ST-LINK 硬件平台 STM32S108C8B6 通用32开发板调试 ...先简单了解一下编码如何把二进制体现出来,如下图,芯片本身调制解调不是调整频率而是采用

    测调 西安.老雷子 2020年6月1日
    软件平台 WINDOWS Keil uVision,STM32 ST-LINK
    硬件平台 STM32S108C8B6 通用32开发板调试
    发射端: 蜂鸟远T1 输入需要用MCU进行编码,利于指定编码
    接收端: 蜂鸟灵R1 输出有五种模式,其中模式5就是串口直接输出编码的
    编码模式 EV1527
    在这里插入图片描述一、 系统调试硬件结构说明
    发射端硬件示意图 接收端硬件示意图

    在这里插入图片描述二、 如何对位进行编码
    先简单了解一下编码中如何把二进制体现出来,如下图,芯片本身调制解调不是调整频率而是采用调幅模式,换句话说,用发射和不发射的时长和间隔来体现是逻辑1还是逻辑0;如下,看懂这个逻辑关系也就注意到了后面发射的时候怎么编1的码,怎么编0的码了。
    在这里插入图片描述上面的对于1位的编码按照从高位到低位顺序连接起来,再在开始加上一个同步码就完成了一个字节的传输,实现起来还是很方便的。
    发射一个字节流程如下:
    1、 发射同步:逻辑1持续1T然后逻辑0持续3T
    2、 顺序发射bit7、bit6、bit5、bit4、bit3、bit2、bit1、bit0(逻辑0和1按照上面规则)
    三、 如何对一个发射码进行编码?
    对于一个发射码而言,按照EV1527的编码规范,发送/接收的码总共应该是8个字节,而这八个字节,并不是将上面单一字节内容直接拼接完成的。
    例如编码“80A7E40B”
    字节 0x80 0xA7 0xE4 0x0B
    顺序 Z1 Z2 Z3 Z4 Z5 Z6 Z7 Z8
    Bit数 4 4 4 4 4 4 4 4
    值 8 0 A 7 E 4 0 B
    在这里插入图片描述上面4个字节,每个字节8位。但需要注意的是蓝色部分(Z1Z5)是遥控器对码时候用的内部编码(对于远R1自学习过程而言),总共2^20个也就是编码规范中常说的百万编码,以此确保不会串码;黄色部分(Z6)只有半个字节,但这4位才对应实际按键编码,这个四位键盘编码在标准用法中只有四个值(1,2,4,8),也可以扩展直接用115(0x01~0x0F)。绿色部分的字节在发射编码的时候可以忽略不处理(芯片自己会生成一个校验码加上去的)
    如果要完成80A7E40B代码的发射,流程如下:
    1、 准备一个缓冲区unsigned char Ask_send_buf[12]
    2、 Ask_send_buf[0]=0x80;Ask_send_buf[1]=0xA7;Ask_send_buf[2]=0Xe4;
    3、 Ask_send_buf[2]的低4位清零并给Ask_send_buf[2]加上键盘码(1~15);
    4、 发射Ask_send_buf[0]
    5、 发射Ask_send_buf[1]
    6、 发射Ask_send_buf[2]
    7、 发射同步码(这个过程在编码规范里面是在前面的,但放在这个位置通讯更稳)
    8、 暂停发射做一个发射间歇(一般有15毫秒合适)
    上述实际上,按照通讯编码规约,完成一个发射码的过程必须要先后发送四次才符合1527的编码规范,因此,需要将上述过程中4~8步骤重复4次接收端才能认可。
    四、 调试注意事项
    1、 硬件连接逻辑确认(前面给出的连接关系别搞错线,注意所选用的模块电压不要出现烧片)
    2、 如何确认发射端开始发码?
    无线模块开始发射以后,由于无线433信号不依赖专用设备比较难以判断是否已经发射,建议可采用其他无线设备检查是否已经开始发射,可以用对讲机将频率调整为433MHz,发射端发码时候会有明显噪音出现。(凡带有自学习功能的遥控器或者遥控模块在未成功学习之前即使收到信号也没反映的)
    3、 如何确认发射码正确?
    接收端用灵R1模块,在确认发射端发射时进入学习状态进行学习,调整R1的输出模式为第5模式,然后通过R1模块自带串口输出功能将接受到的发射码发送到上位机查看。(需要注意模块接收的代码会自动加上前置字符串“LC:”,还会有后面的通讯校验字节)
    4、 如何确认MCU的机器周期时钟
    不同的MCU和不同的时钟配置,指令周期都可能不同,采用代码延时(计时器更方便大家可自己移植)时,为了保证第一个时序图中一个T的时间基本准确在400纳秒,最好采用示波器来矫正正确的循环次数。
    示波器不方便的时候,先搞个1分钟或者几分钟的延时通过秒表来反向推算一下400纳秒到底需要多少个等待周期;

    五、 硬件照片
    顺手把丑陋的调试硬件照片发上来,看看这么简单的连接就搞定了,还有,这无线模块缺失做的太小了,红色是灵R1,蓝色带螺旋天线的是远T1你不小心估计都没看到那个模块,调试通过发现这对模块真心好用,通讯非常稳定可靠。

    在这里插入图片描述
    顺便看看我用的调试板背面,手动飞了两根线,USB接口就直接可以SWD方式下载调试这个STM32的开发板了,比较方便。

    在这里插入图片描述
    六、 上位机接收到的代码
    调试过程中,灵R1模块除了完成与串口通讯模块的三根线连接之外,需要按照手册进行对码学习过程和输出模式设置过程。标准9600的串口通讯,使用还是比较简单的。

    在这里插入图片描述源代码也给大家分享一下吧,免得朋友们走弯路啦
    完整实现的代码下载

    展开全文
  • 参考链接: base64 - 百度百科 python中base64编码与解码 编码、进制转换、汉字转二进制 Python将形如”\xe4…"的十六进制编码字符串恢复为中文 ...3. 如何用 Python 实现 4. 具体代码 5. 代码运行展示 6. 更简...
  • 哈弗曼树往往都会根据哈夫曼编码结合着来说,因此这篇文章,主要结合着面试问题来说明。一、基本概念哈夫曼树的目的是找出存放一串字符所需的最少的二进制编码, 原理是通过统计出每种字符出现的频率!不断地对其...
  • 严格来讲,编码器只会告诉你改如何定位,要如何执行,是需要靠数控系统(或者PLC之类控制器)控制伺服或者步进电机来实现定位的,编码器好比人的眼睛,知道电机轴或者负载处于当前某个位置,工业上用的一般是光电类型...
  • 前言: ...由于较于网络上比较多的讲述了如何从解码哥伦布编码的数据,而比较缺少如何进行编码说明,本文将讲解如何使用代码来实现指数哥伦布熵编码实现。 当然最后也补充解码的代码以供参考。
  • 编码器只会告诉你改如何定位,要如何执行,是需要靠PLC之类控制器或者步进电机来实现定位的,编码器好比人的眼睛,知道电机轴或者负载处于当前某个位置,工业上用的一般是光电类型编码器,下边简单说明一下简单说下...
  • vue 和传统js编码不同 在一个严重依赖数字技术的世界中,编码能力不仅仅是简单的有用技能。 它为我们提供了不仅可以... 编码社区实现了民主化,这意味着学习并不一定局限于我们在其他STEM领域中发现的传统教育和职业...
  • [微信机器人_06]编码实现(完结)

    千次阅读 2014-03-15 16:28:08
    说明:由于自己最开始学习java时不知道如何打开下载的java工程,这里特别说明一下。下载java代码后,如果文件夹中有” .classpath”和” .project”文件,则可以以工程的形式打开盖源码。方法如下: File → Import ...
  • 该设计方法说明如何利用信道编码来提高安全性和抵御攻击,而又不影响通信可靠性。 该算法在(Cyclone-IV4CE115)上实现,以实现可变的吞吐量。 它在SNR = 3.25 dB时达到604 Mbps和10-6 BER,而对于大于6 dB的SNR...
  • 如何用keras实现deepFM

    2021-01-20 11:36:02
    实现基本完全基于文末列出的deepFM 原文(还有几处或者更多地方可以优化,比如二次项多值输入的处理,样本编码等等) 文末参考的文章用Keras实现一个DeepFM 是我们初期学习和搭建deepFM 的主要参考。然后下面我们的...
  • 在一个严重依赖数字技术的世界中,编码能力不仅仅是简单的有用技能。... 编码社区实现了民主化,这意味着学习并不一定局限于我们在其他STEM领域中发现的传统教育和职业道路。 然而,学习编码的经验...
  • 那我又想实现怎么办,既然我写了就说明肯定是又办法的。今天我要给大家介绍一个第三方库——pyexecjs,这个库就能很好的解决我的问题,它可以用python运行JavaScript代码。如果对你有帮助可以给我点个赞呗^_^。配置...
  • 1.编码器概述 ...这里对此不再详细说明,本博文重在如何使用编码器,有兴趣的同学可以去网上了解,或者参考一下博文。 旋转编码器工作原理 2.增量式编码器控制思路 图2-1 编码器实物图 ...
  • python3 最近要通过python实现搜索文件中的关键词出现次数的功能,定义输入的关键字字符串为word="",代码从docx文件读取编码为"utf-8",然后进行匹配搜索。目前输入word="1",word="0"都会报错,word="1234"就不会...
  • 这个问题就涉及到了FFMPEG编码过程,具体内容可以通过《FFMPEG编码过程说明》一文了解,根据FFMPEG编码,我们来尝试实现上面的需求。 利用FFMPEG,结合命令: ffmpeg -re -stream_loop -1 -i test.mp4 -vf drawtext...
  • 3.把编码得出的特征保存到一个文本文档中(说明怎么取编码得到的特征也行) 另外我想知道一个: 训练自动编码器是样本越多越好吗?比如我有30万个样本,全部用来训练自动编码器吗,还是说只取其中一部分来训练呢?...
  • Protocol buffers是一种编码方法构造的一种有效而可扩展的格式的数据。 谷歌使用其内部几乎RPC协议和文件格式的所有协议缓冲区。 C#protobuf如何实现http方式二进制传输的一个例子及说明文档
  • 因为本人一直从事WEB前端开发工作,所以我知道HTML语义的重要性,也清楚如何标准编码,所以我发布在博客的HTML符合下面几个标准,使用这些标准,有利于更成功地实现HTML 到UBB的转换: (1)所有标签合法嵌套并正常...
  • 一些前面说明实现基本完全基于文末列出的deepFM 原文(还有几处或者更多地方可以优化,比如二次项多值输入的处理,样本编码等等)文末参考的文章用Keras实现一个DeepFM是我们初期学习和搭建deepFM 的主要参考。...
  • 这篇文章主要介绍了Python Des加密解密如何实现软件注册码机器码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 原理 判断路径下是否存在识别文件,若存在就...
  • 这个问题就涉及到了FFMPEG编码过程,具体内容可以通过《FFMPEG编码过程说明》一文了解,根据FFMPEG编码,我们来尝试实现上面的需求。 利用FFMPEG,结合命令: ffmpeg -re -stream_loop -1 -i test.mp4 -vf drawtext...
  • C++字符串类型说明(Win32 字符编码)

    千次阅读 2007-11-02 11:47:00
    本指引将总结引进各种字符类型的目的,展示一些简单的用法,并告诉您在必要时,如何实现各种字符串类型之间的转换。 在第一部分,我们将介绍3种字符编码类型。了解各种编码模式的工作方式是很重要的事情。即使你...
  • 那么如何可以做到类似QQ的好友列表功能呢,下面以一款在市面上功能强大的SDK为例做功能实现说明。  AnyChat SDK(AnyChat音视频互动开发平台)是一套跨平台的(*)即时通讯解决方案,基于先进的H.264视频编 码...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 778
精华内容 311
关键字:

编码实现如何说明