极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 5639|回复: 4

简单的电机控制实验代码

[复制链接]
发表于 2012-12-6 23:17:39 | 显示全部楼层 |阅读模式
Arduino程序
sample.ino
  1. /** 示例
  2.     By Apache([email protected]) 2012/11/30
  3. */
  4. #include "proto.h"

  5. #define SET_LEFT_PWM(SPEED) analogWrite(PWM_ENB_PIN, (SPEED))
  6. #define SET_RIGHT_PWM(SPEED) analogWrite(PWM_ENA_PIN, (SPEED))
  7. #define SET_DIR(DIR, XPIN, YPIN) \
  8.     do { \
  9.         if(DIR != STOP_DIR) {\
  10.             digitalWrite(XPIN, DIR); \
  11.             digitalWrite(YPIN, !DIR); \
  12.         }else {\
  13.             digitalWrite(XPIN, 0); \
  14.             digitalWrite(YPIN, 0); \
  15.         } \
  16.     }while(0)
  17.    
  18. #define SET_LEFT_DIR(DIR) SET_DIR(DIR, PWM_IN3_PIN, PWM_IN4_PIN)
  19. #define SET_RIGHT_DIR(DIR) SET_DIR(DIR, PWM_IN1_PIN, PWM_IN2_PIN)

  20. #define SET_MOTOR(LSPD, LDIR, RSPD, RDIR) \
  21.     do { \
  22.         SET_LEFT_PWM((LSPD)); \
  23.         SET_RIGHT_PWM((RSPD)); \
  24.         SET_LEFT_DIR((LDIR)); \
  25.         SET_RIGHT_DIR((RDIR)); \
  26.     }while(0)

  27. #define DEBUG(msg) Serial.println(msg)

  28. static uint8_t waiting_head = 1;
  29. static Head head;

  30. void init_pin()
  31. {
  32.     uint8_t outputs[] = {
  33.         PWM_ENA_PIN, PWM_IN1_PIN, PWM_IN2_PIN,
  34.         PWM_ENB_PIN, PWM_IN3_PIN, PWM_IN4_PIN };
  35.     uint8_t inputs[] = {};
  36.     uint8_t i, ocnt = sizeof(outputs), icnt = sizeof(inputs);
  37.    
  38.     for(i = 0; i < ocnt; i++) {
  39.         pinMode(outputs[i], OUTPUT);
  40.     }
  41.     for(i = 0; i < icnt; i++) {
  42.         pinMode(inputs[i], INPUT);
  43.     }
  44. }
  45. void setup()
  46. {
  47.     Serial.begin(9600);
  48.     Serial.flush();
  49.     init_pin();
  50. }

  51. inline void on_line_move(uint8_t *buffer)
  52. {
  53.     LineMove linemove;
  54.    
  55.     deserialize_LineMove(buffer, &linemove, 0);
  56.     SET_MOTOR(linemove.speed, linemove.dir, linemove.speed, linemove.dir);
  57. }

  58. void on_move(uint8_t *buffer)
  59. {
  60.     Move move;
  61.    
  62.     deserialize_Move(buffer, &move, 0);
  63.     SET_MOTOR(move.left_speed, move.left_dir, move.right_speed, move.right_dir);
  64. }

  65. inline void proto_process(uint32_t cmd, uint8_t *buffer)
  66. {
  67.     switch(cmd) {
  68.     case LINE_MOVE_CMD:
  69.         on_line_move(buffer);
  70.         break;
  71.     case MOVE_CMD:
  72.         on_move(buffer);
  73.         break;
  74.     default:
  75.         break;
  76.     }
  77.     Serial.flush();
  78. }
  79. void recv_package()
  80. {
  81.     int nbytes;
  82.     uint8_t buffer[MAX_BUFFER_SIZE] = "";
  83.    
  84.     nbytes = Serial.available();
  85.     if(waiting_head) {
  86.         if(nbytes >= HEAD_SIZE) {
  87.             Serial.readBytes((char *)buffer, HEAD_SIZE);
  88.             deserialize_Head(buffer, &head, 0);
  89.             waiting_head = 0;
  90.         }
  91.     }
  92.     else {
  93.         if(nbytes >= head.body_len) {
  94.             Serial.readBytes((char *)buffer, head.body_len);
  95.             proto_process(head.cmd, buffer);
  96.             waiting_head = 1;
  97.         }
  98.     }
  99. }
  100. void loop()
  101. {
  102.     recv_package();
  103. }
复制代码
proto.h
  1. /*This head file is generated by code. Please do not edit!*/
  2. #ifndef proto_H
  3. #define proto_H
  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif

  7. #define HEAD_SIZE 3
  8. #define MAX_BUFFER_SIZE 60
  9. #define FORWARD_DIR 0
  10. #define BACKWARD_DIR 1
  11. #define STOP_DIR 2
  12. #define PWM_ENA_PIN 3
  13. #define PWM_ENB_PIN 5
  14. #define PWM_IN1_PIN 8
  15. #define PWM_IN2_PIN 7
  16. #define PWM_IN3_PIN 12
  17. #define PWM_IN4_PIN 11
  18. #define LINE_MOVE_CMD 100
  19. #define MOVE_CMD 101

  20. #pragma pack(1)
  21. typedef struct {
  22.     unsigned char dir;
  23.     unsigned char speed;
  24. }LineMove;
  25. extern inline int serialize_LineMove(LineMove *linemove, void *buffer, const int offset);
  26. extern inline int deserialize_LineMove(void *buffer, LineMove *linemove, const int offset);

  27. typedef struct {
  28.     unsigned char left_dir;
  29.     unsigned char left_speed;
  30.     unsigned char right_dir;
  31.     unsigned char right_speed;
  32. }Move;
  33. extern inline int serialize_Move(Move *move, void *buffer, const int offset);
  34. extern inline int deserialize_Move(void *buffer, Move *move, const int offset);

  35. typedef struct {
  36.     unsigned char cmd;
  37.     unsigned short body_len;
  38. }Head;
  39. extern inline int serialize_Head(Head *head, void *buffer, const int offset);
  40. extern inline int deserialize_Head(void *buffer, Head *head, const int offset);

  41. static int serialize(void *stru, void *buffer, int size, const int offset);
  42. static int deserialize(void *buffer, void *stru, int size, const int offset);

  43. #pragma pack()
  44. #ifdef __cplusplus
  45. }
  46. #endif
  47. #endif
复制代码
proto.c
  1. /*This source file is generated by code. Please do not edit!*/
  2. #include "proto.h"

  3. static int serialize(void *stru, void *buffer, int size, const int offset)
  4. {
  5.     char *p_stru = (char *)stru;
  6.     char *p_buffer = (char *)(buffer + offset);
  7.    
  8.     while(*p_buffer++ = *p_stru++, size--);
  9.    
  10.     return size + offset;
  11. }
  12. static int deserialize(void *buffer, void *stru, int size, const int offset)
  13. {
  14.     char *p_stru = (char *)stru;
  15.     char *p_buffer = (char *)(buffer + offset);

  16.     while(*p_stru++ = *p_buffer++, size--);
  17.    
  18.     return size + offset;
  19. }

  20. inline int serialize_LineMove(LineMove *linemove, void *buffer, const int offset)
  21. {
  22.     return serialize(linemove, buffer, sizeof(*linemove), offset);
  23. }

  24. inline int deserialize_LineMove(void *buffer, LineMove *linemove, const int offset)
  25. {
  26.     return deserialize(buffer, linemove, sizeof(*linemove), offset);
  27. }

  28. inline int serialize_Move(Move *move, void *buffer, const int offset)
  29. {
  30.     return serialize(move, buffer, sizeof(*move), offset);
  31. }

  32. inline int deserialize_Move(void *buffer, Move *move, const int offset)
  33. {
  34.     return deserialize(buffer, move, sizeof(*move), offset);
  35. }

  36. inline int serialize_Head(Head *head, void *buffer, const int offset)
  37. {
  38.     return serialize(head, buffer, sizeof(*head), offset);
  39. }

  40. inline int deserialize_Head(void *buffer, Head *head, const int offset)
  41. {
  42.     return deserialize(buffer, head, sizeof(*head), offset);
  43. }
复制代码
上位机程序
testproto.py
  1. #-*- coding: utf-8 -*-
  2. #示例, 测试LineMove协议
  3. #By Apache([email protected]) 2012/11/20

  4. import sys
  5. try:
  6.     import serial
  7. except ImportError:
  8.     print "Import serial error"
  9.     sys.exit(1)
  10. import proto
  11. from time import sleep

  12. COM = "COM3"
  13. BAUND=9600

  14. print u"正在打开串口..."
  15. try:
  16.     ser = serial.Serial(COM, BAUND)
  17.     sleep(2)
  18. except Exception, e:
  19.     print e
  20.     sys.exit(1)
  21. print u"已打开串口 COM: %s, BAUND: %d" % (COM, BAUND)

  22. class TestLineMove:
  23.     def __init__(self):
  24.         self.head = proto.Head(cmd=proto.LINE_MOVE_CMD)
  25.         self.body = proto.LineMove()
  26.    
  27.     def __sendpkg(self):
  28.         body_buffer = self.body.serialize()
  29.         self.head.body_len = len(body_buffer)
  30.         head_buffer = self.head.serialize()
  31.         ser.write("%s%s" % (head_buffer, body_buffer))
  32.         
  33.     def __line_move(self, msg, dir=0, speed=100, t=2):
  34.         self.body.dir = dir
  35.         self.body.speed = speed
  36.         print msg, u"%s 秒" % t
  37.         self.__sendpkg()
  38.         sleep(t)
  39.         
  40.     def test(self):
  41.         print u"**LineMove协议测试开始"
  42.         for i in xrange(5):
  43.             self.__line_move(u"高速前进", dir=0, speed=255, t=0.5)
  44.             self.__line_move(u"高速后退", dir=1, speed=230, t=0.5)
  45.             self.__line_move(u"停止", dir=2, speed=0, t=0.5)
  46.             self.__line_move(u"低速前进", dir=0, speed=170, t=2)
  47.             self.__line_move(u"高速前进", dir=0, speed=255, t=3)
  48.             self.__line_move(u"低速后退", dir=1, speed=170, t=2)
  49.             self.__line_move(u"高速后退", dir=1, speed=230, t=3)
  50.             self.__line_move(u"停止", dir=2, speed=0, t=1)
  51.         print u"**LineMove协议测试结束"
  52. if __name__ == "__main__":
  53.     TestLineMove().test()
  54.     ser.close()
复制代码
proto.py
  1. #-*- coding: utf-8 -*-
  2. # This script is generated by code. Please do not edit!

  3. from struct import pack, unpack

  4. PACK_TYPE_DICT = {
  5.     "char": ("b", 1),
  6.     "uchar": ("B", 1),
  7.     "short": ("h", 2),
  8.     "ushort": ("H", 2),
  9.     "int": ("i", 4),
  10.     "uint": ("I", 4),
  11.     "long": ("l", 4),
  12.     "ulong": ("L", 4),
  13.     "longlong": ("q", 8),
  14.     "ulonglong": ("Q", 8),
  15.     "float": ("f", 4),
  16.     "double": ("d", 8),
  17. }

  18. class Codec:
  19.     @classmethod
  20.     def serialize(self, obj):
  21.         __buffer = []
  22.         for field_pktype in obj._field_pktype:
  23.             field, pktype = field_pktype[0], PACK_TYPE_DICT[field_pktype[1]][0]
  24.             value = obj.__dict__.get(field)
  25.             if not value: value = 0
  26.             __buffer.append(pack(pktype, value))
  27.         
  28.         return ''.join(__buffer)

  29.     @classmethod
  30.     def deserialize(self, obj, buffer):
  31.         offset = 0
  32.         for field_pktype in obj._field_pktype:
  33.             field = field_pktype[0]
  34.             pktype, size = PACK_TYPE_DICT[field_pktype[1]]
  35.             obj.__dict__[field] = unpack(pktype, buffer[offset: offset + size])[0]
  36.             offset += size
  37.             
  38.         return offset


  39. class MetaClass(type):
  40.     def __init__(cls, name, bases, dict):
  41.         def _init(cls, **_dict):
  42.             for field, val in _dict.items():
  43.                 setattr(cls, field, val)
  44.         def _serialize(cls, **args):
  45.             return dict["_codec"].serialize(cls, **args)
  46.         def _deserialize(cls, buffer, **args):
  47.             return dict["_codec"].deserialize(cls, buffer, **args)
  48.         
  49.         for field, _ in dict["_fields"]:
  50.             setattr(cls, field, None)
  51.             
  52.         setattr(cls, "__init__", _init)
  53.         setattr(cls, "_field_pktype", dict["_fields"])
  54.         setattr(cls, "serialize", _serialize)
  55.         setattr(cls, "deserialize", _deserialize)
  56.         
  57.         delattr(cls, "_fields")
  58.         delattr(cls, "_codec")
  59.         
  60.         super(MetaClass, cls).__init__(name, bases, dict)

  61. HEAD_SIZE = 3
  62. MAX_BUFFER_SIZE = 60
  63. FORWARD_DIR = 0
  64. BACKWARD_DIR = 1
  65. STOP_DIR = 2
  66. PWM_ENA_PIN = 3
  67. PWM_ENB_PIN = 5
  68. PWM_IN1_PIN = 8
  69. PWM_IN2_PIN = 7
  70. PWM_IN3_PIN = 12
  71. PWM_IN4_PIN = 11
  72. LINE_MOVE_CMD = 100
  73. MOVE_CMD = 101

  74. LineMove = MetaClass(
  75. name="LineMove",
  76. bases=(),
  77. dict=dict(
  78.     _codec=Codec,
  79.     _fields=(
  80.             (u'dir', u'uchar'),
  81.             (u'speed', u'uchar')
  82.         )
  83. )
  84. )

  85. Move = MetaClass(
  86. name="Move",
  87. bases=(),
  88. dict=dict(
  89.     _codec=Codec,
  90.     _fields=(
  91.             (u'left_dir', u'uchar'),
  92.             (u'left_speed', u'uchar'),
  93.             (u'right_dir', u'uchar'),
  94.             (u'right_speed', u'uchar')
  95.         )
  96. )
  97. )

  98. Head = MetaClass(
  99. name="Head",
  100. bases=(),
  101. dict=dict(
  102.     _codec=Codec,
  103.     _fields=(
  104.             (u'cmd', u'uchar'),
  105.             (u'body_len', u'ushort')
  106.         )
  107. )
  108. )
复制代码
回复

使用道具 举报

发表于 2012-12-7 08:44:34 | 显示全部楼层
好复杂,还自定义了协议{:3_57:},看着很完善很强大,等看图片或视频介绍
回复 支持 反对

使用道具 举报

发表于 2013-5-28 18:12:19 | 显示全部楼层
也不给个电路
回复 支持 反对

使用道具 举报

发表于 2013-7-2 21:49:44 | 显示全部楼层
这种只是发代码,没有接线和电路的东西,很难看懂啊
回复 支持 反对

使用道具 举报

发表于 2014-1-23 16:40:54 | 显示全部楼层
可、能上图
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-9 12:50 , Processed in 0.080910 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表