├── .gitignore ├── Firmware_for_MeBaseShield ├── Firmware_for_MeBaseShield.ino ├── Me7SegmentDisplay.cpp ├── Me7SegmentDisplay.h ├── MeDCMotor.cpp ├── MeDCMotor.h ├── MeGyro.cpp ├── MeGyro.h ├── MeInfraredReceiver.cpp ├── MeInfraredReceiver.h ├── MePort.cpp ├── MePort.h ├── MeRGBLed.cpp ├── MeRGBLed.h ├── MeServo.cpp ├── MeServo.h ├── MeTemperature.cpp ├── MeTemperature.h ├── MeUltrasonic.cpp ├── MeUltrasonic.h ├── MeWire.cpp └── MeWire.h ├── README.md ├── firmware ├── Me7SegmentDisplay.cpp ├── Me7SegmentDisplay.h ├── MeDCMotor.cpp ├── MeDCMotor.h ├── MeEncoderMotor.cpp ├── MeEncoderMotor.h ├── MeGyro.cpp ├── MeGyro.h ├── MeHostParser.cpp ├── MeHostParser.h ├── MeInfraredReceiver.cpp ├── MeInfraredReceiver.h ├── MePort.cpp ├── MePort.h ├── MeRGBLed.cpp ├── MeRGBLed.h ├── MeServo.cpp ├── MeServo.h ├── MeStepper.cpp ├── MeStepper.h ├── MeTemperature.cpp ├── MeTemperature.h ├── MeUltrasonic.cpp ├── MeUltrasonic.h ├── MeWire.cpp ├── MeWire.h └── firmware.ino ├── mblock_firmware ├── Me7SegmentDisplay.cpp ├── Me7SegmentDisplay.h ├── MeDCMotor.cpp ├── MeDCMotor.h ├── MeEncoderMotor.cpp ├── MeEncoderMotor.h ├── MeGyro.cpp ├── MeGyro.h ├── MeHostParser.cpp ├── MeHostParser.h ├── MeInfraredReceiver.cpp ├── MeInfraredReceiver.h ├── MePort.cpp ├── MePort.h ├── MeRGBLed.cpp ├── MeRGBLed.h ├── MeServo.cpp ├── MeServo.h ├── MeStepper.cpp ├── MeStepper.h ├── MeTemperature.cpp ├── MeTemperature.h ├── MeUltrasonic.cpp ├── MeUltrasonic.h ├── MeWire.cpp ├── MeWire.h └── mblock_firmware.ino ├── mbot_firmware ├── Me7SegmentDisplay.cpp ├── Me7SegmentDisplay.h ├── MeBuzzer.cpp ├── MeBuzzer.h ├── MeDCMotor.cpp ├── MeDCMotor.h ├── MeIR.cpp ├── MeIR.h ├── MeInfraredReceiver.cpp ├── MeInfraredReceiver.h ├── MeOneWire.cpp ├── MeOneWire.h ├── MePort.cpp ├── MePort.h ├── MeRGBLed.cpp ├── MeRGBLed.h ├── MeTemperature.cpp ├── MeTemperature.h ├── MeUltrasonic.cpp ├── MeUltrasonic.h ├── mBot.cpp ├── mBot.h └── mbot_firmware.ino ├── resources ├── firmware │ ├── mblock_firmware.zip │ └── mbot_firmware.zip ├── libraries │ ├── arduino.zip │ ├── makeblock.zip │ ├── mbot.zip │ └── serial.zip ├── locale │ └── locale.zip └── tools │ └── hex.zip └── tool ├── ArduinoTool.zip ├── base_shield.hex ├── leonardo.hex ├── mbot.hex └── uno.hex /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/Me7SegmentDisplay.cpp: -------------------------------------------------------------------------------- 1 | #include "Me7SegmentDisplay.h" 2 | static int8_t TubeTab[] = {0x3f,0x06,0x5b,0x4f, 3 | 0x66,0x6d,0x7d,0x07, 4 | 0x7f,0x6f,0x77,0x7c, 5 | 0x39,0x5e,0x79,0x71, 6 | 0xbf,0x86,0xdb,0xcf, 7 | 0xe6,0xed,0xfd,0x87, 8 | 0xff,0xef,0xf7,0xfc, 9 | 0xb9,0xde,0xf9,0xf1,0x40};//0~9,A,b,C,d,E,F,- 10 | Me7SegmentDisplay::Me7SegmentDisplay():MePort() 11 | { 12 | } 13 | Me7SegmentDisplay::Me7SegmentDisplay(uint8_t port):MePort(port) 14 | { 15 | Clkpin = s2; 16 | Datapin = s1; 17 | pinMode(Clkpin,OUTPUT); 18 | pinMode(Datapin,OUTPUT); 19 | set(); 20 | clearDisplay(); 21 | } 22 | void Me7SegmentDisplay::reset(uint8_t port){ 23 | _port = port; 24 | s2 = mePort[port].s2; 25 | s1 = mePort[port].s1; 26 | Clkpin = s2; 27 | Datapin = s1; 28 | pinMode(Clkpin,OUTPUT); 29 | pinMode(Datapin,OUTPUT); 30 | set(); 31 | //clearDisplay(); 32 | } 33 | void Me7SegmentDisplay::init(void) 34 | { 35 | clearDisplay(); 36 | } 37 | void Me7SegmentDisplay::writeByte(int8_t wr_data) 38 | { 39 | uint8_t i,count1; 40 | for(i=0;i<8;i++) //sent 8bit data 41 | { 42 | digitalWrite(Clkpin,LOW); 43 | if(wr_data & 0x01)digitalWrite(Datapin,HIGH);//LSB first 44 | else digitalWrite(Datapin,LOW); 45 | wr_data >>= 1; 46 | digitalWrite(Clkpin,HIGH); 47 | } 48 | digitalWrite(Clkpin,LOW); //wait for the ACK 49 | digitalWrite(Datapin,HIGH); 50 | digitalWrite(Clkpin,HIGH); 51 | pinMode(Datapin,INPUT); 52 | while(digitalRead(Datapin)) 53 | { 54 | count1 +=1; 55 | if(count1 == 200)// 56 | { 57 | pinMode(Datapin,OUTPUT); 58 | digitalWrite(Datapin,LOW); 59 | count1 =0; 60 | } 61 | } 62 | pinMode(Datapin,OUTPUT); 63 | } 64 | //send start signal to TM1637 65 | void Me7SegmentDisplay::start(void) 66 | { 67 | digitalWrite(Clkpin,HIGH);//send start signal to TM1637 68 | digitalWrite(Datapin,HIGH); 69 | digitalWrite(Datapin,LOW); 70 | digitalWrite(Clkpin,LOW); 71 | } 72 | //End of transmission 73 | void Me7SegmentDisplay::stop(void) 74 | { 75 | digitalWrite(Clkpin,LOW); 76 | digitalWrite(Datapin,LOW); 77 | digitalWrite(Clkpin,HIGH); 78 | digitalWrite(Datapin,HIGH); 79 | } 80 | void Me7SegmentDisplay::display(float value){ 81 | int i=0; 82 | bool isStart = false; 83 | int index = 0; 84 | int8_t disp[]={0,0,0,0}; 85 | bool isNeg = false; 86 | if(value<0){ 87 | isNeg = true; 88 | value = -value; 89 | disp[0] = 0x20; 90 | index++; 91 | } 92 | for(i=0;i<7;i++){ 93 | int n = checkNum(value,3-i); 94 | if(n>=1||i==3){ 95 | isStart=true; 96 | } 97 | if(isStart){ 98 | if(i==3){ 99 | disp[index]=n+0x10; 100 | }else{ 101 | disp[index]=n; 102 | } 103 | index++; 104 | } 105 | if(index>3){ 106 | break; 107 | } 108 | } 109 | display(disp); 110 | } 111 | int Me7SegmentDisplay::checkNum(float v,int b){ 112 | if(b>=0){ 113 | return floor((v-floor(v/pow(10,b+1))*(pow(10,b+1)))/pow(10,b)); 114 | }else{ 115 | b=-b; 116 | int i=0; 117 | for(i=0;i 255 ? 255 : speed; 13 | speed = speed < -255 ? -255 : speed; 14 | 15 | if(speed >= 0) { 16 | MePort::dWrite2(HIGH); 17 | MePort::aWrite1(speed); 18 | } else { 19 | MePort::dWrite2(LOW); 20 | MePort::aWrite1(-speed); 21 | } 22 | } 23 | void MeDCMotor::stop() 24 | { 25 | MeDCMotor::run(0); 26 | } 27 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MeDCMotor.h: -------------------------------------------------------------------------------- 1 | #ifndef MEDCMOTOR_H_ 2 | #define MEDCMOTOR_H_ 3 | #include "MePort.h" 4 | ///@brief Class for DC Motor Module 5 | class MeDCMotor: public MePort 6 | { 7 | public: 8 | MeDCMotor(); 9 | MeDCMotor(uint8_t port); 10 | void run(int speed); 11 | void stop(); 12 | }; 13 | #endif 14 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MeGyro.cpp: -------------------------------------------------------------------------------- 1 | #include "MeGyro.h" 2 | static uint8_t buffers[14]; 3 | static float angleX=0; 4 | static float angleY=0; 5 | static float angleZ=0; 6 | MeGyro::MeGyro(){ 7 | 8 | } 9 | void MeGyro::begin(){ 10 | gSensitivity = 65.5; // for 500 deg/s, check data sheet 11 | gx = 0; 12 | gy = 0; 13 | gz = 0; 14 | gyrX = 0; 15 | gyrY = 0; 16 | gyrZ = 0; 17 | accX = 0; 18 | accY = 0; 19 | accZ = 0; 20 | gyrXoffs = -281.00; 21 | gyrYoffs = 18.00; 22 | gyrZoffs = -83.00; 23 | FREQ=30.0; 24 | Wire.begin(); 25 | 26 | } 27 | int MeGyro::start(){ 28 | 29 | int error = writeReg (0x6b, 0x00); 30 | error += writeReg (0x1a, 0x01); 31 | error += writeReg(0x1b, 0x08); 32 | uint8_t sample_div = 1000 / FREQ - 1; 33 | error +=writeReg (0x19, sample_div); 34 | return error; 35 | } 36 | double MeGyro::getAngleX(){ 37 | if(accZ==0)return 0; 38 | return (atan((float)accX/(float)accZ))*180/3.1415926; 39 | } 40 | double MeGyro::getAngleY(){ 41 | if(accZ==0)return 0; 42 | return (atan((float)accY/(float)accZ))*180/3.1415926; 43 | } 44 | double MeGyro::getAngleZ(){ 45 | if(gyrZ==0)return 0; 46 | return gyrZ/10.0; 47 | } 48 | void MeGyro::close(){ 49 | } 50 | void MeGyro::update(){ 51 | unsigned long start_time = millis(); 52 | uint8_t error; 53 | // read imu data 54 | if(start()!=0){ 55 | return; 56 | } 57 | error = readData(0x3b, i2cData, 14); 58 | if(error!=0){ 59 | 60 | return; 61 | } 62 | 63 | double ax, ay, az; 64 | // assemble 16 bit sensor data 65 | accX = ((i2cData[0] << 8) | i2cData[1]); 66 | accY = ((i2cData[2] << 8) | i2cData[3]); 67 | accZ = ((i2cData[4] << 8) | i2cData[5]); 68 | 69 | gyrX = (((i2cData[8] << 8) | i2cData[9]) - gyrXoffs) / gSensitivity; 70 | gyrY = (((i2cData[10] << 8) | i2cData[11]) - gyrYoffs) / gSensitivity; 71 | gyrZ = (((i2cData[12] << 8) | i2cData[13]) - gyrZoffs) / (gSensitivity+1); 72 | ay = atan2(accX, sqrt( pow(accY, 2) + pow(accZ, 2))) * 180 / M_PI; 73 | ax = atan2(accY, sqrt( pow(accX, 2) + pow(accZ, 2))) * 180 / M_PI; 74 | 75 | // angles based on gyro (deg/s) 76 | gx = gx + gyrX / FREQ; 77 | gy = gy - gyrY / FREQ; 78 | gz += gyrZ / FREQ; 79 | 80 | // complementary filter 81 | // tau = DT*(A)/(1-A) 82 | // = 0.48sec 83 | gx = gx * 0.96 + ax * 0.04; 84 | gy = gy * 0.96 + ay * 0.04; 85 | 86 | //delay(((1/FREQ) * 1000) - (millis() - start_time)-time); 87 | } 88 | int MeGyro::readData(int start, uint8_t *buffer, int size) 89 | { 90 | int i, n, error; 91 | Wire.beginTransmission(0x68); 92 | n = Wire.write(start); 93 | if (n != 1) 94 | return (-10); 95 | n = Wire.endTransmission(false); // hold the I2C-bus 96 | if (n != 0) 97 | return (n); 98 | delayMicroseconds(1); 99 | // Third parameter is true: relase I2C-bus after data is read. 100 | Wire.requestFrom(0x68, size, true); 101 | i = 0; 102 | while(Wire.available() && i 4 | #include 5 | class MeGyro{ 6 | public: 7 | MeGyro(); 8 | void begin(); 9 | void update(); 10 | double getAngleX(); 11 | double getAngleY(); 12 | double getAngleZ(); 13 | void close(); 14 | private: 15 | int readData(int start, uint8_t *buffer, int size); 16 | int writeData(int start, const uint8_t *pData, int size); 17 | int writeReg(int reg, uint8_t data); 18 | int start(); 19 | double gSensitivity; // for 500 deg/s, check data sheet 20 | double gx, gy, gz; 21 | double gyrX, gyrY, gyrZ; 22 | int16_t accX, accY, accZ; 23 | double gyrXoffs, gyrYoffs, gyrZoffs; 24 | double FREQ; 25 | uint8_t i2cData[14]; 26 | }; 27 | #endif 28 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MeInfraredReceiver.cpp: -------------------------------------------------------------------------------- 1 | #include "MeInfraredReceiver.h" 2 | 3 | MeInfraredReceiver::MeInfraredReceiver():MePort(){ 4 | 5 | } 6 | 7 | MeInfraredReceiver::MeInfraredReceiver(uint8_t port):MePort(port){ 8 | pinMode(s1,INPUT); 9 | pinMode(s2,INPUT); 10 | } 11 | int MeInfraredReceiver::available(){ 12 | char c = poll(); 13 | if(c>0){ 14 | _buffer = c; 15 | return 1; 16 | } 17 | return 0; 18 | } 19 | unsigned char MeInfraredReceiver::read(){ 20 | unsigned char c = _buffer; 21 | _buffer = 0; 22 | return c; 23 | } 24 | 25 | bool MeInfraredReceiver::buttonState(){ 26 | 27 | if(getPort()>0){ 28 | return dRead1()==0; 29 | } 30 | return 0; 31 | } 32 | unsigned char MeInfraredReceiver::poll() 33 | { 34 | //noInterrupts(); 35 | unsigned char val = 0; 36 | int bitDelay = 1000000.0/9600.0 - clockCyclesToMicroseconds(50); 37 | if (digitalRead(s2) == LOW) { 38 | for(int offset=0;offset<8;offset++){ 39 | delayMicroseconds(bitDelay); 40 | val |= digitalRead(s2) << offset; 41 | } 42 | delayMicroseconds(bitDelay); 43 | //interrupts(); 44 | return val&0xff; 45 | } 46 | //interrupts(); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MeInfraredReceiver.h: -------------------------------------------------------------------------------- 1 | #ifndef MeInfraredReceiver_H_ 2 | #define MeInfraredReceiver_H_ 3 | #include "MePort.h" 4 | class MeInfraredReceiver:public MePort{ 5 | public : 6 | MeInfraredReceiver(); 7 | MeInfraredReceiver(uint8_t port); 8 | int available(); 9 | unsigned char read(); 10 | unsigned char poll(); 11 | bool buttonState(); 12 | private: 13 | unsigned char _buffer; 14 | }; 15 | #endif 16 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MePort.cpp: -------------------------------------------------------------------------------- 1 | #include "MePort.h" 2 | 3 | #if defined(__AVR_ATmega32U4__) //MeBaseBoard use ATmega32U4 as MCU 4 | 5 | MePort_Sig mePort[11] = {{NC, NC}, {11, A8}, {13, A11}, {10, 9}, {1, 0}, 6 | {MISO, SCK}, {A0, A1}, {A2, A3}, {A4, A5}, {6, 7}, {5, 4} 7 | }; 8 | #else // else ATmega328 9 | MePort_Sig mePort[11] = {{NC, NC}, {11, 10}, {3, 9}, {12, 13}, {8, 2}, 10 | {NC, NC}, {A2, A3}, {A6, A1}, {A7, A0}, {6, 7}, {5, 4} 11 | }; 12 | 13 | #endif 14 | 15 | union{ 16 | byte b[4]; 17 | float fVal; 18 | long lVal; 19 | }u; 20 | 21 | /* Port */ 22 | MePort::MePort(){ 23 | s1 = mePort[0].s1; 24 | s2 = mePort[0].s2; 25 | _port = 0; 26 | } 27 | MePort::MePort(uint8_t port) 28 | { 29 | s1 = mePort[port].s1; 30 | s2 = mePort[port].s2; 31 | _port = port; 32 | //The PWM frequency is 976 Hz 33 | #if defined(__AVR_ATmega32U4__) //MeBaseBoard use ATmega32U4 as MCU 34 | 35 | TCCR1A = _BV(WGM10); 36 | TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12); 37 | 38 | TCCR3A = _BV(WGM30); 39 | TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); 40 | 41 | TCCR4B = _BV(CS42) | _BV(CS41) | _BV(CS40); 42 | TCCR4D = 0; 43 | 44 | #else if defined(__AVR_ATmega328__) // else ATmega328 45 | 46 | TCCR1A = _BV(WGM10); 47 | TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12); 48 | 49 | TCCR2A = _BV(WGM21) |_BV(WGM20); 50 | TCCR2B = _BV(CS22); 51 | 52 | #endif 53 | } 54 | MePort::MePort(uint8_t port,uint8_t slot) 55 | { 56 | s1 = mePort[port].s1; 57 | s2 = mePort[port].s2; 58 | _port = port; 59 | _slot = slot; 60 | //The PWM frequency is 976 Hz 61 | #if defined(__AVR_ATmega32U4__) //MeBaseBoard use ATmega32U4 as MCU 62 | 63 | TCCR1A = _BV(WGM10); 64 | TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12); 65 | 66 | TCCR3A = _BV(WGM30); 67 | TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); 68 | 69 | TCCR4B = _BV(CS42) | _BV(CS41) | _BV(CS40); 70 | TCCR4D = 0; 71 | 72 | #else if defined(__AVR_ATmega328__) // else ATmega328 73 | 74 | TCCR1A = _BV(WGM10); 75 | TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12); 76 | 77 | TCCR2A = _BV(WGM21) |_BV(WGM20); 78 | TCCR2B = _BV(CS22); 79 | 80 | #endif 81 | } 82 | uint8_t MePort::getPort(){ 83 | return _port; 84 | } 85 | uint8_t MePort::getSlot(){ 86 | return _slot; 87 | } 88 | bool MePort::dRead1() 89 | { 90 | bool val; 91 | pinMode(s1, INPUT); 92 | val = digitalRead(s1); 93 | return val; 94 | } 95 | 96 | bool MePort::dRead2() 97 | { 98 | bool val; 99 | pinMode(s2, INPUT); 100 | val = digitalRead(s2); 101 | return val; 102 | } 103 | 104 | void MePort::dWrite1(bool value) 105 | { 106 | pinMode(s1, OUTPUT); 107 | digitalWrite(s1, value); 108 | } 109 | 110 | void MePort::dWrite2(bool value) 111 | { 112 | pinMode(s2, OUTPUT); 113 | digitalWrite(s2, value); 114 | } 115 | 116 | int MePort::aRead1() 117 | { 118 | int val; 119 | val = analogRead(s1); 120 | return val; 121 | } 122 | 123 | int MePort::aRead2() 124 | { 125 | int val; 126 | val = analogRead(s2); 127 | return val; 128 | } 129 | 130 | void MePort::aWrite1(int value) 131 | { 132 | analogWrite(s1, value); 133 | } 134 | 135 | void MePort::aWrite2(int value) 136 | { 137 | analogWrite(s2, value); 138 | } 139 | void MePort::reset(uint8_t port){ 140 | s1 = mePort[port].s1; 141 | s2 = mePort[port].s2; 142 | _port = port; 143 | } 144 | void MePort::reset(uint8_t port,uint8_t slot){ 145 | s1 = mePort[port].s1; 146 | s2 = mePort[port].s2; 147 | _port = port; 148 | _slot = slot; 149 | } 150 | uint8_t MePort::pin1(){ 151 | return s1; 152 | } 153 | uint8_t MePort::pin2(){ 154 | return s2; 155 | } 156 | 157 | uint8_t MePort::pin(){ 158 | return _slot==SLOT_1?s1:s2; 159 | } 160 | uint8_t MePort::pin(uint8_t port,uint8_t slot){ 161 | return slot==SLOT_1?mePort[port].s1:mePort[port].s2; 162 | } 163 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MePort.h: -------------------------------------------------------------------------------- 1 | #ifndef MEPORT_H_ 2 | #define MEPORT_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #ifndef F_CPU 8 | #define F_CPU 16000000UL 9 | #endif 10 | #include 11 | #include 12 | #include 13 | 14 | typedef struct 15 | { 16 | uint8_t s1; 17 | uint8_t s2; 18 | } MePort_Sig; 19 | extern MePort_Sig mePort[11];//mePort[0] is nonsense 20 | 21 | struct cRGB { uint8_t g; uint8_t r; uint8_t b; }; 22 | 23 | #define NC -1 24 | 25 | #define PORT_1 0x01 26 | #define PORT_2 0x02 27 | #define PORT_3 0x03 28 | #define PORT_4 0x04 29 | #define PORT_5 0x05 30 | #define PORT_6 0x06 31 | #define PORT_7 0x07 32 | #define PORT_8 0x08 33 | #define M1 0x09 34 | #define M2 0x0a 35 | 36 | #if defined(__AVR_ATmega32U4__) 37 | // buzzer 38 | #define buzzerOn() DDRE |= 0x04,PORTE |= B00000100 39 | #define buzzerOff() DDRE |= 0x04,PORTE &= B11111011 40 | #else 41 | #define buzzerOn() DDRC |= 0x20,PORTC |= B00100000; 42 | #define buzzerOff() DDRC |= 0x20,PORTC &= B11011111; 43 | #endif 44 | #define SLOT_1 1 45 | #define SLOT_2 2 46 | 47 | 48 | #define FALSE 0 49 | #define TRUE 1 50 | 51 | // Platform specific I/O definitions 52 | 53 | #if defined(__AVR__) 54 | #define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) 55 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 56 | #define IO_REG_TYPE uint8_t 57 | #define IO_REG_ASM asm("r30") 58 | #define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 59 | #define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)) 60 | #define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) 61 | #define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) 62 | #define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) 63 | #endif 64 | 65 | 66 | ///@brief class of MePort,it contains two pin. 67 | class MePort 68 | { 69 | public: 70 | MePort(); 71 | ///@brief initialize the Port 72 | ///@param port port number of device 73 | MePort(uint8_t port); 74 | MePort(uint8_t port,uint8_t slot); 75 | ///@return the level of pin 1 of port 76 | ///@retval true on HIGH. 77 | ///@retval false on LOW. 78 | uint8_t getPort(); 79 | uint8_t getSlot(); 80 | ///@return the level of pin 1 of port 81 | ///@retval true on HIGH. 82 | ///@retval false on LOW. 83 | bool dRead1(); 84 | ///@return the level of pin 2 of port 85 | ///@retval true on HIGH. 86 | ///@retval false on LOW. 87 | bool dRead2(); 88 | ///@brief set the analog value of pin 1 of port 89 | ///@param value is HIGH or LOW 90 | void dWrite1(bool value); 91 | ///@brief set the level of pin 1 of port 92 | ///@param value is HIGH or LOW 93 | void dWrite2(bool value); 94 | ///@return the analog signal of pin 1 of port between 0 to 1023 95 | int aRead1(); 96 | ///@return the analog signal of pin 2 of port between 0 to 1023 97 | int aRead2(); 98 | ///@brief set the PWM outpu value of pin 1 of port 99 | ///@param value between 0 to 255 100 | void aWrite1(int value); 101 | ///@brief set the PWM outpu value of pin 2 of port 102 | ///@param value between 0 to 255 103 | void aWrite2(int value); 104 | void reset(uint8_t port); 105 | void reset(uint8_t port,uint8_t slot); 106 | uint8_t pin1(); 107 | uint8_t pin2(); 108 | uint8_t pin(); 109 | uint8_t pin(uint8_t port,uint8_t slot); 110 | protected: 111 | uint8_t s1; 112 | uint8_t s2; 113 | uint8_t _port; 114 | uint8_t _slot; 115 | }; 116 | #endif 117 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MeRGBLed.cpp: -------------------------------------------------------------------------------- 1 | #include "MeRGBLed.h" 2 | MeRGBLed::MeRGBLed():MePort(0) { 3 | setNumber(16); 4 | } 5 | MeRGBLed::MeRGBLed(uint8_t port):MePort(port) { 6 | pinMask = digitalPinToBitMask(s2); 7 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 8 | ws2812_port_reg = portModeRegister(digitalPinToPort(s2)); 9 | // *ws2812_port_reg |= pinMask; //set pinMode OUTPUT 10 | pinMode(s2,OUTPUT); 11 | setNumber(16); 12 | } 13 | MeRGBLed::MeRGBLed(uint8_t port,uint8_t slot):MePort(port){ 14 | if(slot==1){ 15 | pinMask = digitalPinToBitMask(s2); 16 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 17 | ws2812_port_reg = portModeRegister(digitalPinToPort(s2)); 18 | pinMode(s2,OUTPUT); 19 | }else{ 20 | pinMask = digitalPinToBitMask(s1); 21 | ws2812_port = portOutputRegister(digitalPinToPort(s1)); 22 | ws2812_port_reg = portModeRegister(digitalPinToPort(s1)); 23 | pinMode(s1,OUTPUT); 24 | } 25 | //*ws2812_port_reg |= pinMask; // set pinMode OUTPUT 26 | setNumber(16); 27 | } 28 | void MeRGBLed::reset(uint8_t port){ 29 | _port = port; 30 | s2 = mePort[port].s2; 31 | s1 = mePort[port].s1; 32 | pinMask = digitalPinToBitMask(s2); 33 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 34 | ws2812_port_reg = portModeRegister(digitalPinToPort(s2)); 35 | //*ws2812_port_reg |= pinMask; 36 | pinMode(s2,OUTPUT); 37 | } 38 | void MeRGBLed::setNumber(uint8_t num_leds){ 39 | count_led = num_leds; 40 | pixels = (uint8_t*)malloc(count_led*3); 41 | for(int i=0;i>16; 80 | uint8_t green = (value&0xff00)>>8; 81 | uint8_t blue = value&0xff; 82 | pixels[tmp] = green; 83 | pixels[tmp+1] = red; 84 | pixels[tmp+2] = blue; 85 | return true; 86 | } 87 | return false; 88 | } 89 | /* 90 | This routine writes an array of bytes with RGB values to the Dataout pin 91 | using the fast 800kHz clockless WS2811/2812 protocol. 92 | */ 93 | 94 | // Timing in ns 95 | #define w_zeropulse 350 96 | #define w_onepulse 900 97 | #define w_totalperiod 1250 98 | 99 | // Fixed cycles used by the inner loop 100 | #define w_fixedlow 3 101 | #define w_fixedhigh 6 102 | #define w_fixedtotal 10 103 | 104 | // Insert NOPs to match the timing, if possible 105 | #define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000) 106 | #define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000) 107 | #define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000) 108 | 109 | // w1 - nops between rising edge and falling edge - low 110 | #define w1 (w_zerocycles-w_fixedlow) 111 | // w2 nops between fe low and fe high 112 | #define w2 (w_onecycles-w_fixedhigh-w1) 113 | // w3 nops to complete loop 114 | #define w3 (w_totalcycles-w_fixedtotal-w1-w2) 115 | 116 | #if w1>0 117 | #define w1_nops w1 118 | #else 119 | #define w1_nops 0 120 | #endif 121 | 122 | // The only critical timing parameter is the minimum pulse length of the "0" 123 | // Warn or throw error if this timing can not be met with current F_CPU settings. 124 | #define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000) 125 | #if w_lowtime>550 126 | #error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?" 127 | #elif w_lowtime>450 128 | #warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)." 129 | #warning "Please consider a higher clockspeed, if possible" 130 | #endif 131 | 132 | #if w2>0 133 | #define w2_nops w2 134 | #else 135 | #define w2_nops 0 136 | #endif 137 | 138 | #if w3>0 139 | #define w3_nops w3 140 | #else 141 | #define w3_nops 0 142 | #endif 143 | 144 | #define w_nop1 "nop \n\t" 145 | #define w_nop2 "rjmp .+0 \n\t" 146 | #define w_nop4 w_nop2 w_nop2 147 | #define w_nop8 w_nop4 w_nop4 148 | #define w_nop16 w_nop8 w_nop8 149 | 150 | void MeRGBLed::rgbled_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi,uint8_t *port) 151 | { 152 | uint8_t curbyte,ctr,masklo; 153 | uint8_t oldSREG = SREG; 154 | cli(); //Disables all interrupts 155 | 156 | masklo = *port & ~maskhi; 157 | maskhi = *port | maskhi; 158 | 159 | while (datlen--) { 160 | curbyte=*data++; 161 | 162 | asm volatile( 163 | " ldi %0,8 \n\t" 164 | "loop%=: \n\t" 165 | " st X,%3 \n\t" // '1' [02] '0' [02] - re 166 | #if (w1_nops&1) 167 | w_nop1 168 | #endif 169 | #if (w1_nops&2) 170 | w_nop2 171 | #endif 172 | #if (w1_nops&4) 173 | w_nop4 174 | #endif 175 | #if (w1_nops&8) 176 | w_nop8 177 | #endif 178 | #if (w1_nops&16) 179 | w_nop16 180 | #endif 181 | " sbrs %1,7 \n\t" // '1' [04] '0' [03] 182 | " st X,%4 \n\t" // '1' [--] '0' [05] - fe-low 183 | " lsl %1 \n\t" // '1' [05] '0' [06] 184 | #if (w2_nops&1) 185 | w_nop1 186 | #endif 187 | #if (w2_nops&2) 188 | w_nop2 189 | #endif 190 | #if (w2_nops&4) 191 | w_nop4 192 | #endif 193 | #if (w2_nops&8) 194 | w_nop8 195 | #endif 196 | #if (w2_nops&16) 197 | w_nop16 198 | #endif 199 | " brcc skipone%= \n\t" // '1' [+1] '0' [+2] - 200 | " st X,%4 \n\t" // '1' [+3] '0' [--] - fe-high 201 | "skipone%=: " // '1' [+3] '0' [+2] - 202 | 203 | #if (w3_nops&1) 204 | w_nop1 205 | #endif 206 | #if (w3_nops&2) 207 | w_nop2 208 | #endif 209 | #if (w3_nops&4) 210 | w_nop4 211 | #endif 212 | #if (w3_nops&8) 213 | w_nop8 214 | #endif 215 | #if (w3_nops&16) 216 | w_nop16 217 | #endif 218 | 219 | " dec %0 \n\t" // '1' [+4] '0' [+3] 220 | " brne loop%=\n\t" // '1' [+5] '0' [+4] 221 | : "=&d" (ctr) 222 | // : "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo) 223 | : "r" (curbyte), "x" (port), "r" (maskhi), "r" (masklo) 224 | ); 225 | } 226 | 227 | SREG = oldSREG; 228 | } 229 | void MeRGBLed::show() { 230 | // *ws2812_port_reg |= pinMask; // Enable DDR 231 | rgbled_sendarray_mask(pixels,3*count_led,pinMask,(uint8_t*) ws2812_port); 232 | } 233 | 234 | MeRGBLed::~MeRGBLed() { 235 | 236 | 237 | } 238 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MeRGBLed.h: -------------------------------------------------------------------------------- 1 | #ifndef MeRGBLed_h 2 | #define MeRGBLed_h 3 | #include "MePort.h" 4 | ///@brief Class for RGB Led Module(http://www.makeblock.cc/me-rgb-led-v1-0/) and Led Strip(http://www.makeblock.cc/led-rgb-strip-addressable-sealed-1m/) 5 | class MeRGBLed:public MePort { 6 | public: 7 | MeRGBLed(); 8 | MeRGBLed(uint8_t port); 9 | MeRGBLed(uint8_t port,uint8_t slot); 10 | ~MeRGBLed(); 11 | void reset(uint8_t port); 12 | ///@brief set the count of leds. 13 | void setNumber(uint8_t num_led); 14 | ///@brief get the count of leds. 15 | uint8_t getNumber(); 16 | ///@brief get the rgb value of the led with the index. 17 | cRGB getColorAt(uint8_t index); 18 | ///@brief set the rgb value of the led with the index. 19 | bool setColorAt(uint8_t index, uint8_t red,uint8_t green,uint8_t blue); 20 | bool setColorAt(uint8_t index, long value); 21 | ///@brief become effective of all led's change. 22 | void show(); 23 | 24 | private: 25 | uint16_t count_led; 26 | uint8_t *pixels; 27 | 28 | void rgbled_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask,uint8_t *port); 29 | 30 | const volatile uint8_t *ws2812_port; 31 | volatile uint8_t *ws2812_port_reg; 32 | uint8_t pinMask; 33 | }; 34 | #endif 35 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MeServo.cpp: -------------------------------------------------------------------------------- 1 | #include "MeServo.h" 2 | 3 | MeServo::MeServo() { 4 | isAttached = false; 5 | servoPin = 0; 6 | angle = 90; 7 | mTime = micros(); 8 | pinState = false; 9 | _index=0; 10 | 11 | } 12 | MeServo::MeServo(uint8_t port): MePort(port) 13 | { 14 | attach(s1); 15 | } 16 | MeServo::MeServo(uint8_t port,uint8_t slot): MePort(port,slot) 17 | { 18 | attach(slot==SLOT_1?s1:s2); 19 | } 20 | void MeServo::reset(uint8_t port,uint8_t slot){ 21 | //detach(); 22 | _port = port; 23 | _slot = slot; 24 | s2 = mePort[port].s2; 25 | s1 = mePort[port].s1; 26 | servoPin = slot==SLOT_1?s1:s2; 27 | attach(servoPin); 28 | } 29 | void MeServo::attach(int pin) { 30 | if(indexOfServo(pin)==-1&&_index<8){ 31 | pins[_index]=pin; 32 | _index++; 33 | } 34 | if(indexOfServo(pin)>-1){ 35 | isAttached = true; 36 | pinMode(pin, OUTPUT); 37 | if(!servos[indexOfServo(pin)].attached()){ 38 | servos[indexOfServo(pin)].attach(pin); 39 | } 40 | } 41 | } 42 | int MeServo::indexOfServo(int pin){ 43 | for(int i=0;i<8;i++){ 44 | if(pin==pins[i]){ 45 | return i; 46 | } 47 | } 48 | return -1; 49 | } 50 | void MeServo::detach(int pin) { 51 | isAttached = false; 52 | // pinMode(servoPin, INPUT); 53 | if(indexOfServo(pin)>-1){ 54 | pins[indexOfServo(pin)]=-1; 55 | if(servos[indexOfServo(pin)].attached()){ 56 | servos[indexOfServo(pin)].detach(); 57 | } 58 | } 59 | } 60 | 61 | boolean MeServo::attached(void) { 62 | return isAttached; 63 | } 64 | 65 | void MeServo::write(int pin,uint8_t a) { 66 | angle = a; 67 | if(indexOfServo(pin)>-1){ 68 | servos[indexOfServo(pin)].write(a); 69 | } 70 | } 71 | 72 | void MeServo::refresh(void) { 73 | // if(isAttached){ 74 | // digitalWrite(servoPin, HIGH); 75 | // delayMicroseconds(delayTime); 76 | // digitalWrite(servoPin, LOW); 77 | // } 78 | } 79 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MeServo.h: -------------------------------------------------------------------------------- 1 | #ifndef MESERVO_H_ 2 | #define MESERVO_H_ 3 | #include 4 | #include 5 | #include "MePort.h" 6 | class MeServo : public MePort{ 7 | public: 8 | MeServo(); 9 | MeServo(uint8_t port); 10 | MeServo(uint8_t port,uint8_t slot); 11 | void reset(uint8_t port,uint8_t slot); 12 | void attach(int pin); 13 | void detach(int pin); 14 | boolean attached(); 15 | void write(int pin,uint8_t a); 16 | void refresh(void); 17 | int indexOfServo(int pin); 18 | private: 19 | boolean isAttached; 20 | int angle,servoPin; 21 | uint16_t delayTime; 22 | unsigned long mTime; 23 | int pinState; 24 | int pins[8]; 25 | int _index; 26 | Servo servos[8]; 27 | }; 28 | #endif 29 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MeTemperature.h: -------------------------------------------------------------------------------- 1 | #ifndef MeTemperature_h 2 | #define MeTemperature_h 3 | #include "MePort.h" 4 | #if defined(__AVR__) 5 | #define MePIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) 6 | #define MePIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 7 | #define MeIO_REG_TYPE uint8_t 8 | #define MeIO_REG_ASM asm("r30") 9 | #define MeDIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 10 | #define MeDIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)),((*((base)+2)) |= (mask))//INPUT_PULLUP 11 | #define MeDIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) 12 | #define MeDIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) 13 | #define MeDIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) 14 | #endif 15 | class MeOneWire 16 | { 17 | private: 18 | MeIO_REG_TYPE bitmask; 19 | volatile MeIO_REG_TYPE *baseReg; 20 | // global search state 21 | unsigned char ROM_NO[8]; 22 | uint8_t LastDiscrepancy; 23 | uint8_t LastFamilyDiscrepancy; 24 | uint8_t LastDeviceFlag; 25 | public: 26 | MeOneWire(); 27 | MeOneWire( uint8_t pin); 28 | bool readIO(void); 29 | void reset(uint8_t pin); 30 | // Perform a 1-Wire reset cycle. Returns 1 if a device responds 31 | // with a presence pulse. Returns 0 if there is no device or the 32 | // bus is shorted or otherwise held low for more than 250uS 33 | uint8_t reset(void); 34 | // Issue a 1-Wire rom select command, you do the reset first. 35 | void select(const uint8_t rom[8]); 36 | // Issue a 1-Wire rom skip command, to address all on bus. 37 | void skip(void); 38 | // Write a byte. If 'power' is one then the wire is held high at 39 | // the end for parasitically powered devices. You are responsible 40 | // for eventually depowering it by calling depower() or doing 41 | // another read or write. 42 | void write(uint8_t v, uint8_t power = 0); 43 | void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); 44 | // Read a byte. 45 | uint8_t read(void); 46 | void read_bytes(uint8_t *buf, uint16_t count); 47 | // Write a bit. The bus is always left powered at the end, see 48 | // note in write() about that. 49 | void write_bit(uint8_t v); 50 | // Read a bit. 51 | uint8_t read_bit(void); 52 | // Stop forcing power onto the bus. You only need to do this if 53 | // you used the 'power' flag to write() or used a write_bit() call 54 | // and aren't about to do another read or write. You would rather 55 | // not leave this powered if you don't have to, just in case 56 | // someone shorts your bus. 57 | void depower(void); 58 | // Clear the search state so that if will start from the beginning again. 59 | void reset_search(); 60 | // Setup the search to find the device type 'family_code' on the next call 61 | // to search(*newAddr) if it is present. 62 | void target_search(uint8_t family_code); 63 | // Look for the next device. Returns 1 if a new address has been 64 | // returned. A zero might mean that the bus is shorted, there are 65 | // no devices, or you have already retrieved all of them. It 66 | // might be a good idea to check the CRC to make sure you didn't 67 | // get garbage. The order is deterministic. You will always get 68 | // the same devices in the same order. 69 | uint8_t search(uint8_t *newAddr); 70 | }; 71 | ///@brief Class for temperature sensor 72 | class MeTemperature:public MePort{ 73 | public: 74 | MeTemperature(); 75 | MeTemperature(uint8_t port); 76 | MeTemperature(uint8_t port,uint8_t slot); 77 | void reset(uint8_t port, uint8_t slot); 78 | ///@brief get the celsius of temperature 79 | float temperature(); 80 | private: 81 | MeOneWire _ts; 82 | }; 83 | #endif 84 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MeUltrasonic.cpp: -------------------------------------------------------------------------------- 1 | #include "MeUltrasonic.h" 2 | /* UltrasonicSenser */ 3 | MeUltrasonic::MeUltrasonic(): MePort(0) 4 | { 5 | } 6 | MeUltrasonic::MeUltrasonic(uint8_t port): MePort(port) 7 | { 8 | } 9 | 10 | double MeUltrasonic::distanceCm(uint16_t maxCm) 11 | { 12 | long distance = measure(maxCm * 55 + 200); 13 | return (double)distance / 58.0; 14 | } 15 | 16 | double MeUltrasonic::distanceInch(uint16_t maxInch) 17 | { 18 | long distance = measure(maxInch * 145 + 200); 19 | return (double)(distance / 148.0); 20 | } 21 | 22 | double MeUltrasonic::distanceCm(){ 23 | return distanceCm(400); 24 | } 25 | double MeUltrasonic::distanceInch(){ 26 | return distanceInch(5); 27 | } 28 | long MeUltrasonic::measure(unsigned long timeout) 29 | { 30 | long duration; 31 | MePort::dWrite2(LOW); 32 | delayMicroseconds(2); 33 | MePort::dWrite2(HIGH); 34 | delayMicroseconds(10); 35 | MePort::dWrite2(LOW); 36 | pinMode(s2, INPUT); 37 | duration = pulseIn(s2, HIGH, timeout); 38 | return duration; 39 | } 40 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MeUltrasonic.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef MEULTRASONIC_H_ 3 | #define MEULTRASONIC_H_ 4 | #include "MePort.h" 5 | ///@brief Class for Ultrasonic Sensor Module 6 | class MeUltrasonic: public MePort 7 | { 8 | public : 9 | MeUltrasonic(); 10 | MeUltrasonic(uint8_t port); 11 | double distanceCm(); 12 | double distanceInch(); 13 | double distanceCm(uint16_t maxCm); 14 | double distanceInch(uint16_t maxInch); 15 | long measure(unsigned long timeout); 16 | }; 17 | #endif 18 | -------------------------------------------------------------------------------- /Firmware_for_MeBaseShield/MeWire.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _I2CDEV_H_ 3 | #define _I2CDEV_H_ 4 | 5 | // ----------------------------------------------------------------------------- 6 | // I2C interface implementation setting 7 | // ----------------------------------------------------------------------------- 8 | //#define I2CDEV_IMPLEMENTATION I2CDEV_ARDUINO_WIRE 9 | #define I2CDEV_IMPLEMENTATION I2CDEV_BUILTIN_FASTWIRE 10 | 11 | // comment this out if you are using a non-optimal IDE/implementation setting 12 | // but want the compiler to shut up about it 13 | #define I2CDEV_IMPLEMENTATION_WARNINGS 14 | 15 | // ----------------------------------------------------------------------------- 16 | // I2C interface implementation options 17 | // ----------------------------------------------------------------------------- 18 | #define I2CDEV_ARDUINO_WIRE 1 // Wire object from Arduino 19 | #define I2CDEV_BUILTIN_NBWIRE 2 // Tweaked Wire object from Gene Knight's NBWire project 20 | // ^^^ NBWire implementation is still buggy w/some interrupts! 21 | #define I2CDEV_BUILTIN_FASTWIRE 3 // FastWire object from Francesco Ferrara's project 22 | #define I2CDEV_I2CMASTER_LIBRARY 4 // I2C object from DSSCircuits I2C-Master Library at https://github.com/DSSCircuits/I2C-Master-Library 23 | 24 | // ----------------------------------------------------------------------------- 25 | // Arduino-style "Serial.print" debug constant (uncomment to enable) 26 | // ----------------------------------------------------------------------------- 27 | //#define I2CDEV_SERIAL_DEBUG 28 | 29 | #ifdef ARDUINO 30 | #if ARDUINO < 100 31 | #include "WProgram.h" 32 | #else 33 | #include "Arduino.h" 34 | #endif 35 | #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE 36 | #include 37 | #endif 38 | #if I2CDEV_IMPLEMENTATION == I2CDEV_I2CMASTER_LIBRARY 39 | #include 40 | #endif 41 | #endif 42 | 43 | // 1000ms default read timeout (modify with "I2Cdev::readTimeout = [ms];") 44 | #define I2CDEV_DEFAULT_READ_TIMEOUT 1000 45 | 46 | class I2Cdev { 47 | public: 48 | I2Cdev(); 49 | 50 | static int8_t readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); 51 | static int8_t readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); 52 | static int8_t readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); 53 | static int8_t readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); 54 | static int8_t readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); 55 | static int8_t readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); 56 | static int8_t readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); 57 | static int8_t readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); 58 | 59 | static bool writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data); 60 | static bool writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data); 61 | static bool writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data); 62 | static bool writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data); 63 | static bool writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data); 64 | static bool writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data); 65 | static bool writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data); 66 | static bool writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data); 67 | 68 | static uint16_t readTimeout; 69 | }; 70 | 71 | ////////////////////// 72 | // FastWire 0.24 73 | // This is a library to help faster programs to read I2C devices. 74 | // Copyright(C) 2012 75 | // Francesco Ferrara 76 | ////////////////////// 77 | 78 | /* Master */ 79 | #define TW_START 0x08 80 | #define TW_REP_START 0x10 81 | 82 | /* Master Transmitter */ 83 | #define TW_MT_SLA_ACK 0x18 84 | #define TW_MT_SLA_NACK 0x20 85 | #define TW_MT_DATA_ACK 0x28 86 | #define TW_MT_DATA_NACK 0x30 87 | #define TW_MT_ARB_LOST 0x38 88 | 89 | /* Master Receiver */ 90 | #define TW_MR_ARB_LOST 0x38 91 | #define TW_MR_SLA_ACK 0x40 92 | #define TW_MR_SLA_NACK 0x48 93 | #define TW_MR_DATA_ACK 0x50 94 | #define TW_MR_DATA_NACK 0x58 95 | 96 | #define TW_OK 0 97 | #define TW_ERROR 1 98 | 99 | class Fastwire { 100 | private: 101 | static boolean waitInt(); 102 | 103 | public: 104 | static void setup(int khz, boolean pullup); 105 | static byte beginTransmission(byte device); 106 | static byte write(byte value); 107 | static byte writeBuf(byte device, byte address, byte *data, byte num); 108 | static byte readBuf(byte device, byte address, byte *data, byte num); 109 | static void reset(); 110 | static byte stop(); 111 | }; 112 | 113 | 114 | #endif /* _I2CDEV_H_ */ 115 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Makeblock-Firmware 2 | ================== 3 | -------------------------------------------------------------------------------- /firmware/Me7SegmentDisplay.cpp: -------------------------------------------------------------------------------- 1 | #include "Me7SegmentDisplay.h" 2 | static int8_t TubeTab[] = {0x3f,0x06,0x5b,0x4f, 3 | 0x66,0x6d,0x7d,0x07, 4 | 0x7f,0x6f,0x77,0x7c, 5 | 0x39,0x5e,0x79,0x71, 6 | 0xbf,0x86,0xdb,0xcf, 7 | 0xe6,0xed,0xfd,0x87, 8 | 0xff,0xef,0xf7,0xfc, 9 | 0xb9,0xde,0xf9,0xf1,0x40};//0~9,A,b,C,d,E,F,- 10 | Me7SegmentDisplay::Me7SegmentDisplay():MePort() 11 | { 12 | } 13 | Me7SegmentDisplay::Me7SegmentDisplay(uint8_t port):MePort(port) 14 | { 15 | Clkpin = s2; 16 | Datapin = s1; 17 | pinMode(Clkpin,OUTPUT); 18 | pinMode(Datapin,OUTPUT); 19 | set(); 20 | clearDisplay(); 21 | } 22 | void Me7SegmentDisplay::reset(uint8_t port){ 23 | _port = port; 24 | s2 = mePort[port].s2; 25 | s1 = mePort[port].s1; 26 | Clkpin = s2; 27 | Datapin = s1; 28 | pinMode(Clkpin,OUTPUT); 29 | pinMode(Datapin,OUTPUT); 30 | set(); 31 | //clearDisplay(); 32 | } 33 | void Me7SegmentDisplay::init(void) 34 | { 35 | clearDisplay(); 36 | } 37 | void Me7SegmentDisplay::writeByte(int8_t wr_data) 38 | { 39 | uint8_t i,count1; 40 | for(i=0;i<8;i++) //sent 8bit data 41 | { 42 | digitalWrite(Clkpin,LOW); 43 | if(wr_data & 0x01)digitalWrite(Datapin,HIGH);//LSB first 44 | else digitalWrite(Datapin,LOW); 45 | wr_data >>= 1; 46 | digitalWrite(Clkpin,HIGH); 47 | } 48 | digitalWrite(Clkpin,LOW); //wait for the ACK 49 | digitalWrite(Datapin,HIGH); 50 | digitalWrite(Clkpin,HIGH); 51 | pinMode(Datapin,INPUT); 52 | while(digitalRead(Datapin)) 53 | { 54 | count1 +=1; 55 | if(count1 == 200)// 56 | { 57 | pinMode(Datapin,OUTPUT); 58 | digitalWrite(Datapin,LOW); 59 | count1 =0; 60 | } 61 | } 62 | pinMode(Datapin,OUTPUT); 63 | } 64 | //send start signal to TM1637 65 | void Me7SegmentDisplay::start(void) 66 | { 67 | digitalWrite(Clkpin,HIGH);//send start signal to TM1637 68 | digitalWrite(Datapin,HIGH); 69 | digitalWrite(Datapin,LOW); 70 | digitalWrite(Clkpin,LOW); 71 | } 72 | //End of transmission 73 | void Me7SegmentDisplay::stop(void) 74 | { 75 | digitalWrite(Clkpin,LOW); 76 | digitalWrite(Datapin,LOW); 77 | digitalWrite(Clkpin,HIGH); 78 | digitalWrite(Datapin,HIGH); 79 | } 80 | void Me7SegmentDisplay::display(float value){ 81 | int i=0; 82 | bool isStart = false; 83 | int index = 0; 84 | int8_t disp[]={0,0,0,0}; 85 | bool isNeg = false; 86 | if(value<0){ 87 | isNeg = true; 88 | value = -value; 89 | disp[0] = 0x20; 90 | index++; 91 | } 92 | for(i=0;i<7;i++){ 93 | int n = checkNum(value,3-i); 94 | if(n>=1||i==3){ 95 | isStart=true; 96 | } 97 | if(isStart){ 98 | if(i==3){ 99 | disp[index]=n+0x10; 100 | }else{ 101 | disp[index]=n; 102 | } 103 | index++; 104 | } 105 | if(index>3){ 106 | break; 107 | } 108 | } 109 | display(disp); 110 | } 111 | int Me7SegmentDisplay::checkNum(float v,int b){ 112 | if(b>=0){ 113 | return floor((v-floor(v/pow(10,b+1))*(pow(10,b+1)))/pow(10,b)); 114 | }else{ 115 | b=-b; 116 | int i=0; 117 | for(i=0;i 255 ? 255 : speed; 13 | speed = speed < -255 ? -255 : speed; 14 | 15 | if(speed >= 0) { 16 | MePort::dWrite2(HIGH); 17 | MePort::aWrite1(speed); 18 | } else { 19 | MePort::dWrite2(LOW); 20 | MePort::aWrite1(-speed); 21 | } 22 | } 23 | void MeDCMotor::stop() 24 | { 25 | MeDCMotor::run(0); 26 | } 27 | -------------------------------------------------------------------------------- /firmware/MeDCMotor.h: -------------------------------------------------------------------------------- 1 | #ifndef MEDCMOTOR_H_ 2 | #define MEDCMOTOR_H_ 3 | #include "MePort.h" 4 | ///@brief Class for DC Motor Module 5 | class MeDCMotor: public MePort 6 | { 7 | public: 8 | MeDCMotor(); 9 | MeDCMotor(uint8_t port); 10 | void run(int speed); 11 | void stop(); 12 | }; 13 | #endif 14 | -------------------------------------------------------------------------------- /firmware/MeEncoderMotor.cpp: -------------------------------------------------------------------------------- 1 | // MeEncoderMotor.cpp 2 | 3 | #include "MeEncoderMotor.h" 4 | #include "MeHostParser.h" 5 | // frame type 6 | #define ENCODER_MOTOR_GET_PARAM 0x01 7 | #define ENCODER_MOTOR_SAVE_PARAM 0x02 8 | #define ENCODER_MOTOR_TEST_PARAM 0x03 9 | #define ENCODER_MOTOR_SHOW_PARAM 0x04 10 | #define ENCODER_MOTOR_RUN_STOP 0x05 11 | #define ENCODER_MOTOR_GET_DIFF_POS 0x06 12 | #define ENCODER_MOTOR_RESET 0x07 13 | #define ENCODER_MOTOR_SPEED_TIME 0x08 14 | #define ENCODER_MOTOR_GET_SPEED 0x09 15 | #define ENCODER_MOTOR_GET_POS 0x10 16 | #define ENCODER_MOTOR_MOVE 0x11 17 | #define ENCODER_MOTOR_MOVE_TO 0x12 18 | #define ENCODER_MOTOR_DEBUG_STR 0xCC 19 | #define ENCODER_MOTOR_ACKNOWLEDGE 0xFF 20 | 21 | MeHostParser encoderParser = MeHostParser(); 22 | 23 | // function: pack data into a package to send 24 | // param: buf buffer to save package 25 | // bufSize size of buf 26 | // module the associated module of package 27 | // data the data to pack 28 | // length the length(size) of data 29 | // return: 0 error 30 | // other package size 31 | uint32_t MeHost_Pack(uint8_t * buf, 32 | uint32_t bufSize, 33 | uint8_t module, 34 | uint8_t * data, 35 | uint32_t length) 36 | { 37 | uint32_t i = 0; 38 | 39 | // head: 0xA5 40 | buf[i++] = 0xA5; 41 | buf[i++] = module; 42 | // pack length 43 | buf[i++] = *((uint8_t *)&length + 0); 44 | buf[i++] = *((uint8_t *)&length + 1); 45 | buf[i++] = *((uint8_t *)&length + 2); 46 | buf[i++] = *((uint8_t *)&length + 3); 47 | // pack data 48 | for(uint32_t j = 0; j < length; ++j) 49 | { 50 | buf[i++] = data[j]; 51 | } 52 | 53 | // calculate the LRC 54 | uint8_t check = 0x00; 55 | for(uint32_t j = 0; j < length; ++j) 56 | { 57 | check ^= data[j]; 58 | } 59 | buf[i++] = check; 60 | 61 | // tail: 0x5A 62 | buf[i++] = 0x5A; 63 | 64 | if (i > bufSize) 65 | { 66 | return 0; 67 | } 68 | else 69 | { 70 | return i; 71 | } 72 | } 73 | 74 | /* EncoderMotor */ 75 | MeEncoderMotor::MeEncoderMotor(uint8_t addr,uint8_t slot):MeWire(addr - 1) 76 | { 77 | _slot = slot - 1; 78 | } 79 | MeEncoderMotor::MeEncoderMotor(uint8_t slot):MeWire(0x8) 80 | { 81 | _slot = slot - 1; 82 | } 83 | MeEncoderMotor::MeEncoderMotor():MeWire(0x8){ 84 | _slot = 0; 85 | } 86 | void MeEncoderMotor::begin() 87 | { 88 | MeWire::begin(); 89 | reset(); 90 | } 91 | 92 | boolean MeEncoderMotor::reset() 93 | { 94 | uint8_t w[10] = {0}; 95 | uint8_t r[10] = {0}; 96 | 97 | uint8_t data[2] = {0}; 98 | data[0] = _slot; 99 | data[1] = ENCODER_MOTOR_RESET; 100 | 101 | MeHost_Pack(w, 10, 0x01, data, 2); 102 | request(w, r, 10, 10); 103 | encoderParser.pushStr(r, 10); 104 | 105 | uint8_t ack[2] = {0}; 106 | encoderParser.getData(ack, 2); 107 | return ack[1]; 108 | } 109 | 110 | boolean MeEncoderMotor::moveTo(float angle, float speed) 111 | { 112 | uint8_t w[18] = {0}; 113 | uint8_t r[10] = {0}; 114 | 115 | uint8_t data[10] = {0}; 116 | data[0] = _slot; 117 | data[1] = ENCODER_MOTOR_MOVE_TO; 118 | *((float *)(data + 2)) = angle; 119 | *((float *)(data + 6)) = speed; 120 | 121 | MeHost_Pack(w, 18, 0x01, data, 10); 122 | request(w, r, 18, 10); 123 | encoderParser.pushStr(r, 10); 124 | encoderParser.run(); 125 | 126 | uint8_t ack[2] = {0}; 127 | encoderParser.getData(ack, 2); 128 | return ack[1]; 129 | } 130 | 131 | boolean MeEncoderMotor::move(float angle, float speed) 132 | { 133 | if(angle==0){ 134 | return runSpeed(speed); 135 | } 136 | uint8_t w[18] = {0}; 137 | uint8_t r[10] = {0}; 138 | 139 | uint8_t data[10] = {0}; 140 | data[0] = _slot; 141 | data[1] = ENCODER_MOTOR_MOVE; 142 | *((float *)(data + 2)) = angle; 143 | *((float *)(data + 6)) = speed; 144 | 145 | MeHost_Pack(w, 18, 0x01, data, 10); 146 | request(w, r, 18, 10); 147 | encoderParser.pushStr(r, 10); 148 | encoderParser.run(); 149 | 150 | uint8_t ack[2] = {0}; 151 | encoderParser.getData(ack, 2); 152 | return ack[1]; 153 | } 154 | 155 | boolean MeEncoderMotor::runTurns(float turns, float speed) 156 | { 157 | return move(turns * 360, speed); 158 | } 159 | 160 | boolean MeEncoderMotor::runSpeed(float speed) 161 | { 162 | uint8_t w[14] = {0}; 163 | uint8_t r[10] = {0}; 164 | 165 | uint8_t data[6] = {0}; 166 | data[0] = _slot; 167 | data[1] = ENCODER_MOTOR_RUN_STOP; 168 | *((float *)(data + 2)) = speed; 169 | 170 | MeHost_Pack(w, 14, 0x01, data, 6); 171 | request(w, r, 14, 10); 172 | encoderParser.pushStr(r, 10); 173 | encoderParser.run(); 174 | 175 | // uint8_t ack[2] = {0}; 176 | // encoderParser.GetData(ack, 2); 177 | // return ack[1]; 178 | return 0; 179 | } 180 | 181 | boolean MeEncoderMotor::runSpeedAndTime(float speed, float time) 182 | { 183 | uint8_t w[18] = {0}; 184 | uint8_t r[10] = {0}; 185 | 186 | uint8_t data[10] = {0}; 187 | data[0] = _slot; 188 | data[1] = ENCODER_MOTOR_SPEED_TIME; 189 | *((float *)(data + 2)) = speed; 190 | *((float *)(data + 6)) = time; 191 | 192 | MeHost_Pack(w, 18, 0x01, data, 10); 193 | request(w, r, 18, 10); 194 | encoderParser.pushStr(r, 10); 195 | encoderParser.run(); 196 | 197 | // uint8_t ack[2] = {0}; 198 | // encoderParser.GetData(ack, 2); 199 | // return ack[1]; 200 | return 0; 201 | } 202 | 203 | float MeEncoderMotor::getCurrentSpeed() 204 | { 205 | uint8_t w[10] = {0}; 206 | uint8_t r[14] = {0}; 207 | 208 | uint8_t data[2] = {0}; 209 | data[0] = _slot; 210 | data[1] = ENCODER_MOTOR_GET_SPEED; 211 | 212 | MeHost_Pack(w, 10, 0x01, data, 2); 213 | request(w, r, 10, 14); 214 | encoderParser.pushStr(r, 14); 215 | encoderParser.run(); 216 | 217 | uint8_t temp[6] = {0}; 218 | encoderParser.getData(temp, 6); 219 | float speed = *((float *)(temp + 2)); 220 | return speed; 221 | } 222 | 223 | float MeEncoderMotor::getCurrentPosition() 224 | { 225 | uint8_t w[10] = {0}; 226 | uint8_t r[14] = {0}; 227 | 228 | uint8_t data[2] = {0}; 229 | data[0] = _slot; 230 | data[1] = ENCODER_MOTOR_GET_POS; 231 | 232 | MeHost_Pack(w, 10, 0x01, data, 2); 233 | request(w, r, 10, 14); 234 | encoderParser.pushStr(r, 14); 235 | 236 | encoderParser.run(); 237 | 238 | uint8_t temp[6] = {0}; 239 | uint8_t size = encoderParser.getData(temp, 6); 240 | float pos = *((float *)(temp + 2)); 241 | return pos; 242 | } 243 | -------------------------------------------------------------------------------- /firmware/MeEncoderMotor.h: -------------------------------------------------------------------------------- 1 | #ifndef MeEncoderMotor_h 2 | #define MeEncoderMotor_h 3 | #include "MeWire.h" 4 | 5 | 6 | ///@brief Class for Encoder Motor Driver 7 | class MeEncoderMotor:public MeWire{ 8 | public: 9 | MeEncoderMotor(uint8_t addr,uint8_t slot); 10 | MeEncoderMotor(uint8_t slot); 11 | MeEncoderMotor(); 12 | void begin(); 13 | boolean reset(); 14 | boolean move(float angle, float speed); 15 | boolean moveTo(float angle, float speed); 16 | boolean runTurns(float turns, float speed); 17 | boolean runSpeed(float speed); 18 | boolean runSpeedAndTime(float speed, float time); 19 | float getCurrentSpeed(); 20 | float getCurrentPosition(); 21 | private: 22 | uint8_t _slot; 23 | }; 24 | #endif 25 | -------------------------------------------------------------------------------- /firmware/MeGyro.cpp: -------------------------------------------------------------------------------- 1 | #include "MeGyro.h" 2 | static uint8_t buffers[14]; 3 | static float angleX=0; 4 | static float angleY=0; 5 | static float angleZ=0; 6 | MeGyro::MeGyro(){ 7 | 8 | } 9 | void MeGyro::begin(){ 10 | gSensitivity = 65.5; // for 500 deg/s, check data sheet 11 | gx = 0; 12 | gy = 0; 13 | gz = 0; 14 | gyrX = 0; 15 | gyrY = 0; 16 | gyrZ = 0; 17 | accX = 0; 18 | accY = 0; 19 | accZ = 0; 20 | gyrXoffs = -281.00; 21 | gyrYoffs = 18.00; 22 | gyrZoffs = -83.00; 23 | FREQ=30.0; 24 | Wire.begin(); 25 | 26 | } 27 | int MeGyro::start(){ 28 | 29 | int error = writeReg (0x6b, 0x00); 30 | error += writeReg (0x1a, 0x01); 31 | error += writeReg(0x1b, 0x08); 32 | uint8_t sample_div = 1000 / FREQ - 1; 33 | error +=writeReg (0x19, sample_div); 34 | return error; 35 | } 36 | double MeGyro::getAngleX(){ 37 | if(accZ==0)return 0; 38 | return (atan((float)accX/(float)accZ))*180/3.1415926; 39 | } 40 | double MeGyro::getAngleY(){ 41 | if(accZ==0)return 0; 42 | return (atan((float)accY/(float)accZ))*180/3.1415926; 43 | } 44 | double MeGyro::getAngleZ(){ 45 | if(gyrZ==0)return 0; 46 | return gyrZ/10.0; 47 | } 48 | void MeGyro::close(){ 49 | } 50 | void MeGyro::update(){ 51 | unsigned long start_time = millis(); 52 | uint8_t error; 53 | // read imu data 54 | if(start()!=0){ 55 | return; 56 | } 57 | error = readData(0x3b, i2cData, 14); 58 | if(error!=0){ 59 | 60 | return; 61 | } 62 | 63 | double ax, ay, az; 64 | // assemble 16 bit sensor data 65 | accX = ((i2cData[0] << 8) | i2cData[1]); 66 | accY = ((i2cData[2] << 8) | i2cData[3]); 67 | accZ = ((i2cData[4] << 8) | i2cData[5]); 68 | 69 | gyrX = (((i2cData[8] << 8) | i2cData[9]) - gyrXoffs) / gSensitivity; 70 | gyrY = (((i2cData[10] << 8) | i2cData[11]) - gyrYoffs) / gSensitivity; 71 | gyrZ = (((i2cData[12] << 8) | i2cData[13]) - gyrZoffs) / (gSensitivity+1); 72 | ay = atan2(accX, sqrt( pow(accY, 2) + pow(accZ, 2))) * 180 / M_PI; 73 | ax = atan2(accY, sqrt( pow(accX, 2) + pow(accZ, 2))) * 180 / M_PI; 74 | 75 | // angles based on gyro (deg/s) 76 | gx = gx + gyrX / FREQ; 77 | gy = gy - gyrY / FREQ; 78 | gz += gyrZ / FREQ; 79 | 80 | // complementary filter 81 | // tau = DT*(A)/(1-A) 82 | // = 0.48sec 83 | gx = gx * 0.96 + ax * 0.04; 84 | gy = gy * 0.96 + ay * 0.04; 85 | 86 | //delay(((1/FREQ) * 1000) - (millis() - start_time)-time); 87 | } 88 | int MeGyro::readData(int start, uint8_t *buffer, int size) 89 | { 90 | int i, n, error; 91 | Wire.beginTransmission(0x68); 92 | n = Wire.write(start); 93 | if (n != 1) 94 | return (-10); 95 | n = Wire.endTransmission(false); // hold the I2C-bus 96 | if (n != 0) 97 | return (n); 98 | delayMicroseconds(1); 99 | // Third parameter is true: relase I2C-bus after data is read. 100 | Wire.requestFrom(0x68, size, true); 101 | i = 0; 102 | while(Wire.available() && i 4 | #include 5 | class MeGyro{ 6 | public: 7 | MeGyro(); 8 | void begin(); 9 | void update(); 10 | double getAngleX(); 11 | double getAngleY(); 12 | double getAngleZ(); 13 | void close(); 14 | private: 15 | int readData(int start, uint8_t *buffer, int size); 16 | int writeData(int start, const uint8_t *pData, int size); 17 | int writeReg(int reg, uint8_t data); 18 | int start(); 19 | double gSensitivity; // for 500 deg/s, check data sheet 20 | double gx, gy, gz; 21 | double gyrX, gyrY, gyrZ; 22 | int16_t accX, accY, accZ; 23 | double gyrXoffs, gyrYoffs, gyrZoffs; 24 | double FREQ; 25 | uint8_t i2cData[14]; 26 | }; 27 | #endif 28 | -------------------------------------------------------------------------------- /firmware/MeHostParser.cpp: -------------------------------------------------------------------------------- 1 | // MeHostParser.cpp 2 | 3 | #include "MeHostParser.h" 4 | 5 | #define HEAD 0xA5 6 | #define TAIL 0x5A 7 | 8 | // states 9 | #define ST_WAIT_4_START 0x01 10 | #define ST_HEAD_READ 0x02 11 | #define ST_MODULE_READ 0x03 12 | #define ST_LENGTH_READ 0x04 13 | #define ST_DATA_READ 0x05 14 | #define ST_CHECK_READ 0x06 15 | 16 | MeHostParser::MeHostParser() 17 | { 18 | state = ST_WAIT_4_START; 19 | in = 0; 20 | out = 0; 21 | packageReady = 0; 22 | 23 | module = 0; 24 | length = 0; 25 | data = NULL; 26 | check = 0; 27 | 28 | lengthRead = 0; 29 | currentDataPos = 0; 30 | } 31 | 32 | MeHostParser::~MeHostParser() 33 | { 34 | ; 35 | } 36 | 37 | uint8_t MeHostParser::getPackageReady() 38 | { 39 | return (1 == packageReady); 40 | } 41 | 42 | uint8_t MeHostParser::pushStr(uint8_t * str, uint32_t length) 43 | { 44 | if (length > ((in + BUF_SIZE - out - 1) & MASK)) 45 | { 46 | return 0; 47 | } 48 | else 49 | { 50 | for (int i = 0; i < length; ++i) 51 | { 52 | pushByte(str[i]); 53 | } 54 | } 55 | } 56 | 57 | uint8_t MeHostParser::pushByte(uint8_t ch) 58 | { 59 | if (((in + 1) & MASK) != out) 60 | { 61 | buffer[in] = ch; 62 | ++in; 63 | in &= MASK; 64 | return 1; 65 | } 66 | else 67 | { 68 | return 0; 69 | } 70 | } 71 | 72 | uint8_t MeHostParser::getByte(uint8_t * ch) 73 | { 74 | if (in != out) 75 | { 76 | *ch = buffer[out]; 77 | ++out; 78 | out &= MASK; 79 | return 1; 80 | } 81 | else 82 | { 83 | // Serial.println("GET error!"); 84 | return 0; 85 | } 86 | } 87 | 88 | uint8_t calculateLRC(uint8_t *data, uint32_t length) 89 | { 90 | uint8_t LRC = 0; 91 | for (uint32_t i = 0; i < length; ++i) 92 | { 93 | LRC ^= data[i]; 94 | } 95 | return LRC; 96 | } 97 | 98 | uint8_t MeHostParser::run(void) 99 | { 100 | uint8_t ch = 0; 101 | while (getByte(&ch)) 102 | { 103 | switch (state) 104 | { 105 | case ST_WAIT_4_START: 106 | if (HEAD == ch) 107 | { 108 | state = ST_HEAD_READ; 109 | } 110 | break; 111 | case ST_HEAD_READ: 112 | module = ch; 113 | state = ST_MODULE_READ; 114 | break; 115 | case ST_MODULE_READ: 116 | // read 4 bytes as "length" 117 | *(((uint8_t *)&length) + lengthRead) = ch; 118 | ++lengthRead; 119 | if (4 == lengthRead) 120 | { 121 | lengthRead = 0; 122 | state = ST_LENGTH_READ; 123 | } 124 | break; 125 | case ST_LENGTH_READ: 126 | // alloc space for data 127 | if (0 == currentDataPos) 128 | { 129 | if (length > 255) 130 | { 131 | state = ST_WAIT_4_START; 132 | currentDataPos = 0; 133 | lengthRead = 0; 134 | length = 0; 135 | module = 0; 136 | check = 0; 137 | break; 138 | } 139 | data = (uint8_t *)malloc(length + 1); 140 | if (NULL == data) 141 | { 142 | state = ST_WAIT_4_START; 143 | currentDataPos = 0; 144 | lengthRead = 0; 145 | length = 0; 146 | module = 0; 147 | check = 0; 148 | break; 149 | } 150 | } 151 | // read data 152 | data[currentDataPos] = ch; 153 | ++currentDataPos; 154 | if (currentDataPos == length) 155 | { 156 | currentDataPos = 0; 157 | state = ST_DATA_READ; 158 | } 159 | break; 160 | case ST_DATA_READ: 161 | check = ch; 162 | if (check != calculateLRC(data, length)) 163 | { 164 | state = ST_WAIT_4_START; 165 | if (NULL != data) 166 | { 167 | free(data); 168 | data = NULL; 169 | } 170 | currentDataPos = 0; 171 | lengthRead = 0; 172 | length = 0; 173 | module = 0; 174 | check = 0; 175 | } 176 | else 177 | { 178 | state = ST_CHECK_READ; 179 | } 180 | break; 181 | case ST_CHECK_READ: 182 | if (TAIL != ch) 183 | { 184 | if (NULL != data) 185 | { 186 | free(data); 187 | data = NULL; 188 | } 189 | length = 0; 190 | } 191 | else 192 | { 193 | packageReady = 1; 194 | } 195 | state = ST_WAIT_4_START; 196 | currentDataPos = 0; 197 | lengthRead = 0; 198 | module = 0; 199 | check = 0; 200 | break; 201 | default: 202 | break; 203 | } 204 | } 205 | return state; 206 | } 207 | 208 | 209 | 210 | uint8_t MeHostParser::getData(uint8_t *buf, uint32_t size) 211 | { 212 | int copySize = (size > length) ? length : size; 213 | if ((NULL != data) && (NULL != buf)) 214 | { 215 | memcpy(buf, data, copySize); 216 | free(data); 217 | data = NULL; 218 | length = 0; 219 | packageReady = 0; 220 | 221 | return copySize; 222 | } 223 | else 224 | { 225 | return 0; 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /firmware/MeHostParser.h: -------------------------------------------------------------------------------- 1 | #ifndef MeHostParser_h 2 | #define MeHostParser_h 3 | #include 4 | #define BUF_SIZE 256 5 | #define MASK 255 6 | 7 | class MeHostParser 8 | { 9 | public: 10 | MeHostParser(); 11 | ~MeHostParser(); 12 | 13 | // push data to buffer 14 | uint8_t pushStr(uint8_t * str, uint32_t length); 15 | uint8_t pushByte(uint8_t ch); 16 | // run state machine 17 | uint8_t run(); 18 | // get the package ready state 19 | uint8_t getPackageReady(); 20 | // copy data to user's buffer 21 | uint8_t getData(uint8_t *buf, uint32_t size); 22 | 23 | void print(char *str, uint32_t * cnt); 24 | private: 25 | int state; 26 | uint8_t buffer[BUF_SIZE]; 27 | uint32_t in; 28 | uint32_t out; 29 | uint8_t packageReady; 30 | 31 | uint8_t module; 32 | uint32_t length; 33 | uint8_t *data; 34 | uint8_t check; 35 | 36 | uint32_t lengthRead; 37 | uint32_t currentDataPos; 38 | 39 | uint8_t getByte(uint8_t * ch); 40 | }; 41 | 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /firmware/MeInfraredReceiver.cpp: -------------------------------------------------------------------------------- 1 | #include "MeInfraredReceiver.h" 2 | 3 | MeInfraredReceiver::MeInfraredReceiver():MePort(){ 4 | 5 | } 6 | 7 | MeInfraredReceiver::MeInfraredReceiver(uint8_t port):MePort(port){ 8 | pinMode(s1,INPUT); 9 | pinMode(s2,INPUT); 10 | } 11 | int MeInfraredReceiver::available(){ 12 | char c = poll(); 13 | if(c>0){ 14 | _buffer = c; 15 | return 1; 16 | } 17 | return 0; 18 | } 19 | unsigned char MeInfraredReceiver::read(){ 20 | unsigned char c = _buffer; 21 | _buffer = 0; 22 | return c; 23 | } 24 | 25 | bool MeInfraredReceiver::buttonState(){ 26 | 27 | if(getPort()>0){ 28 | return dRead1()==0; 29 | } 30 | return 0; 31 | } 32 | unsigned char MeInfraredReceiver::poll() 33 | { 34 | //noInterrupts(); 35 | unsigned char val = 0; 36 | int bitDelay = 1000000.0/9600.0 - clockCyclesToMicroseconds(50); 37 | if (digitalRead(s2) == LOW) { 38 | for(int offset=0;offset<8;offset++){ 39 | delayMicroseconds(bitDelay); 40 | val |= digitalRead(s2) << offset; 41 | } 42 | delayMicroseconds(bitDelay); 43 | //interrupts(); 44 | return val&0xff; 45 | } 46 | //interrupts(); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /firmware/MeInfraredReceiver.h: -------------------------------------------------------------------------------- 1 | #ifndef MeInfraredReceiver_H_ 2 | #define MeInfraredReceiver_H_ 3 | #include "MePort.h" 4 | class MeInfraredReceiver:public MePort{ 5 | public : 6 | MeInfraredReceiver(); 7 | MeInfraredReceiver(uint8_t port); 8 | int available(); 9 | unsigned char read(); 10 | unsigned char poll(); 11 | bool buttonState(); 12 | private: 13 | unsigned char _buffer; 14 | }; 15 | #endif 16 | -------------------------------------------------------------------------------- /firmware/MePort.cpp: -------------------------------------------------------------------------------- 1 | #include "MePort.h" 2 | 3 | #if defined(__AVR_ATmega32U4__) //MeBaseBoard use ATmega32U4 as MCU 4 | 5 | MePort_Sig mePort[11] = {{NC, NC}, {11, A8}, {13, A11}, {10, 9}, {1, 0}, 6 | {MISO, SCK}, {A0, A1}, {A2, A3}, {A4, A5}, {6, 7}, {5, 4} 7 | }; 8 | #else // else ATmega328 9 | MePort_Sig mePort[11] = {{NC, NC}, {11, 10}, {3, 9}, {12, 13}, {8, 2}, 10 | {NC, NC}, {A2, A3}, {A6, A1}, {A7, A0}, {6, 7}, {5, 4} 11 | }; 12 | 13 | #endif 14 | 15 | union{ 16 | byte b[4]; 17 | float fVal; 18 | long lVal; 19 | }u; 20 | 21 | /* Port */ 22 | MePort::MePort(){ 23 | s1 = mePort[0].s1; 24 | s2 = mePort[0].s2; 25 | _port = 0; 26 | } 27 | MePort::MePort(uint8_t port) 28 | { 29 | s1 = mePort[port].s1; 30 | s2 = mePort[port].s2; 31 | _port = port; 32 | //The PWM frequency is 976 Hz 33 | #if defined(__AVR_ATmega32U4__) //MeBaseBoard use ATmega32U4 as MCU 34 | 35 | TCCR1A = _BV(WGM10); 36 | TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12); 37 | 38 | TCCR3A = _BV(WGM30); 39 | TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); 40 | 41 | TCCR4B = _BV(CS42) | _BV(CS41) | _BV(CS40); 42 | TCCR4D = 0; 43 | 44 | #else if defined(__AVR_ATmega328__) // else ATmega328 45 | 46 | TCCR1A = _BV(WGM10); 47 | TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12); 48 | 49 | TCCR2A = _BV(WGM21) |_BV(WGM20); 50 | TCCR2B = _BV(CS22); 51 | 52 | #endif 53 | } 54 | MePort::MePort(uint8_t port,uint8_t slot) 55 | { 56 | s1 = mePort[port].s1; 57 | s2 = mePort[port].s2; 58 | _port = port; 59 | _slot = slot; 60 | //The PWM frequency is 976 Hz 61 | #if defined(__AVR_ATmega32U4__) //MeBaseBoard use ATmega32U4 as MCU 62 | 63 | TCCR1A = _BV(WGM10); 64 | TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12); 65 | 66 | TCCR3A = _BV(WGM30); 67 | TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); 68 | 69 | TCCR4B = _BV(CS42) | _BV(CS41) | _BV(CS40); 70 | TCCR4D = 0; 71 | 72 | #else if defined(__AVR_ATmega328__) // else ATmega328 73 | 74 | TCCR1A = _BV(WGM10); 75 | TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12); 76 | 77 | TCCR2A = _BV(WGM21) |_BV(WGM20); 78 | TCCR2B = _BV(CS22); 79 | 80 | #endif 81 | } 82 | uint8_t MePort::getPort(){ 83 | return _port; 84 | } 85 | uint8_t MePort::getSlot(){ 86 | return _slot; 87 | } 88 | bool MePort::dRead1() 89 | { 90 | bool val; 91 | pinMode(s1, INPUT); 92 | val = digitalRead(s1); 93 | return val; 94 | } 95 | 96 | bool MePort::dRead2() 97 | { 98 | bool val; 99 | pinMode(s2, INPUT); 100 | val = digitalRead(s2); 101 | return val; 102 | } 103 | 104 | void MePort::dWrite1(bool value) 105 | { 106 | pinMode(s1, OUTPUT); 107 | digitalWrite(s1, value); 108 | } 109 | 110 | void MePort::dWrite2(bool value) 111 | { 112 | pinMode(s2, OUTPUT); 113 | digitalWrite(s2, value); 114 | } 115 | 116 | int MePort::aRead1() 117 | { 118 | int val; 119 | val = analogRead(s1); 120 | return val; 121 | } 122 | 123 | int MePort::aRead2() 124 | { 125 | int val; 126 | val = analogRead(s2); 127 | return val; 128 | } 129 | 130 | void MePort::aWrite1(int value) 131 | { 132 | analogWrite(s1, value); 133 | } 134 | 135 | void MePort::aWrite2(int value) 136 | { 137 | analogWrite(s2, value); 138 | } 139 | void MePort::reset(uint8_t port){ 140 | s1 = mePort[port].s1; 141 | s2 = mePort[port].s2; 142 | _port = port; 143 | } 144 | void MePort::reset(uint8_t port,uint8_t slot){ 145 | s1 = mePort[port].s1; 146 | s2 = mePort[port].s2; 147 | _port = port; 148 | _slot = slot; 149 | } 150 | uint8_t MePort::pin1(){ 151 | return s1; 152 | } 153 | uint8_t MePort::pin2(){ 154 | return s2; 155 | } 156 | 157 | uint8_t MePort::pin(){ 158 | return _slot==SLOT_1?s1:s2; 159 | } 160 | uint8_t MePort::pin(uint8_t port,uint8_t slot){ 161 | return slot==SLOT_1?mePort[port].s1:mePort[port].s2; 162 | } 163 | -------------------------------------------------------------------------------- /firmware/MePort.h: -------------------------------------------------------------------------------- 1 | #ifndef MEPORT_H_ 2 | #define MEPORT_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #ifndef F_CPU 8 | #define F_CPU 16000000UL 9 | #endif 10 | #include 11 | #include 12 | #include 13 | 14 | typedef struct 15 | { 16 | uint8_t s1; 17 | uint8_t s2; 18 | } MePort_Sig; 19 | extern MePort_Sig mePort[11];//mePort[0] is nonsense 20 | 21 | struct cRGB { uint8_t g; uint8_t r; uint8_t b; }; 22 | 23 | #define NC -1 24 | 25 | #define PORT_1 0x01 26 | #define PORT_2 0x02 27 | #define PORT_3 0x03 28 | #define PORT_4 0x04 29 | #define PORT_5 0x05 30 | #define PORT_6 0x06 31 | #define PORT_7 0x07 32 | #define PORT_8 0x08 33 | #define M1 0x09 34 | #define M2 0x0a 35 | 36 | #if defined(__AVR_ATmega32U4__) 37 | // buzzer 38 | #define buzzerOn() DDRE |= 0x04,PORTE |= B00000100 39 | #define buzzerOff() DDRE |= 0x04,PORTE &= B11111011 40 | #else 41 | #define buzzerOn() DDRC |= 0x20,PORTC |= B00100000; 42 | #define buzzerOff() DDRC |= 0x20,PORTC &= B11011111; 43 | #endif 44 | #define SLOT_1 1 45 | #define SLOT_2 2 46 | 47 | 48 | #define FALSE 0 49 | #define TRUE 1 50 | 51 | // Platform specific I/O definitions 52 | 53 | #if defined(__AVR__) 54 | #define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) 55 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 56 | #define IO_REG_TYPE uint8_t 57 | #define IO_REG_ASM asm("r30") 58 | #define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 59 | #define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)) 60 | #define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) 61 | #define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) 62 | #define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) 63 | #endif 64 | 65 | 66 | ///@brief class of MePort,it contains two pin. 67 | class MePort 68 | { 69 | public: 70 | MePort(); 71 | ///@brief initialize the Port 72 | ///@param port port number of device 73 | MePort(uint8_t port); 74 | MePort(uint8_t port,uint8_t slot); 75 | ///@return the level of pin 1 of port 76 | ///@retval true on HIGH. 77 | ///@retval false on LOW. 78 | uint8_t getPort(); 79 | uint8_t getSlot(); 80 | ///@return the level of pin 1 of port 81 | ///@retval true on HIGH. 82 | ///@retval false on LOW. 83 | bool dRead1(); 84 | ///@return the level of pin 2 of port 85 | ///@retval true on HIGH. 86 | ///@retval false on LOW. 87 | bool dRead2(); 88 | ///@brief set the analog value of pin 1 of port 89 | ///@param value is HIGH or LOW 90 | void dWrite1(bool value); 91 | ///@brief set the level of pin 1 of port 92 | ///@param value is HIGH or LOW 93 | void dWrite2(bool value); 94 | ///@return the analog signal of pin 1 of port between 0 to 1023 95 | int aRead1(); 96 | ///@return the analog signal of pin 2 of port between 0 to 1023 97 | int aRead2(); 98 | ///@brief set the PWM outpu value of pin 1 of port 99 | ///@param value between 0 to 255 100 | void aWrite1(int value); 101 | ///@brief set the PWM outpu value of pin 2 of port 102 | ///@param value between 0 to 255 103 | void aWrite2(int value); 104 | void reset(uint8_t port); 105 | void reset(uint8_t port,uint8_t slot); 106 | uint8_t pin1(); 107 | uint8_t pin2(); 108 | uint8_t pin(); 109 | uint8_t pin(uint8_t port,uint8_t slot); 110 | protected: 111 | uint8_t s1; 112 | uint8_t s2; 113 | uint8_t _port; 114 | uint8_t _slot; 115 | }; 116 | #endif 117 | -------------------------------------------------------------------------------- /firmware/MeRGBLed.cpp: -------------------------------------------------------------------------------- 1 | #include "MeRGBLed.h" 2 | MeRGBLed::MeRGBLed():MePort(0) { 3 | setNumber(16); 4 | } 5 | MeRGBLed::MeRGBLed(uint8_t port):MePort(port) { 6 | pinMask = digitalPinToBitMask(s2); 7 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 8 | ws2812_port_reg = portModeRegister(digitalPinToPort(s2)); 9 | // *ws2812_port_reg |= pinMask; //set pinMode OUTPUT 10 | pinMode(s2,OUTPUT); 11 | setNumber(16); 12 | } 13 | MeRGBLed::MeRGBLed(uint8_t port,uint8_t slot):MePort(port){ 14 | if(slot==1){ 15 | pinMask = digitalPinToBitMask(s2); 16 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 17 | ws2812_port_reg = portModeRegister(digitalPinToPort(s2)); 18 | pinMode(s2,OUTPUT); 19 | }else{ 20 | pinMask = digitalPinToBitMask(s1); 21 | ws2812_port = portOutputRegister(digitalPinToPort(s1)); 22 | ws2812_port_reg = portModeRegister(digitalPinToPort(s1)); 23 | pinMode(s1,OUTPUT); 24 | } 25 | //*ws2812_port_reg |= pinMask; // set pinMode OUTPUT 26 | setNumber(16); 27 | } 28 | void MeRGBLed::reset(uint8_t port){ 29 | _port = port; 30 | s2 = mePort[port].s2; 31 | s1 = mePort[port].s1; 32 | pinMask = digitalPinToBitMask(s2); 33 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 34 | ws2812_port_reg = portModeRegister(digitalPinToPort(s2)); 35 | //*ws2812_port_reg |= pinMask; 36 | pinMode(s2,OUTPUT); 37 | } 38 | void MeRGBLed::reset(uint8_t port,uint8_t slot){ 39 | _port = port; 40 | _slot = slot; 41 | s2 = slot==1?mePort[port].s2:mePort[port].s1; 42 | s1 = slot==1?mePort[port].s1:mePort[port].s2; 43 | pinMask = digitalPinToBitMask(s2); 44 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 45 | ws2812_port_reg = portModeRegister(digitalPinToPort(s2)); 46 | //*ws2812_port_reg |= pinMask; 47 | pinMode(s2,OUTPUT); 48 | } 49 | void MeRGBLed::setNumber(uint8_t num_leds){ 50 | count_led = num_leds; 51 | pixels = (uint8_t*)malloc(count_led*3); 52 | for(int i=0;i>16; 98 | uint8_t green = (value&0xff00)>>8; 99 | uint8_t blue = value&0xff; 100 | pixels[tmp] = green; 101 | pixels[tmp+1] = red; 102 | pixels[tmp+2] = blue; 103 | return true; 104 | } 105 | return false; 106 | } 107 | /* 108 | This routine writes an array of bytes with RGB values to the Dataout pin 109 | using the fast 800kHz clockless WS2811/2812 protocol. 110 | */ 111 | 112 | // Timing in ns 113 | #define w_zeropulse 350 114 | #define w_onepulse 900 115 | #define w_totalperiod 1250 116 | 117 | // Fixed cycles used by the inner loop 118 | #define w_fixedlow 3 119 | #define w_fixedhigh 6 120 | #define w_fixedtotal 10 121 | 122 | // Insert NOPs to match the timing, if possible 123 | #define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000) 124 | #define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000) 125 | #define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000) 126 | 127 | // w1 - nops between rising edge and falling edge - low 128 | #define w1 (w_zerocycles-w_fixedlow) 129 | // w2 nops between fe low and fe high 130 | #define w2 (w_onecycles-w_fixedhigh-w1) 131 | // w3 nops to complete loop 132 | #define w3 (w_totalcycles-w_fixedtotal-w1-w2) 133 | 134 | #if w1>0 135 | #define w1_nops w1 136 | #else 137 | #define w1_nops 0 138 | #endif 139 | 140 | // The only critical timing parameter is the minimum pulse length of the "0" 141 | // Warn or throw error if this timing can not be met with current F_CPU settings. 142 | #define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000) 143 | #if w_lowtime>550 144 | #error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?" 145 | #elif w_lowtime>450 146 | #warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)." 147 | #warning "Please consider a higher clockspeed, if possible" 148 | #endif 149 | 150 | #if w2>0 151 | #define w2_nops w2 152 | #else 153 | #define w2_nops 0 154 | #endif 155 | 156 | #if w3>0 157 | #define w3_nops w3 158 | #else 159 | #define w3_nops 0 160 | #endif 161 | 162 | #define w_nop1 "nop \n\t" 163 | #define w_nop2 "rjmp .+0 \n\t" 164 | #define w_nop4 w_nop2 w_nop2 165 | #define w_nop8 w_nop4 w_nop4 166 | #define w_nop16 w_nop8 w_nop8 167 | 168 | void MeRGBLed::rgbled_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi,uint8_t *port) 169 | { 170 | uint8_t curbyte,ctr,masklo; 171 | uint8_t oldSREG = SREG; 172 | cli(); //Disables all interrupts 173 | 174 | masklo = *port & ~maskhi; 175 | maskhi = *port | maskhi; 176 | 177 | while (datlen--) { 178 | curbyte=*data++; 179 | 180 | asm volatile( 181 | " ldi %0,8 \n\t" 182 | "loop%=: \n\t" 183 | " st X,%3 \n\t" // '1' [02] '0' [02] - re 184 | #if (w1_nops&1) 185 | w_nop1 186 | #endif 187 | #if (w1_nops&2) 188 | w_nop2 189 | #endif 190 | #if (w1_nops&4) 191 | w_nop4 192 | #endif 193 | #if (w1_nops&8) 194 | w_nop8 195 | #endif 196 | #if (w1_nops&16) 197 | w_nop16 198 | #endif 199 | " sbrs %1,7 \n\t" // '1' [04] '0' [03] 200 | " st X,%4 \n\t" // '1' [--] '0' [05] - fe-low 201 | " lsl %1 \n\t" // '1' [05] '0' [06] 202 | #if (w2_nops&1) 203 | w_nop1 204 | #endif 205 | #if (w2_nops&2) 206 | w_nop2 207 | #endif 208 | #if (w2_nops&4) 209 | w_nop4 210 | #endif 211 | #if (w2_nops&8) 212 | w_nop8 213 | #endif 214 | #if (w2_nops&16) 215 | w_nop16 216 | #endif 217 | " brcc skipone%= \n\t" // '1' [+1] '0' [+2] - 218 | " st X,%4 \n\t" // '1' [+3] '0' [--] - fe-high 219 | "skipone%=: " // '1' [+3] '0' [+2] - 220 | 221 | #if (w3_nops&1) 222 | w_nop1 223 | #endif 224 | #if (w3_nops&2) 225 | w_nop2 226 | #endif 227 | #if (w3_nops&4) 228 | w_nop4 229 | #endif 230 | #if (w3_nops&8) 231 | w_nop8 232 | #endif 233 | #if (w3_nops&16) 234 | w_nop16 235 | #endif 236 | 237 | " dec %0 \n\t" // '1' [+4] '0' [+3] 238 | " brne loop%=\n\t" // '1' [+5] '0' [+4] 239 | : "=&d" (ctr) 240 | // : "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo) 241 | : "r" (curbyte), "x" (port), "r" (maskhi), "r" (masklo) 242 | ); 243 | } 244 | 245 | SREG = oldSREG; 246 | } 247 | void MeRGBLed::show() { 248 | // *ws2812_port_reg |= pinMask; // Enable DDR 249 | rgbled_sendarray_mask(pixels,3*count_led,pinMask,(uint8_t*) ws2812_port); 250 | } 251 | 252 | MeRGBLed::~MeRGBLed() { 253 | 254 | 255 | } 256 | -------------------------------------------------------------------------------- /firmware/MeRGBLed.h: -------------------------------------------------------------------------------- 1 | #ifndef MeRGBLed_h 2 | #define MeRGBLed_h 3 | #include "MePort.h" 4 | ///@brief Class for RGB Led Module(http://www.makeblock.cc/me-rgb-led-v1-0/) and Led Strip(http://www.makeblock.cc/led-rgb-strip-addressable-sealed-1m/) 5 | class MeRGBLed:public MePort { 6 | public: 7 | MeRGBLed(); 8 | MeRGBLed(uint8_t port); 9 | MeRGBLed(uint8_t port,uint8_t slot); 10 | ~MeRGBLed(); 11 | void reset(uint8_t port); 12 | void reset(uint8_t port,uint8_t slot); 13 | ///@brief set the count of leds. 14 | void setNumber(uint8_t num_led); 15 | ///@brief get the count of leds. 16 | uint8_t getNumber(); 17 | ///@brief get the rgb value of the led with the index. 18 | cRGB getColorAt(uint8_t index); 19 | ///@brief set the rgb value of the led with the index. 20 | bool setColorAt(uint8_t index, uint8_t red,uint8_t green,uint8_t blue); 21 | bool setColorAt(uint8_t index, long value); 22 | bool setColor(uint8_t red,uint8_t green,uint8_t blue); 23 | ///@brief become effective of all led's change. 24 | void show(); 25 | 26 | private: 27 | uint16_t count_led; 28 | uint8_t *pixels; 29 | 30 | void rgbled_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask,uint8_t *port); 31 | 32 | const volatile uint8_t *ws2812_port; 33 | volatile uint8_t *ws2812_port_reg; 34 | uint8_t pinMask; 35 | }; 36 | #endif 37 | -------------------------------------------------------------------------------- /firmware/MeServo.cpp: -------------------------------------------------------------------------------- 1 | #include "MeServo.h" 2 | 3 | MeServo::MeServo() { 4 | isAttached = false; 5 | servoPin = 0; 6 | angle = 90; 7 | mTime = micros(); 8 | pinState = false; 9 | _index=0; 10 | 11 | } 12 | MeServo::MeServo(uint8_t port): MePort(port) 13 | { 14 | attach(s1); 15 | } 16 | MeServo::MeServo(uint8_t port,uint8_t slot): MePort(port,slot) 17 | { 18 | attach(slot==SLOT_1?s1:s2); 19 | } 20 | void MeServo::reset(uint8_t port,uint8_t slot){ 21 | //detach(); 22 | _port = port; 23 | _slot = slot; 24 | s2 = mePort[port].s2; 25 | s1 = mePort[port].s1; 26 | servoPin = slot==SLOT_1?s1:s2; 27 | attach(servoPin); 28 | } 29 | void MeServo::attach(int pin) { 30 | if(indexOfServo(pin)==-1&&_index<8){ 31 | pins[_index]=pin; 32 | _index++; 33 | } 34 | if(indexOfServo(pin)>-1){ 35 | isAttached = true; 36 | pinMode(pin, OUTPUT); 37 | if(!servos[indexOfServo(pin)].attached()){ 38 | servos[indexOfServo(pin)].attach(pin); 39 | } 40 | } 41 | } 42 | int MeServo::indexOfServo(int pin){ 43 | for(int i=0;i<8;i++){ 44 | if(pin==pins[i]){ 45 | return i; 46 | } 47 | } 48 | return -1; 49 | } 50 | void MeServo::detach(int pin) { 51 | isAttached = false; 52 | // pinMode(servoPin, INPUT); 53 | if(indexOfServo(pin)>-1){ 54 | pins[indexOfServo(pin)]=-1; 55 | if(servos[indexOfServo(pin)].attached()){ 56 | servos[indexOfServo(pin)].detach(); 57 | } 58 | } 59 | } 60 | 61 | boolean MeServo::attached(void) { 62 | return isAttached; 63 | } 64 | 65 | void MeServo::write(int pin,uint8_t a) { 66 | angle = a; 67 | if(indexOfServo(pin)>-1){ 68 | servos[indexOfServo(pin)].write(a); 69 | } 70 | } 71 | 72 | void MeServo::refresh(void) { 73 | // if(isAttached){ 74 | // digitalWrite(servoPin, HIGH); 75 | // delayMicroseconds(delayTime); 76 | // digitalWrite(servoPin, LOW); 77 | // } 78 | } 79 | -------------------------------------------------------------------------------- /firmware/MeServo.h: -------------------------------------------------------------------------------- 1 | #ifndef MESERVO_H_ 2 | #define MESERVO_H_ 3 | #include 4 | #include 5 | #include "MePort.h" 6 | class MeServo : public MePort{ 7 | public: 8 | MeServo(); 9 | MeServo(uint8_t port); 10 | MeServo(uint8_t port,uint8_t slot); 11 | void reset(uint8_t port,uint8_t slot); 12 | void attach(int pin); 13 | void detach(int pin); 14 | boolean attached(); 15 | void write(int pin,uint8_t a); 16 | void refresh(void); 17 | int indexOfServo(int pin); 18 | private: 19 | boolean isAttached; 20 | int angle,servoPin; 21 | uint16_t delayTime; 22 | unsigned long mTime; 23 | int pinState; 24 | int pins[8]; 25 | int _index; 26 | Servo servos[8]; 27 | }; 28 | #endif 29 | -------------------------------------------------------------------------------- /firmware/MeStepper.cpp: -------------------------------------------------------------------------------- 1 | // MeStepper.cpp 2 | 3 | #include "MeStepper.h" 4 | 5 | void MeStepper::moveTo(long absolute) 6 | { 7 | _targetPos = absolute; 8 | computeNewSpeed(); 9 | } 10 | 11 | void MeStepper::move(long relative) 12 | { 13 | moveTo(_currentPos + relative); 14 | } 15 | 16 | boolean MeStepper::runSpeed() 17 | { 18 | unsigned long time = micros(); 19 | 20 | if (time > _lastStepTime + _stepInterval) 21 | { 22 | if (_speed > 0) 23 | { 24 | // Clockwise 25 | _currentPos += 1; 26 | } 27 | else if (_speed < 0) 28 | { 29 | // Anticlockwise 30 | _currentPos -= 1; 31 | } 32 | step(); 33 | 34 | _lastStepTime = time; 35 | return true; 36 | } 37 | else 38 | return false; 39 | } 40 | 41 | long MeStepper::distanceToGo() 42 | { 43 | return _targetPos - _currentPos; 44 | } 45 | 46 | long MeStepper::targetPosition() 47 | { 48 | return _targetPos; 49 | } 50 | 51 | long MeStepper::currentPosition() 52 | { 53 | return _currentPos; 54 | } 55 | 56 | void MeStepper::setCurrentPosition(long position) 57 | { 58 | _currentPos = position; 59 | } 60 | 61 | void MeStepper::computeNewSpeed() 62 | { 63 | setSpeed(desiredSpeed()); 64 | } 65 | 66 | float MeStepper::desiredSpeed() 67 | { 68 | long distanceTo = distanceToGo(); 69 | 70 | float requiredSpeed; 71 | if (distanceTo == 0) 72 | return 0.0; 73 | else if (distanceTo > 0) 74 | requiredSpeed = sqrt(2.0 * distanceTo * _acceleration); 75 | else 76 | requiredSpeed = -sqrt(2.0 * -distanceTo * _acceleration); 77 | 78 | if (requiredSpeed > _speed) 79 | { 80 | if (_speed == 0) 81 | requiredSpeed = sqrt(2.0 * _acceleration); 82 | else 83 | requiredSpeed = _speed + abs(_acceleration / _speed); 84 | if (requiredSpeed > _maxSpeed) 85 | requiredSpeed = _maxSpeed; 86 | } 87 | else if (requiredSpeed < _speed) 88 | { 89 | if (_speed == 0) 90 | requiredSpeed = -sqrt(2.0 * _acceleration); 91 | else 92 | requiredSpeed = _speed - abs(_acceleration / _speed); 93 | if (requiredSpeed < -_maxSpeed) 94 | requiredSpeed = -_maxSpeed; 95 | } 96 | // Serial.println(requiredSpeed); 97 | return requiredSpeed; 98 | } 99 | 100 | boolean MeStepper::run() 101 | { 102 | if (_targetPos == _currentPos) 103 | return false; 104 | 105 | if (runSpeed()) 106 | computeNewSpeed(); 107 | return true; 108 | } 109 | MeStepper::MeStepper(): MePort(0){ 110 | } 111 | MeStepper::MeStepper(uint8_t port): MePort(port) 112 | { 113 | _currentPos = 0; 114 | _targetPos = 0; 115 | _speed = 0.0; 116 | _maxSpeed = 3000.0; 117 | _acceleration = 3000.0; 118 | _stepInterval = 0; 119 | _lastStepTime = 0; 120 | _dir = 1; 121 | pinMode(s1,OUTPUT); 122 | pinMode(s2,OUTPUT); 123 | digitalWrite(s1,_dir); 124 | } 125 | void MeStepper::setMaxSpeed(float speed) 126 | { 127 | _maxSpeed = speed; 128 | computeNewSpeed(); 129 | } 130 | 131 | void MeStepper::setAcceleration(float acceleration) 132 | { 133 | _acceleration = acceleration; 134 | computeNewSpeed(); 135 | } 136 | 137 | void MeStepper::setSpeed(float speed) 138 | { 139 | _speed = speed; 140 | _stepInterval = abs(1000.0 / _speed)*1000.0; 141 | if(_speed>0){ 142 | _dir = 1; 143 | }else{ 144 | _dir = 0; 145 | } 146 | digitalWrite(s1,_dir); 147 | } 148 | 149 | float MeStepper::speed() 150 | { 151 | return _speed; 152 | } 153 | 154 | void MeStepper::step() 155 | { 156 | digitalWrite(s2, HIGH); 157 | delayMicroseconds(1); 158 | digitalWrite(s2, LOW); 159 | } 160 | 161 | // Blocks until the target position is reached 162 | void MeStepper::runToPosition() 163 | { 164 | while (run()) 165 | ; 166 | } 167 | 168 | boolean MeStepper::runSpeedToPosition() 169 | { 170 | return _targetPos!=_currentPos ? MeStepper::runSpeed() : false; 171 | } 172 | 173 | // Blocks until the new target position is reached 174 | void MeStepper::runToNewPosition(long position) 175 | { 176 | moveTo(position); 177 | runToPosition(); 178 | } 179 | 180 | -------------------------------------------------------------------------------- /firmware/MeStepper.h: -------------------------------------------------------------------------------- 1 | #ifndef MeStepper_h 2 | #define MeStepper_h 3 | #include "MePort.h" 4 | 5 | #if ARDUINO >= 100 6 | #include "Arduino.h" 7 | #else 8 | #include "WProgram.h" 9 | #include "stdlib.h" 10 | #include "wiring.h" 11 | #endif 12 | 13 | 14 | // These defs cause trouble on some versions of Arduino 15 | #undef round 16 | 17 | ///////////////////////////////////////////////////////////////////// 18 | /// \class MeStepper MeStepper.h 19 | class MeStepper:public MePort 20 | { 21 | public: 22 | MeStepper(); 23 | MeStepper(uint8_t port); 24 | 25 | void moveTo(long absolute); 26 | 27 | void move(long relative); 28 | boolean run(); 29 | boolean runSpeed(); 30 | void setMaxSpeed(float speed); 31 | void setAcceleration(float acceleration); 32 | void setSpeed(float speed); 33 | float speed(); 34 | long distanceToGo(); 35 | long targetPosition(); 36 | long currentPosition(); 37 | void setCurrentPosition(long position); 38 | void runToPosition(); 39 | boolean runSpeedToPosition(); 40 | void runToNewPosition(long position); 41 | void disableOutputs(); 42 | void enableOutputs(); 43 | 44 | protected: 45 | 46 | void computeNewSpeed(); 47 | virtual void step(); 48 | 49 | virtual float desiredSpeed(); 50 | 51 | private: 52 | uint8_t _dir; // 2 or 4 53 | uint8_t _dirPin, _stpPin; 54 | long _currentPos; // Steps 55 | long _targetPos; // Steps 56 | float _speed; // Steps per second 57 | float _maxSpeed; 58 | float _acceleration; 59 | unsigned long _stepInterval; 60 | unsigned long _lastStepTime; 61 | }; 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /firmware/MeTemperature.h: -------------------------------------------------------------------------------- 1 | #ifndef MeTemperature_h 2 | #define MeTemperature_h 3 | #include "MePort.h" 4 | #if defined(__AVR__) 5 | #define MePIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) 6 | #define MePIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 7 | #define MeIO_REG_TYPE uint8_t 8 | #define MeIO_REG_ASM asm("r30") 9 | #define MeDIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 10 | #define MeDIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)),((*((base)+2)) |= (mask))//INPUT_PULLUP 11 | #define MeDIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) 12 | #define MeDIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) 13 | #define MeDIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) 14 | #endif 15 | class MeOneWire 16 | { 17 | private: 18 | MeIO_REG_TYPE bitmask; 19 | volatile MeIO_REG_TYPE *baseReg; 20 | // global search state 21 | unsigned char ROM_NO[8]; 22 | uint8_t LastDiscrepancy; 23 | uint8_t LastFamilyDiscrepancy; 24 | uint8_t LastDeviceFlag; 25 | public: 26 | MeOneWire(); 27 | MeOneWire( uint8_t pin); 28 | bool readIO(void); 29 | void reset(uint8_t pin); 30 | // Perform a 1-Wire reset cycle. Returns 1 if a device responds 31 | // with a presence pulse. Returns 0 if there is no device or the 32 | // bus is shorted or otherwise held low for more than 250uS 33 | uint8_t reset(void); 34 | // Issue a 1-Wire rom select command, you do the reset first. 35 | void select(const uint8_t rom[8]); 36 | // Issue a 1-Wire rom skip command, to address all on bus. 37 | void skip(void); 38 | // Write a byte. If 'power' is one then the wire is held high at 39 | // the end for parasitically powered devices. You are responsible 40 | // for eventually depowering it by calling depower() or doing 41 | // another read or write. 42 | void write(uint8_t v, uint8_t power = 0); 43 | void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); 44 | // Read a byte. 45 | uint8_t read(void); 46 | void read_bytes(uint8_t *buf, uint16_t count); 47 | // Write a bit. The bus is always left powered at the end, see 48 | // note in write() about that. 49 | void write_bit(uint8_t v); 50 | // Read a bit. 51 | uint8_t read_bit(void); 52 | // Stop forcing power onto the bus. You only need to do this if 53 | // you used the 'power' flag to write() or used a write_bit() call 54 | // and aren't about to do another read or write. You would rather 55 | // not leave this powered if you don't have to, just in case 56 | // someone shorts your bus. 57 | void depower(void); 58 | // Clear the search state so that if will start from the beginning again. 59 | void reset_search(); 60 | // Setup the search to find the device type 'family_code' on the next call 61 | // to search(*newAddr) if it is present. 62 | void target_search(uint8_t family_code); 63 | // Look for the next device. Returns 1 if a new address has been 64 | // returned. A zero might mean that the bus is shorted, there are 65 | // no devices, or you have already retrieved all of them. It 66 | // might be a good idea to check the CRC to make sure you didn't 67 | // get garbage. The order is deterministic. You will always get 68 | // the same devices in the same order. 69 | uint8_t search(uint8_t *newAddr); 70 | }; 71 | ///@brief Class for temperature sensor 72 | class MeTemperature:public MePort{ 73 | public: 74 | MeTemperature(); 75 | MeTemperature(uint8_t port); 76 | MeTemperature(uint8_t port,uint8_t slot); 77 | void reset(uint8_t port, uint8_t slot); 78 | ///@brief get the celsius of temperature 79 | float temperature(); 80 | private: 81 | MeOneWire _ts; 82 | }; 83 | #endif 84 | -------------------------------------------------------------------------------- /firmware/MeUltrasonic.cpp: -------------------------------------------------------------------------------- 1 | #include "MeUltrasonic.h" 2 | /* UltrasonicSenser */ 3 | MeUltrasonic::MeUltrasonic(): MePort(0) 4 | { 5 | } 6 | MeUltrasonic::MeUltrasonic(uint8_t port): MePort(port) 7 | { 8 | } 9 | 10 | double MeUltrasonic::distanceCm(uint16_t maxCm) 11 | { 12 | long distance = measure(maxCm * 55 + 200); 13 | return (double)distance / 58.0; 14 | } 15 | 16 | double MeUltrasonic::distanceInch(uint16_t maxInch) 17 | { 18 | long distance = measure(maxInch * 145 + 200); 19 | return (double)(distance / 148.0); 20 | } 21 | 22 | double MeUltrasonic::distanceCm(){ 23 | return distanceCm(400); 24 | } 25 | double MeUltrasonic::distanceInch(){ 26 | return distanceInch(5); 27 | } 28 | long MeUltrasonic::measure(unsigned long timeout) 29 | { 30 | long duration; 31 | MePort::dWrite2(LOW); 32 | delayMicroseconds(2); 33 | MePort::dWrite2(HIGH); 34 | delayMicroseconds(10); 35 | MePort::dWrite2(LOW); 36 | pinMode(s2, INPUT); 37 | duration = pulseIn(s2, HIGH, timeout); 38 | return duration; 39 | } 40 | -------------------------------------------------------------------------------- /firmware/MeUltrasonic.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef MEULTRASONIC_H_ 3 | #define MEULTRASONIC_H_ 4 | #include "MePort.h" 5 | ///@brief Class for Ultrasonic Sensor Module 6 | class MeUltrasonic: public MePort 7 | { 8 | public : 9 | MeUltrasonic(); 10 | MeUltrasonic(uint8_t port); 11 | double distanceCm(); 12 | double distanceInch(); 13 | double distanceCm(uint16_t maxCm); 14 | double distanceInch(uint16_t maxInch); 15 | long measure(unsigned long timeout); 16 | }; 17 | #endif 18 | -------------------------------------------------------------------------------- /firmware/MeWire.cpp: -------------------------------------------------------------------------------- 1 | #include "MeWire.h" 2 | /* Wire */ 3 | MeWire::MeWire(uint8_t address): MePort() 4 | { 5 | _slaveAddress = address + 1; 6 | } 7 | MeWire::MeWire(uint8_t port, uint8_t address): MePort(port) 8 | { 9 | _slaveAddress = address + 1; 10 | } 11 | void MeWire::begin() 12 | { 13 | delay(1000); 14 | Wire.begin(); 15 | write(BEGIN_FLAG, 0x01); 16 | } 17 | bool MeWire::isRunning() 18 | { 19 | return read(BEGIN_STATE); 20 | } 21 | void MeWire::setI2CBaseAddress(uint8_t baseAddress) 22 | { 23 | byte w[2] = {0}; 24 | byte r[4] = {0}; 25 | w[0] = 0x21; 26 | w[1] = baseAddress; 27 | request(w, r, 2, 4); 28 | } 29 | 30 | byte MeWire::read(byte dataAddress) 31 | { 32 | byte *b = {0}; 33 | read(dataAddress, b, 1); 34 | return b[0]; 35 | } 36 | 37 | void MeWire::read(byte dataAddress, uint8_t *buf, int len) 38 | { 39 | byte rxByte; 40 | Wire.beginTransmission(_slaveAddress); // transmit to device 41 | Wire.write(dataAddress); // sends one byte 42 | Wire.endTransmission(); // stop transmitting 43 | delayMicroseconds(1); 44 | Wire.requestFrom(_slaveAddress, len); // request 6 bytes from slave device 45 | int index = 0; 46 | while(Wire.available()) // slave may send less than requested 47 | { 48 | rxByte = Wire.read(); // receive a byte as character 49 | buf[index] = rxByte; 50 | index++; 51 | } 52 | } 53 | 54 | void MeWire::write(byte dataAddress, byte data) 55 | { 56 | Wire.beginTransmission(_slaveAddress); // transmit to device 57 | Wire.write(dataAddress); // sends one byte 58 | Wire.endTransmission(); // stop transmitting 59 | 60 | Wire.beginTransmission(_slaveAddress); // transmit to device 61 | Wire.write(data); // sends one byte 62 | Wire.endTransmission(); // stop transmitting 63 | } 64 | void MeWire::request(byte *writeData, byte *readData, int wlen, int rlen) 65 | { 66 | 67 | uint8_t rxByte; 68 | uint8_t index = 0; 69 | 70 | Wire.beginTransmission(_slaveAddress); // transmit to device 71 | 72 | Wire.write(writeData, wlen); 73 | 74 | Wire.endTransmission(); 75 | delayMicroseconds(2); 76 | Wire.requestFrom(_slaveAddress, rlen); // request 6 bytes from slave device 77 | delayMicroseconds(2); 78 | while(Wire.available()) // slave may send less than requested 79 | { 80 | rxByte = Wire.read(); // receive a byte as character 81 | 82 | readData[index] = rxByte; 83 | index++; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /firmware/MeWire.h: -------------------------------------------------------------------------------- 1 | #ifndef MeWire_h 2 | #define MeWire_h 3 | #include 4 | #include "MePort.h" 5 | //Wire Setup 6 | #define BEGIN_FLAG 0x1E 7 | #define BEGIN_STATE 0x91 8 | ///@brief class of MeWire 9 | class MeWire: public MePort 10 | { 11 | public: 12 | MeWire(uint8_t address); 13 | ///@brief initialize 14 | ///@param port port number of device 15 | MeWire(uint8_t port, uint8_t address); 16 | ///@brief reset start index of i2c slave address. 17 | void setI2CBaseAddress(uint8_t baseAddress); 18 | bool isRunning(); 19 | ///@brief Initiate the Wire library and join the I2C bus as a master or slave. This should normally be called only once. 20 | ///@param address the 7-bit slave address (optional); if not specified, join the bus as a master. 21 | void begin(); 22 | ///@brief send one byte data request for read one byte from slave address. 23 | byte read(byte dataAddress); 24 | void read(byte dataAddress, uint8_t *buf, int len); 25 | ///@brief send one byte data request for write one byte to slave address. 26 | void write(byte dataAddress, byte data); 27 | void request(byte *writeData, byte *readData, int wlen, int rlen); 28 | protected: 29 | int _slaveAddress; 30 | }; 31 | #endif 32 | -------------------------------------------------------------------------------- /mblock_firmware/Me7SegmentDisplay.cpp: -------------------------------------------------------------------------------- 1 | #include "Me7SegmentDisplay.h" 2 | static int8_t TubeTab[] = {0x3f,0x06,0x5b,0x4f, 3 | 0x66,0x6d,0x7d,0x07, 4 | 0x7f,0x6f,0x77,0x7c, 5 | 0x39,0x5e,0x79,0x71, 6 | 0xbf,0x86,0xdb,0xcf, 7 | 0xe6,0xed,0xfd,0x87, 8 | 0xff,0xef,0xf7,0xfc, 9 | 0xb9,0xde,0xf9,0xf1,0x40};//0~9,A,b,C,d,E,F,- 10 | Me7SegmentDisplay::Me7SegmentDisplay():MePort() 11 | { 12 | } 13 | Me7SegmentDisplay::Me7SegmentDisplay(uint8_t port):MePort(port) 14 | { 15 | Clkpin = s2; 16 | Datapin = s1; 17 | pinMode(Clkpin,OUTPUT); 18 | pinMode(Datapin,OUTPUT); 19 | set(); 20 | clearDisplay(); 21 | } 22 | void Me7SegmentDisplay::reset(uint8_t port){ 23 | _port = port; 24 | s2 = mePort[port].s2; 25 | s1 = mePort[port].s1; 26 | Clkpin = s2; 27 | Datapin = s1; 28 | pinMode(Clkpin,OUTPUT); 29 | pinMode(Datapin,OUTPUT); 30 | set(); 31 | //clearDisplay(); 32 | } 33 | void Me7SegmentDisplay::init(void) 34 | { 35 | clearDisplay(); 36 | } 37 | void Me7SegmentDisplay::writeByte(int8_t wr_data) 38 | { 39 | uint8_t i,count1; 40 | for(i=0;i<8;i++) //sent 8bit data 41 | { 42 | digitalWrite(Clkpin,LOW); 43 | if(wr_data & 0x01)digitalWrite(Datapin,HIGH);//LSB first 44 | else digitalWrite(Datapin,LOW); 45 | wr_data >>= 1; 46 | digitalWrite(Clkpin,HIGH); 47 | } 48 | digitalWrite(Clkpin,LOW); //wait for the ACK 49 | digitalWrite(Datapin,HIGH); 50 | digitalWrite(Clkpin,HIGH); 51 | pinMode(Datapin,INPUT); 52 | while(digitalRead(Datapin)) 53 | { 54 | count1 +=1; 55 | if(count1 == 200)// 56 | { 57 | pinMode(Datapin,OUTPUT); 58 | digitalWrite(Datapin,LOW); 59 | count1 =0; 60 | } 61 | } 62 | pinMode(Datapin,OUTPUT); 63 | } 64 | //send start signal to TM1637 65 | void Me7SegmentDisplay::start(void) 66 | { 67 | digitalWrite(Clkpin,HIGH);//send start signal to TM1637 68 | digitalWrite(Datapin,HIGH); 69 | digitalWrite(Datapin,LOW); 70 | digitalWrite(Clkpin,LOW); 71 | } 72 | //End of transmission 73 | void Me7SegmentDisplay::stop(void) 74 | { 75 | digitalWrite(Clkpin,LOW); 76 | digitalWrite(Datapin,LOW); 77 | digitalWrite(Clkpin,HIGH); 78 | digitalWrite(Datapin,HIGH); 79 | } 80 | void Me7SegmentDisplay::display(float value){ 81 | int i=0; 82 | bool isStart = false; 83 | int index = 0; 84 | int8_t disp[]={0,0,0,0}; 85 | bool isNeg = false; 86 | if(value<0){ 87 | isNeg = true; 88 | value = -value; 89 | disp[0] = 0x20; 90 | index++; 91 | } 92 | for(i=0;i<7;i++){ 93 | int n = checkNum(value,3-i); 94 | if(n>=1||i==3){ 95 | isStart=true; 96 | } 97 | if(isStart){ 98 | if(i==3){ 99 | disp[index]=n+0x10; 100 | }else{ 101 | disp[index]=n; 102 | } 103 | index++; 104 | } 105 | if(index>3){ 106 | break; 107 | } 108 | } 109 | display(disp); 110 | } 111 | int Me7SegmentDisplay::checkNum(float v,int b){ 112 | if(b>=0){ 113 | return floor((v-floor(v/pow(10,b+1))*(pow(10,b+1)))/pow(10,b)); 114 | }else{ 115 | b=-b; 116 | int i=0; 117 | for(i=0;i 255 ? 255 : speed; 13 | speed = speed < -255 ? -255 : speed; 14 | 15 | if(speed >= 0) { 16 | MePort::dWrite2(HIGH); 17 | MePort::aWrite1(speed); 18 | } else { 19 | MePort::dWrite2(LOW); 20 | MePort::aWrite1(-speed); 21 | } 22 | } 23 | void MeDCMotor::stop() 24 | { 25 | MeDCMotor::run(0); 26 | } 27 | -------------------------------------------------------------------------------- /mblock_firmware/MeDCMotor.h: -------------------------------------------------------------------------------- 1 | #ifndef MEDCMOTOR_H_ 2 | #define MEDCMOTOR_H_ 3 | #include "MePort.h" 4 | ///@brief Class for DC Motor Module 5 | class MeDCMotor: public MePort 6 | { 7 | public: 8 | MeDCMotor(); 9 | MeDCMotor(uint8_t port); 10 | void run(int speed); 11 | void stop(); 12 | }; 13 | #endif 14 | -------------------------------------------------------------------------------- /mblock_firmware/MeEncoderMotor.cpp: -------------------------------------------------------------------------------- 1 | // MeEncoderMotor.cpp 2 | 3 | #include "MeEncoderMotor.h" 4 | #include "MeHostParser.h" 5 | // frame type 6 | #define ENCODER_MOTOR_GET_PARAM 0x01 7 | #define ENCODER_MOTOR_SAVE_PARAM 0x02 8 | #define ENCODER_MOTOR_TEST_PARAM 0x03 9 | #define ENCODER_MOTOR_SHOW_PARAM 0x04 10 | #define ENCODER_MOTOR_RUN_STOP 0x05 11 | #define ENCODER_MOTOR_GET_DIFF_POS 0x06 12 | #define ENCODER_MOTOR_RESET 0x07 13 | #define ENCODER_MOTOR_SPEED_TIME 0x08 14 | #define ENCODER_MOTOR_GET_SPEED 0x09 15 | #define ENCODER_MOTOR_GET_POS 0x10 16 | #define ENCODER_MOTOR_MOVE 0x11 17 | #define ENCODER_MOTOR_MOVE_TO 0x12 18 | #define ENCODER_MOTOR_DEBUG_STR 0xCC 19 | #define ENCODER_MOTOR_ACKNOWLEDGE 0xFF 20 | 21 | MeHostParser encoderParser = MeHostParser(); 22 | 23 | // function: pack data into a package to send 24 | // param: buf buffer to save package 25 | // bufSize size of buf 26 | // module the associated module of package 27 | // data the data to pack 28 | // length the length(size) of data 29 | // return: 0 error 30 | // other package size 31 | uint32_t MeHost_Pack(uint8_t * buf, 32 | uint32_t bufSize, 33 | uint8_t module, 34 | uint8_t * data, 35 | uint32_t length) 36 | { 37 | uint32_t i = 0; 38 | 39 | // head: 0xA5 40 | buf[i++] = 0xA5; 41 | buf[i++] = module; 42 | // pack length 43 | buf[i++] = *((uint8_t *)&length + 0); 44 | buf[i++] = *((uint8_t *)&length + 1); 45 | buf[i++] = *((uint8_t *)&length + 2); 46 | buf[i++] = *((uint8_t *)&length + 3); 47 | // pack data 48 | for(uint32_t j = 0; j < length; ++j) 49 | { 50 | buf[i++] = data[j]; 51 | } 52 | 53 | // calculate the LRC 54 | uint8_t check = 0x00; 55 | for(uint32_t j = 0; j < length; ++j) 56 | { 57 | check ^= data[j]; 58 | } 59 | buf[i++] = check; 60 | 61 | // tail: 0x5A 62 | buf[i++] = 0x5A; 63 | 64 | if (i > bufSize) 65 | { 66 | return 0; 67 | } 68 | else 69 | { 70 | return i; 71 | } 72 | } 73 | 74 | /* EncoderMotor */ 75 | MeEncoderMotor::MeEncoderMotor(uint8_t addr,uint8_t slot):MeWire(addr - 1) 76 | { 77 | _slot = slot - 1; 78 | } 79 | MeEncoderMotor::MeEncoderMotor(uint8_t slot):MeWire(0x8) 80 | { 81 | _slot = slot - 1; 82 | } 83 | MeEncoderMotor::MeEncoderMotor():MeWire(0x8){ 84 | _slot = 0; 85 | } 86 | void MeEncoderMotor::begin() 87 | { 88 | MeWire::begin(); 89 | reset(); 90 | } 91 | 92 | boolean MeEncoderMotor::reset() 93 | { 94 | uint8_t w[10] = {0}; 95 | uint8_t r[10] = {0}; 96 | 97 | uint8_t data[2] = {0}; 98 | data[0] = _slot; 99 | data[1] = ENCODER_MOTOR_RESET; 100 | 101 | MeHost_Pack(w, 10, 0x01, data, 2); 102 | request(w, r, 10, 10); 103 | encoderParser.pushStr(r, 10); 104 | 105 | uint8_t ack[2] = {0}; 106 | encoderParser.getData(ack, 2); 107 | return ack[1]; 108 | } 109 | 110 | boolean MeEncoderMotor::moveTo(float angle, float speed) 111 | { 112 | uint8_t w[18] = {0}; 113 | uint8_t r[10] = {0}; 114 | 115 | uint8_t data[10] = {0}; 116 | data[0] = _slot; 117 | data[1] = ENCODER_MOTOR_MOVE_TO; 118 | *((float *)(data + 2)) = angle; 119 | *((float *)(data + 6)) = speed; 120 | 121 | MeHost_Pack(w, 18, 0x01, data, 10); 122 | request(w, r, 18, 10); 123 | encoderParser.pushStr(r, 10); 124 | encoderParser.run(); 125 | 126 | uint8_t ack[2] = {0}; 127 | encoderParser.getData(ack, 2); 128 | return ack[1]; 129 | } 130 | 131 | boolean MeEncoderMotor::move(float angle, float speed) 132 | { 133 | if(angle==0){ 134 | return runSpeed(speed); 135 | } 136 | uint8_t w[18] = {0}; 137 | uint8_t r[10] = {0}; 138 | 139 | uint8_t data[10] = {0}; 140 | data[0] = _slot; 141 | data[1] = ENCODER_MOTOR_MOVE; 142 | *((float *)(data + 2)) = angle; 143 | *((float *)(data + 6)) = speed; 144 | 145 | MeHost_Pack(w, 18, 0x01, data, 10); 146 | request(w, r, 18, 10); 147 | encoderParser.pushStr(r, 10); 148 | encoderParser.run(); 149 | 150 | uint8_t ack[2] = {0}; 151 | encoderParser.getData(ack, 2); 152 | return ack[1]; 153 | } 154 | 155 | boolean MeEncoderMotor::runTurns(float turns, float speed) 156 | { 157 | return move(turns * 360, speed); 158 | } 159 | 160 | boolean MeEncoderMotor::runSpeed(float speed) 161 | { 162 | uint8_t w[14] = {0}; 163 | uint8_t r[10] = {0}; 164 | 165 | uint8_t data[6] = {0}; 166 | data[0] = _slot; 167 | data[1] = ENCODER_MOTOR_RUN_STOP; 168 | *((float *)(data + 2)) = speed; 169 | 170 | MeHost_Pack(w, 14, 0x01, data, 6); 171 | request(w, r, 14, 10); 172 | encoderParser.pushStr(r, 10); 173 | encoderParser.run(); 174 | 175 | // uint8_t ack[2] = {0}; 176 | // encoderParser.GetData(ack, 2); 177 | // return ack[1]; 178 | return 0; 179 | } 180 | 181 | boolean MeEncoderMotor::runSpeedAndTime(float speed, float time) 182 | { 183 | uint8_t w[18] = {0}; 184 | uint8_t r[10] = {0}; 185 | 186 | uint8_t data[10] = {0}; 187 | data[0] = _slot; 188 | data[1] = ENCODER_MOTOR_SPEED_TIME; 189 | *((float *)(data + 2)) = speed; 190 | *((float *)(data + 6)) = time; 191 | 192 | MeHost_Pack(w, 18, 0x01, data, 10); 193 | request(w, r, 18, 10); 194 | encoderParser.pushStr(r, 10); 195 | encoderParser.run(); 196 | 197 | // uint8_t ack[2] = {0}; 198 | // encoderParser.GetData(ack, 2); 199 | // return ack[1]; 200 | return 0; 201 | } 202 | 203 | float MeEncoderMotor::getCurrentSpeed() 204 | { 205 | uint8_t w[10] = {0}; 206 | uint8_t r[14] = {0}; 207 | 208 | uint8_t data[2] = {0}; 209 | data[0] = _slot; 210 | data[1] = ENCODER_MOTOR_GET_SPEED; 211 | 212 | MeHost_Pack(w, 10, 0x01, data, 2); 213 | request(w, r, 10, 14); 214 | encoderParser.pushStr(r, 14); 215 | encoderParser.run(); 216 | 217 | uint8_t temp[6] = {0}; 218 | encoderParser.getData(temp, 6); 219 | float speed = *((float *)(temp + 2)); 220 | return speed; 221 | } 222 | 223 | float MeEncoderMotor::getCurrentPosition() 224 | { 225 | uint8_t w[10] = {0}; 226 | uint8_t r[14] = {0}; 227 | 228 | uint8_t data[2] = {0}; 229 | data[0] = _slot; 230 | data[1] = ENCODER_MOTOR_GET_POS; 231 | 232 | MeHost_Pack(w, 10, 0x01, data, 2); 233 | request(w, r, 10, 14); 234 | encoderParser.pushStr(r, 14); 235 | 236 | encoderParser.run(); 237 | 238 | uint8_t temp[6] = {0}; 239 | uint8_t size = encoderParser.getData(temp, 6); 240 | float pos = *((float *)(temp + 2)); 241 | return pos; 242 | } 243 | -------------------------------------------------------------------------------- /mblock_firmware/MeEncoderMotor.h: -------------------------------------------------------------------------------- 1 | #ifndef MeEncoderMotor_h 2 | #define MeEncoderMotor_h 3 | #include "MeWire.h" 4 | 5 | 6 | ///@brief Class for Encoder Motor Driver 7 | class MeEncoderMotor:public MeWire{ 8 | public: 9 | MeEncoderMotor(uint8_t addr,uint8_t slot); 10 | MeEncoderMotor(uint8_t slot); 11 | MeEncoderMotor(); 12 | void begin(); 13 | boolean reset(); 14 | boolean move(float angle, float speed); 15 | boolean moveTo(float angle, float speed); 16 | boolean runTurns(float turns, float speed); 17 | boolean runSpeed(float speed); 18 | boolean runSpeedAndTime(float speed, float time); 19 | float getCurrentSpeed(); 20 | float getCurrentPosition(); 21 | private: 22 | uint8_t _slot; 23 | }; 24 | #endif 25 | -------------------------------------------------------------------------------- /mblock_firmware/MeGyro.cpp: -------------------------------------------------------------------------------- 1 | #include "MeGyro.h" 2 | static uint8_t buffers[14]; 3 | static float angleX=0; 4 | static float angleY=0; 5 | static float angleZ=0; 6 | MeGyro::MeGyro(){ 7 | 8 | } 9 | void MeGyro::begin(){ 10 | gSensitivity = 65.5; // for 500 deg/s, check data sheet 11 | gx = 0; 12 | gy = 0; 13 | gz = 0; 14 | gyrX = 0; 15 | gyrY = 0; 16 | gyrZ = 0; 17 | accX = 0; 18 | accY = 0; 19 | accZ = 0; 20 | gyrXoffs = -281.00; 21 | gyrYoffs = 18.00; 22 | gyrZoffs = -83.00; 23 | FREQ=30.0; 24 | Wire.begin(); 25 | 26 | } 27 | int MeGyro::start(){ 28 | 29 | int error = writeReg (0x6b, 0x00); 30 | error += writeReg (0x1a, 0x01); 31 | error += writeReg(0x1b, 0x08); 32 | uint8_t sample_div = 1000 / FREQ - 1; 33 | error +=writeReg (0x19, sample_div); 34 | return error; 35 | } 36 | double MeGyro::getAngleX(){ 37 | if(accZ==0)return 0; 38 | return (atan((float)accX/(float)accZ))*180/3.1415926; 39 | } 40 | double MeGyro::getAngleY(){ 41 | if(accZ==0)return 0; 42 | return (atan((float)accY/(float)accZ))*180/3.1415926; 43 | } 44 | double MeGyro::getAngleZ(){ 45 | if(gyrZ==0)return 0; 46 | return gyrZ/10.0; 47 | } 48 | void MeGyro::close(){ 49 | } 50 | void MeGyro::update(){ 51 | unsigned long start_time = millis(); 52 | uint8_t error; 53 | // read imu data 54 | if(start()!=0){ 55 | return; 56 | } 57 | error = readData(0x3b, i2cData, 14); 58 | if(error!=0){ 59 | 60 | return; 61 | } 62 | 63 | double ax, ay, az; 64 | // assemble 16 bit sensor data 65 | accX = ((i2cData[0] << 8) | i2cData[1]); 66 | accY = ((i2cData[2] << 8) | i2cData[3]); 67 | accZ = ((i2cData[4] << 8) | i2cData[5]); 68 | 69 | gyrX = (((i2cData[8] << 8) | i2cData[9]) - gyrXoffs) / gSensitivity; 70 | gyrY = (((i2cData[10] << 8) | i2cData[11]) - gyrYoffs) / gSensitivity; 71 | gyrZ = (((i2cData[12] << 8) | i2cData[13]) - gyrZoffs) / (gSensitivity+1); 72 | ay = atan2(accX, sqrt( pow(accY, 2) + pow(accZ, 2))) * 180 / M_PI; 73 | ax = atan2(accY, sqrt( pow(accX, 2) + pow(accZ, 2))) * 180 / M_PI; 74 | 75 | // angles based on gyro (deg/s) 76 | gx = gx + gyrX / FREQ; 77 | gy = gy - gyrY / FREQ; 78 | gz += gyrZ / FREQ; 79 | 80 | // complementary filter 81 | // tau = DT*(A)/(1-A) 82 | // = 0.48sec 83 | gx = gx * 0.96 + ax * 0.04; 84 | gy = gy * 0.96 + ay * 0.04; 85 | 86 | //delay(((1/FREQ) * 1000) - (millis() - start_time)-time); 87 | } 88 | int MeGyro::readData(int start, uint8_t *buffer, int size) 89 | { 90 | int i, n, error; 91 | Wire.beginTransmission(0x68); 92 | n = Wire.write(start); 93 | if (n != 1) 94 | return (-10); 95 | n = Wire.endTransmission(false); // hold the I2C-bus 96 | if (n != 0) 97 | return (n); 98 | delayMicroseconds(1); 99 | // Third parameter is true: relase I2C-bus after data is read. 100 | Wire.requestFrom(0x68, size, true); 101 | i = 0; 102 | while(Wire.available() && i 4 | #include 5 | class MeGyro{ 6 | public: 7 | MeGyro(); 8 | void begin(); 9 | void update(); 10 | double getAngleX(); 11 | double getAngleY(); 12 | double getAngleZ(); 13 | void close(); 14 | private: 15 | int readData(int start, uint8_t *buffer, int size); 16 | int writeData(int start, const uint8_t *pData, int size); 17 | int writeReg(int reg, uint8_t data); 18 | int start(); 19 | double gSensitivity; // for 500 deg/s, check data sheet 20 | double gx, gy, gz; 21 | double gyrX, gyrY, gyrZ; 22 | int16_t accX, accY, accZ; 23 | double gyrXoffs, gyrYoffs, gyrZoffs; 24 | double FREQ; 25 | uint8_t i2cData[14]; 26 | }; 27 | #endif 28 | -------------------------------------------------------------------------------- /mblock_firmware/MeHostParser.cpp: -------------------------------------------------------------------------------- 1 | // MeHostParser.cpp 2 | 3 | #include "MeHostParser.h" 4 | 5 | #define HEAD 0xA5 6 | #define TAIL 0x5A 7 | 8 | // states 9 | #define ST_WAIT_4_START 0x01 10 | #define ST_HEAD_READ 0x02 11 | #define ST_MODULE_READ 0x03 12 | #define ST_LENGTH_READ 0x04 13 | #define ST_DATA_READ 0x05 14 | #define ST_CHECK_READ 0x06 15 | 16 | MeHostParser::MeHostParser() 17 | { 18 | state = ST_WAIT_4_START; 19 | in = 0; 20 | out = 0; 21 | packageReady = 0; 22 | 23 | module = 0; 24 | length = 0; 25 | data = NULL; 26 | check = 0; 27 | 28 | lengthRead = 0; 29 | currentDataPos = 0; 30 | } 31 | 32 | MeHostParser::~MeHostParser() 33 | { 34 | ; 35 | } 36 | 37 | uint8_t MeHostParser::getPackageReady() 38 | { 39 | return (1 == packageReady); 40 | } 41 | 42 | uint8_t MeHostParser::pushStr(uint8_t * str, uint32_t length) 43 | { 44 | if (length > ((in + BUF_SIZE - out - 1) & MASK)) 45 | { 46 | return 0; 47 | } 48 | else 49 | { 50 | for (int i = 0; i < length; ++i) 51 | { 52 | pushByte(str[i]); 53 | } 54 | } 55 | } 56 | 57 | uint8_t MeHostParser::pushByte(uint8_t ch) 58 | { 59 | if (((in + 1) & MASK) != out) 60 | { 61 | buffer[in] = ch; 62 | ++in; 63 | in &= MASK; 64 | return 1; 65 | } 66 | else 67 | { 68 | return 0; 69 | } 70 | } 71 | 72 | uint8_t MeHostParser::getByte(uint8_t * ch) 73 | { 74 | if (in != out) 75 | { 76 | *ch = buffer[out]; 77 | ++out; 78 | out &= MASK; 79 | return 1; 80 | } 81 | else 82 | { 83 | // Serial.println("GET error!"); 84 | return 0; 85 | } 86 | } 87 | 88 | uint8_t calculateLRC(uint8_t *data, uint32_t length) 89 | { 90 | uint8_t LRC = 0; 91 | for (uint32_t i = 0; i < length; ++i) 92 | { 93 | LRC ^= data[i]; 94 | } 95 | return LRC; 96 | } 97 | 98 | uint8_t MeHostParser::run(void) 99 | { 100 | uint8_t ch = 0; 101 | while (getByte(&ch)) 102 | { 103 | switch (state) 104 | { 105 | case ST_WAIT_4_START: 106 | if (HEAD == ch) 107 | { 108 | state = ST_HEAD_READ; 109 | } 110 | break; 111 | case ST_HEAD_READ: 112 | module = ch; 113 | state = ST_MODULE_READ; 114 | break; 115 | case ST_MODULE_READ: 116 | // read 4 bytes as "length" 117 | *(((uint8_t *)&length) + lengthRead) = ch; 118 | ++lengthRead; 119 | if (4 == lengthRead) 120 | { 121 | lengthRead = 0; 122 | state = ST_LENGTH_READ; 123 | } 124 | break; 125 | case ST_LENGTH_READ: 126 | // alloc space for data 127 | if (0 == currentDataPos) 128 | { 129 | if (length > 255) 130 | { 131 | state = ST_WAIT_4_START; 132 | currentDataPos = 0; 133 | lengthRead = 0; 134 | length = 0; 135 | module = 0; 136 | check = 0; 137 | break; 138 | } 139 | data = (uint8_t *)malloc(length + 1); 140 | if (NULL == data) 141 | { 142 | state = ST_WAIT_4_START; 143 | currentDataPos = 0; 144 | lengthRead = 0; 145 | length = 0; 146 | module = 0; 147 | check = 0; 148 | break; 149 | } 150 | } 151 | // read data 152 | data[currentDataPos] = ch; 153 | ++currentDataPos; 154 | if (currentDataPos == length) 155 | { 156 | currentDataPos = 0; 157 | state = ST_DATA_READ; 158 | } 159 | break; 160 | case ST_DATA_READ: 161 | check = ch; 162 | if (check != calculateLRC(data, length)) 163 | { 164 | state = ST_WAIT_4_START; 165 | if (NULL != data) 166 | { 167 | free(data); 168 | data = NULL; 169 | } 170 | currentDataPos = 0; 171 | lengthRead = 0; 172 | length = 0; 173 | module = 0; 174 | check = 0; 175 | } 176 | else 177 | { 178 | state = ST_CHECK_READ; 179 | } 180 | break; 181 | case ST_CHECK_READ: 182 | if (TAIL != ch) 183 | { 184 | if (NULL != data) 185 | { 186 | free(data); 187 | data = NULL; 188 | } 189 | length = 0; 190 | } 191 | else 192 | { 193 | packageReady = 1; 194 | } 195 | state = ST_WAIT_4_START; 196 | currentDataPos = 0; 197 | lengthRead = 0; 198 | module = 0; 199 | check = 0; 200 | break; 201 | default: 202 | break; 203 | } 204 | } 205 | return state; 206 | } 207 | 208 | 209 | 210 | uint8_t MeHostParser::getData(uint8_t *buf, uint32_t size) 211 | { 212 | int copySize = (size > length) ? length : size; 213 | if ((NULL != data) && (NULL != buf)) 214 | { 215 | memcpy(buf, data, copySize); 216 | free(data); 217 | data = NULL; 218 | length = 0; 219 | packageReady = 0; 220 | 221 | return copySize; 222 | } 223 | else 224 | { 225 | return 0; 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /mblock_firmware/MeHostParser.h: -------------------------------------------------------------------------------- 1 | #ifndef MeHostParser_h 2 | #define MeHostParser_h 3 | #include 4 | #define BUF_SIZE 256 5 | #define MASK 255 6 | 7 | class MeHostParser 8 | { 9 | public: 10 | MeHostParser(); 11 | ~MeHostParser(); 12 | 13 | // push data to buffer 14 | uint8_t pushStr(uint8_t * str, uint32_t length); 15 | uint8_t pushByte(uint8_t ch); 16 | // run state machine 17 | uint8_t run(); 18 | // get the package ready state 19 | uint8_t getPackageReady(); 20 | // copy data to user's buffer 21 | uint8_t getData(uint8_t *buf, uint32_t size); 22 | 23 | void print(char *str, uint32_t * cnt); 24 | private: 25 | int state; 26 | uint8_t buffer[BUF_SIZE]; 27 | uint32_t in; 28 | uint32_t out; 29 | uint8_t packageReady; 30 | 31 | uint8_t module; 32 | uint32_t length; 33 | uint8_t *data; 34 | uint8_t check; 35 | 36 | uint32_t lengthRead; 37 | uint32_t currentDataPos; 38 | 39 | uint8_t getByte(uint8_t * ch); 40 | }; 41 | 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /mblock_firmware/MeInfraredReceiver.cpp: -------------------------------------------------------------------------------- 1 | #include "MeInfraredReceiver.h" 2 | 3 | MeInfraredReceiver::MeInfraredReceiver():MePort(){ 4 | 5 | } 6 | 7 | MeInfraredReceiver::MeInfraredReceiver(uint8_t port):MePort(port){ 8 | pinMode(s1,INPUT); 9 | pinMode(s2,INPUT); 10 | } 11 | int MeInfraredReceiver::available(){ 12 | char c = poll(); 13 | if(c>0){ 14 | _buffer = c; 15 | return 1; 16 | } 17 | return 0; 18 | } 19 | unsigned char MeInfraredReceiver::read(){ 20 | unsigned char c = _buffer; 21 | _buffer = 0; 22 | return c; 23 | } 24 | 25 | bool MeInfraredReceiver::buttonState(){ 26 | 27 | if(getPort()>0){ 28 | return dRead1()==0; 29 | } 30 | return 0; 31 | } 32 | unsigned char MeInfraredReceiver::poll() 33 | { 34 | //noInterrupts(); 35 | unsigned char val = 0; 36 | int bitDelay = 1000000.0/9600.0 - clockCyclesToMicroseconds(50); 37 | if (digitalRead(s2) == LOW) { 38 | for(int offset=0;offset<8;offset++){ 39 | delayMicroseconds(bitDelay); 40 | val |= digitalRead(s2) << offset; 41 | } 42 | delayMicroseconds(bitDelay); 43 | //interrupts(); 44 | return val&0xff; 45 | } 46 | //interrupts(); 47 | return 0; 48 | } 49 | unsigned char MeInfraredReceiver::getCode(){ 50 | return _irCode; 51 | } 52 | void MeInfraredReceiver::loop() 53 | { 54 | if(buttonState()==1){ 55 | if(available()>0){ 56 | _irCode = read(); 57 | } 58 | }else{ 59 | _irCode = 0; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /mblock_firmware/MeInfraredReceiver.h: -------------------------------------------------------------------------------- 1 | #ifndef MeInfraredReceiver_H_ 2 | #define MeInfraredReceiver_H_ 3 | #include "MePort.h" 4 | class MeInfraredReceiver:public MePort{ 5 | public : 6 | MeInfraredReceiver(); 7 | MeInfraredReceiver(uint8_t port); 8 | int available(); 9 | unsigned char read(); 10 | unsigned char getCode(); 11 | unsigned char poll(); 12 | bool buttonState(); 13 | void loop(); 14 | private: 15 | unsigned char _irCode; 16 | unsigned char _buffer; 17 | }; 18 | #endif 19 | -------------------------------------------------------------------------------- /mblock_firmware/MePort.cpp: -------------------------------------------------------------------------------- 1 | #include "MePort.h" 2 | 3 | #if defined(__AVR_ATmega32U4__) //MeBaseBoard use ATmega32U4 as MCU 4 | 5 | MePort_Sig mePort[11] = {{NC, NC}, {11, A8}, {13, A11}, {10, 9}, {1, 0}, 6 | {MISO, SCK}, {A0, A1}, {A2, A3}, {A4, A5}, {6, 7}, {5, 4} 7 | }; 8 | #else // else ATmega328 9 | MePort_Sig mePort[11] = {{NC, NC}, {11, 10}, {3, 9}, {12, 13}, {8, 2}, 10 | {NC, NC}, {A2, A3}, {A6, A1}, {A7, A0}, {6, 7}, {5, 4} 11 | }; 12 | 13 | #endif 14 | 15 | union{ 16 | byte b[4]; 17 | float fVal; 18 | long lVal; 19 | }u; 20 | 21 | /* Port */ 22 | MePort::MePort(){ 23 | s1 = mePort[0].s1; 24 | s2 = mePort[0].s2; 25 | _port = 0; 26 | } 27 | MePort::MePort(uint8_t port) 28 | { 29 | s1 = mePort[port].s1; 30 | s2 = mePort[port].s2; 31 | _port = port; 32 | //The PWM frequency is 976 Hz 33 | #if defined(__AVR_ATmega32U4__) //MeBaseBoard use ATmega32U4 as MCU 34 | 35 | TCCR1A = _BV(WGM10); 36 | TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12); 37 | 38 | TCCR3A = _BV(WGM30); 39 | TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); 40 | 41 | TCCR4B = _BV(CS42) | _BV(CS41) | _BV(CS40); 42 | TCCR4D = 0; 43 | 44 | #else if defined(__AVR_ATmega328__) // else ATmega328 45 | 46 | TCCR1A = _BV(WGM10); 47 | TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12); 48 | 49 | TCCR2A = _BV(WGM21) |_BV(WGM20); 50 | TCCR2B = _BV(CS22); 51 | 52 | #endif 53 | } 54 | MePort::MePort(uint8_t port,uint8_t slot) 55 | { 56 | s1 = mePort[port].s1; 57 | s2 = mePort[port].s2; 58 | _port = port; 59 | _slot = slot; 60 | //The PWM frequency is 976 Hz 61 | #if defined(__AVR_ATmega32U4__) //MeBaseBoard use ATmega32U4 as MCU 62 | 63 | TCCR1A = _BV(WGM10); 64 | TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12); 65 | 66 | TCCR3A = _BV(WGM30); 67 | TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); 68 | 69 | TCCR4B = _BV(CS42) | _BV(CS41) | _BV(CS40); 70 | TCCR4D = 0; 71 | 72 | #else if defined(__AVR_ATmega328__) // else ATmega328 73 | 74 | TCCR1A = _BV(WGM10); 75 | TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12); 76 | 77 | TCCR2A = _BV(WGM21) |_BV(WGM20); 78 | TCCR2B = _BV(CS22); 79 | 80 | #endif 81 | } 82 | uint8_t MePort::getPort(){ 83 | return _port; 84 | } 85 | uint8_t MePort::getSlot(){ 86 | return _slot; 87 | } 88 | bool MePort::dRead1() 89 | { 90 | bool val; 91 | pinMode(s1, INPUT); 92 | val = digitalRead(s1); 93 | return val; 94 | } 95 | 96 | bool MePort::dRead2() 97 | { 98 | bool val; 99 | pinMode(s2, INPUT); 100 | val = digitalRead(s2); 101 | return val; 102 | } 103 | 104 | void MePort::dWrite1(bool value) 105 | { 106 | pinMode(s1, OUTPUT); 107 | digitalWrite(s1, value); 108 | } 109 | 110 | void MePort::dWrite2(bool value) 111 | { 112 | pinMode(s2, OUTPUT); 113 | digitalWrite(s2, value); 114 | } 115 | 116 | int MePort::aRead1() 117 | { 118 | int val; 119 | val = analogRead(s1); 120 | return val; 121 | } 122 | 123 | int MePort::aRead2() 124 | { 125 | int val; 126 | val = analogRead(s2); 127 | return val; 128 | } 129 | 130 | void MePort::aWrite1(int value) 131 | { 132 | analogWrite(s1, value); 133 | } 134 | 135 | void MePort::aWrite2(int value) 136 | { 137 | analogWrite(s2, value); 138 | } 139 | void MePort::reset(uint8_t port){ 140 | s1 = mePort[port].s1; 141 | s2 = mePort[port].s2; 142 | _port = port; 143 | } 144 | void MePort::reset(uint8_t port,uint8_t slot){ 145 | s1 = mePort[port].s1; 146 | s2 = mePort[port].s2; 147 | _port = port; 148 | _slot = slot; 149 | } 150 | uint8_t MePort::pin1(){ 151 | return s1; 152 | } 153 | uint8_t MePort::pin2(){ 154 | return s2; 155 | } 156 | 157 | uint8_t MePort::pin(){ 158 | return _slot==SLOT_1?s1:s2; 159 | } 160 | uint8_t MePort::pin(uint8_t port,uint8_t slot){ 161 | return slot==SLOT_1?mePort[port].s1:mePort[port].s2; 162 | } 163 | -------------------------------------------------------------------------------- /mblock_firmware/MePort.h: -------------------------------------------------------------------------------- 1 | #ifndef MEPORT_H_ 2 | #define MEPORT_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #ifndef F_CPU 8 | #define F_CPU 16000000UL 9 | #endif 10 | #include 11 | #include 12 | #include 13 | 14 | typedef struct 15 | { 16 | uint8_t s1; 17 | uint8_t s2; 18 | } MePort_Sig; 19 | extern MePort_Sig mePort[11];//mePort[0] is nonsense 20 | 21 | #define NC -1 22 | 23 | #define PORT_1 0x01 24 | #define PORT_2 0x02 25 | #define PORT_3 0x03 26 | #define PORT_4 0x04 27 | #define PORT_5 0x05 28 | #define PORT_6 0x06 29 | #define PORT_7 0x07 30 | #define PORT_8 0x08 31 | #define M1 0x09 32 | #define M2 0x0a 33 | struct cRGB { 34 | uint8_t g; 35 | uint8_t r; 36 | uint8_t b; 37 | }; 38 | #if defined(__AVR_ATmega32U4__) 39 | // buzzer 40 | #define buzzerOn() DDRE |= 0x04,PORTE |= B00000100 41 | #define buzzerOff() DDRE |= 0x04,PORTE &= B11111011 42 | #else 43 | #define buzzerOn() DDRC |= 0x20,PORTC |= B00100000; 44 | #define buzzerOff() DDRC |= 0x20,PORTC &= B11011111; 45 | #endif 46 | #define SLOT_1 1 47 | #define SLOT_2 2 48 | 49 | 50 | #define FALSE 0 51 | #define TRUE 1 52 | 53 | // Platform specific I/O definitions 54 | 55 | #if defined(__AVR__) 56 | #define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) 57 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 58 | #define IO_REG_TYPE uint8_t 59 | #define IO_REG_ASM asm("r30") 60 | #define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 61 | #define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)) 62 | #define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) 63 | #define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) 64 | #define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) 65 | #endif 66 | 67 | 68 | ///@brief class of MePort,it contains two pin. 69 | class MePort 70 | { 71 | public: 72 | MePort(); 73 | ///@brief initialize the Port 74 | ///@param port port number of device 75 | MePort(uint8_t port); 76 | MePort(uint8_t port,uint8_t slot); 77 | ///@return the level of pin 1 of port 78 | ///@retval true on HIGH. 79 | ///@retval false on LOW. 80 | uint8_t getPort(); 81 | uint8_t getSlot(); 82 | ///@return the level of pin 1 of port 83 | ///@retval true on HIGH. 84 | ///@retval false on LOW. 85 | bool dRead1(); 86 | ///@return the level of pin 2 of port 87 | ///@retval true on HIGH. 88 | ///@retval false on LOW. 89 | bool dRead2(); 90 | ///@brief set the analog value of pin 1 of port 91 | ///@param value is HIGH or LOW 92 | void dWrite1(bool value); 93 | ///@brief set the level of pin 1 of port 94 | ///@param value is HIGH or LOW 95 | void dWrite2(bool value); 96 | ///@return the analog signal of pin 1 of port between 0 to 1023 97 | int aRead1(); 98 | ///@return the analog signal of pin 2 of port between 0 to 1023 99 | int aRead2(); 100 | ///@brief set the PWM outpu value of pin 1 of port 101 | ///@param value between 0 to 255 102 | void aWrite1(int value); 103 | ///@brief set the PWM outpu value of pin 2 of port 104 | ///@param value between 0 to 255 105 | void aWrite2(int value); 106 | void reset(uint8_t port); 107 | void reset(uint8_t port,uint8_t slot); 108 | uint8_t pin1(); 109 | uint8_t pin2(); 110 | uint8_t pin(); 111 | uint8_t pin(uint8_t port,uint8_t slot); 112 | protected: 113 | uint8_t s1; 114 | uint8_t s2; 115 | uint8_t _port; 116 | uint8_t _slot; 117 | }; 118 | #endif 119 | -------------------------------------------------------------------------------- /mblock_firmware/MeRGBLed.cpp: -------------------------------------------------------------------------------- 1 | #include "MeRGBLed.h" 2 | MeRGBLed::MeRGBLed():MePort(0) { 3 | setNumber(32); 4 | } 5 | MeRGBLed::MeRGBLed(uint8_t port):MePort(port) { 6 | pinMask = digitalPinToBitMask(s2); 7 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 8 | ws2812_port_reg = portModeRegister(digitalPinToPort(s2)); 9 | // *ws2812_port_reg |= pinMask; //set pinMode OUTPUT 10 | pinMode(s2,OUTPUT); 11 | setNumber(32); 12 | } 13 | MeRGBLed::MeRGBLed(uint8_t port,uint8_t slot):MePort(port){ 14 | if(slot==1){ 15 | pinMask = digitalPinToBitMask(s2); 16 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 17 | ws2812_port_reg = portModeRegister(digitalPinToPort(s2)); 18 | pinMode(s2,OUTPUT); 19 | }else{ 20 | pinMask = digitalPinToBitMask(s1); 21 | ws2812_port = portOutputRegister(digitalPinToPort(s1)); 22 | ws2812_port_reg = portModeRegister(digitalPinToPort(s1)); 23 | pinMode(s1,OUTPUT); 24 | } 25 | //*ws2812_port_reg |= pinMask; // set pinMode OUTPUT 26 | setNumber(32); 27 | } 28 | void MeRGBLed::reset(uint8_t port){ 29 | _port = port; 30 | s2 = mePort[port].s2; 31 | s1 = mePort[port].s1; 32 | pinMask = digitalPinToBitMask(s2); 33 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 34 | ws2812_port_reg = portModeRegister(digitalPinToPort(s2)); 35 | //*ws2812_port_reg |= pinMask; 36 | pinMode(s2,OUTPUT); 37 | } 38 | void MeRGBLed::setNumber(uint8_t num_leds){ 39 | count_led = num_leds; 40 | pixels = (uint8_t*)malloc(count_led*3); 41 | for(int i=0;i>16; 99 | uint8_t green = (value&0xff00)>>8; 100 | uint8_t blue = value&0xff; 101 | pixels[tmp] = green; 102 | pixels[tmp+1] = red; 103 | pixels[tmp+2] = blue; 104 | return true; 105 | } 106 | return false; 107 | } 108 | /* 109 | This routine writes an array of bytes with RGB values to the Dataout pin 110 | using the fast 800kHz clockless WS2811/2812 protocol. 111 | */ 112 | 113 | // Timing in ns 114 | #define w_zeropulse 350 115 | #define w_onepulse 900 116 | #define w_totalperiod 1250 117 | 118 | // Fixed cycles used by the inner loop 119 | #define w_fixedlow 3 120 | #define w_fixedhigh 6 121 | #define w_fixedtotal 10 122 | 123 | // Insert NOPs to match the timing, if possible 124 | #define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000) 125 | #define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000) 126 | #define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000) 127 | 128 | // w1 - nops between rising edge and falling edge - low 129 | #define w1 (w_zerocycles-w_fixedlow) 130 | // w2 nops between fe low and fe high 131 | #define w2 (w_onecycles-w_fixedhigh-w1) 132 | // w3 nops to complete loop 133 | #define w3 (w_totalcycles-w_fixedtotal-w1-w2) 134 | 135 | #if w1>0 136 | #define w1_nops w1 137 | #else 138 | #define w1_nops 0 139 | #endif 140 | 141 | // The only critical timing parameter is the minimum pulse length of the "0" 142 | // Warn or throw error if this timing can not be met with current F_CPU settings. 143 | #define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000) 144 | #if w_lowtime>550 145 | #error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?" 146 | #elif w_lowtime>450 147 | #warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)." 148 | #warning "Please consider a higher clockspeed, if possible" 149 | #endif 150 | 151 | #if w2>0 152 | #define w2_nops w2 153 | #else 154 | #define w2_nops 0 155 | #endif 156 | 157 | #if w3>0 158 | #define w3_nops w3 159 | #else 160 | #define w3_nops 0 161 | #endif 162 | 163 | #define w_nop1 "nop \n\t" 164 | #define w_nop2 "rjmp .+0 \n\t" 165 | #define w_nop4 w_nop2 w_nop2 166 | #define w_nop8 w_nop4 w_nop4 167 | #define w_nop16 w_nop8 w_nop8 168 | 169 | void MeRGBLed::rgbled_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi,uint8_t *port) 170 | { 171 | uint8_t curbyte,ctr,masklo; 172 | uint8_t oldSREG = SREG; 173 | cli(); //Disables all interrupts 174 | 175 | masklo = *port & ~maskhi; 176 | maskhi = *port | maskhi; 177 | 178 | while (datlen--) { 179 | curbyte=*data++; 180 | 181 | asm volatile( 182 | " ldi %0,8 \n\t" 183 | "loop%=: \n\t" 184 | " st X,%3 \n\t" // '1' [02] '0' [02] - re 185 | #if (w1_nops&1) 186 | w_nop1 187 | #endif 188 | #if (w1_nops&2) 189 | w_nop2 190 | #endif 191 | #if (w1_nops&4) 192 | w_nop4 193 | #endif 194 | #if (w1_nops&8) 195 | w_nop8 196 | #endif 197 | #if (w1_nops&16) 198 | w_nop16 199 | #endif 200 | " sbrs %1,7 \n\t" // '1' [04] '0' [03] 201 | " st X,%4 \n\t" // '1' [--] '0' [05] - fe-low 202 | " lsl %1 \n\t" // '1' [05] '0' [06] 203 | #if (w2_nops&1) 204 | w_nop1 205 | #endif 206 | #if (w2_nops&2) 207 | w_nop2 208 | #endif 209 | #if (w2_nops&4) 210 | w_nop4 211 | #endif 212 | #if (w2_nops&8) 213 | w_nop8 214 | #endif 215 | #if (w2_nops&16) 216 | w_nop16 217 | #endif 218 | " brcc skipone%= \n\t" // '1' [+1] '0' [+2] - 219 | " st X,%4 \n\t" // '1' [+3] '0' [--] - fe-high 220 | "skipone%=: " // '1' [+3] '0' [+2] - 221 | 222 | #if (w3_nops&1) 223 | w_nop1 224 | #endif 225 | #if (w3_nops&2) 226 | w_nop2 227 | #endif 228 | #if (w3_nops&4) 229 | w_nop4 230 | #endif 231 | #if (w3_nops&8) 232 | w_nop8 233 | #endif 234 | #if (w3_nops&16) 235 | w_nop16 236 | #endif 237 | 238 | " dec %0 \n\t" // '1' [+4] '0' [+3] 239 | " brne loop%=\n\t" // '1' [+5] '0' [+4] 240 | : "=&d" (ctr) 241 | // : "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo) 242 | : "r" (curbyte), "x" (port), "r" (maskhi), "r" (masklo) 243 | ); 244 | } 245 | 246 | SREG = oldSREG; 247 | } 248 | void MeRGBLed::show() { 249 | // *ws2812_port_reg |= pinMask; // Enable DDR 250 | rgbled_sendarray_mask(pixels,3*count_led,pinMask,(uint8_t*) ws2812_port); 251 | } 252 | 253 | MeRGBLed::~MeRGBLed() { 254 | 255 | 256 | } 257 | -------------------------------------------------------------------------------- /mblock_firmware/MeRGBLed.h: -------------------------------------------------------------------------------- 1 | #ifndef MeRGBLed_h 2 | #define MeRGBLed_h 3 | #include "MePort.h" 4 | ///@brief Class for RGB Led Module(http://www.makeblock.cc/me-rgb-led-v1-0/) and Led Strip(http://www.makeblock.cc/led-rgb-strip-addressable-sealed-1m/) 5 | class MeRGBLed:public MePort { 6 | public: 7 | MeRGBLed(); 8 | MeRGBLed(uint8_t port); 9 | MeRGBLed(uint8_t port,uint8_t slot); 10 | ~MeRGBLed(); 11 | void reset(uint8_t port); 12 | ///@brief set the count of leds. 13 | void setNumber(uint8_t num_led); 14 | ///@brief get the count of leds. 15 | uint8_t getNumber(); 16 | ///@brief get the rgb value of the led with the index. 17 | cRGB getColorAt(uint8_t index); 18 | ///@brief set the rgb value of the led with the index. 19 | bool setColorAt(uint8_t index, uint8_t red,uint8_t green,uint8_t blue); 20 | bool setColor(uint8_t index, uint8_t red,uint8_t green,uint8_t blue); 21 | bool setColor(uint8_t red,uint8_t green,uint8_t blue); 22 | bool setColorAt(uint8_t index, long value); 23 | ///@brief become effective of all led's change. 24 | void show(); 25 | 26 | private: 27 | uint16_t count_led; 28 | uint8_t *pixels; 29 | 30 | void rgbled_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask,uint8_t *port); 31 | 32 | const volatile uint8_t *ws2812_port; 33 | volatile uint8_t *ws2812_port_reg; 34 | uint8_t pinMask; 35 | }; 36 | #endif 37 | -------------------------------------------------------------------------------- /mblock_firmware/MeServo.cpp: -------------------------------------------------------------------------------- 1 | #include "MeServo.h" 2 | 3 | MeServo::MeServo() { 4 | isAttached = false; 5 | servoPin = 0; 6 | angle = 90; 7 | mTime = micros(); 8 | pinState = false; 9 | _index=0; 10 | 11 | } 12 | MeServo::MeServo(uint8_t port): MePort(port) 13 | { 14 | attach(s1); 15 | } 16 | MeServo::MeServo(uint8_t port,uint8_t slot): MePort(port,slot) 17 | { 18 | attach(slot==SLOT_1?s1:s2); 19 | } 20 | void MeServo::reset(uint8_t port,uint8_t slot){ 21 | //detach(); 22 | _port = port; 23 | _slot = slot; 24 | s2 = mePort[port].s2; 25 | s1 = mePort[port].s1; 26 | servoPin = slot==SLOT_1?s1:s2; 27 | attach(servoPin); 28 | } 29 | void MeServo::attach(int pin) { 30 | if(indexOfServo(pin)==-1&&_index<8){ 31 | pins[_index]=pin; 32 | _index++; 33 | } 34 | if(indexOfServo(pin)>-1){ 35 | isAttached = true; 36 | pinMode(pin, OUTPUT); 37 | if(!servos[indexOfServo(pin)].attached()){ 38 | servos[indexOfServo(pin)].attach(pin); 39 | } 40 | } 41 | } 42 | int MeServo::indexOfServo(int pin){ 43 | for(int i=0;i<8;i++){ 44 | if(pin==pins[i]){ 45 | return i; 46 | } 47 | } 48 | return -1; 49 | } 50 | void MeServo::detach(int pin) { 51 | isAttached = false; 52 | // pinMode(servoPin, INPUT); 53 | if(indexOfServo(pin)>-1){ 54 | pins[indexOfServo(pin)]=-1; 55 | if(servos[indexOfServo(pin)].attached()){ 56 | servos[indexOfServo(pin)].detach(); 57 | } 58 | } 59 | } 60 | 61 | boolean MeServo::attached(void) { 62 | return isAttached; 63 | } 64 | 65 | void MeServo::write(int pin,uint8_t a) { 66 | angle = a; 67 | if(indexOfServo(pin)>-1){ 68 | servos[indexOfServo(pin)].write(a); 69 | } 70 | } 71 | 72 | void MeServo::refresh(void) { 73 | // if(isAttached){ 74 | // digitalWrite(servoPin, HIGH); 75 | // delayMicroseconds(delayTime); 76 | // digitalWrite(servoPin, LOW); 77 | // } 78 | } 79 | -------------------------------------------------------------------------------- /mblock_firmware/MeServo.h: -------------------------------------------------------------------------------- 1 | #ifndef MESERVO_H_ 2 | #define MESERVO_H_ 3 | #include 4 | #include 5 | #include "MePort.h" 6 | class MeServo : public MePort{ 7 | public: 8 | MeServo(); 9 | MeServo(uint8_t port); 10 | MeServo(uint8_t port,uint8_t slot); 11 | void reset(uint8_t port,uint8_t slot); 12 | void attach(int pin); 13 | void detach(int pin); 14 | boolean attached(); 15 | void write(int pin,uint8_t a); 16 | void refresh(void); 17 | int indexOfServo(int pin); 18 | private: 19 | boolean isAttached; 20 | int angle,servoPin; 21 | uint16_t delayTime; 22 | unsigned long mTime; 23 | int pinState; 24 | int pins[8]; 25 | int _index; 26 | Servo servos[8]; 27 | }; 28 | #endif 29 | -------------------------------------------------------------------------------- /mblock_firmware/MeStepper.cpp: -------------------------------------------------------------------------------- 1 | // MeStepper.cpp 2 | 3 | #include "MeStepper.h" 4 | 5 | void MeStepper::moveTo(long absolute) 6 | { 7 | _targetPos = absolute; 8 | computeNewSpeed(); 9 | } 10 | 11 | void MeStepper::move(long relative) 12 | { 13 | moveTo(_currentPos + relative); 14 | } 15 | 16 | boolean MeStepper::runSpeed() 17 | { 18 | unsigned long time = micros(); 19 | 20 | if (time > _lastStepTime + _stepInterval) 21 | { 22 | if (_speed > 0) 23 | { 24 | // Clockwise 25 | _currentPos += 1; 26 | } 27 | else if (_speed < 0) 28 | { 29 | // Anticlockwise 30 | _currentPos -= 1; 31 | } 32 | step(); 33 | 34 | _lastStepTime = time; 35 | return true; 36 | } 37 | else 38 | return false; 39 | } 40 | 41 | long MeStepper::distanceToGo() 42 | { 43 | return _targetPos - _currentPos; 44 | } 45 | 46 | long MeStepper::targetPosition() 47 | { 48 | return _targetPos; 49 | } 50 | 51 | long MeStepper::currentPosition() 52 | { 53 | return _currentPos; 54 | } 55 | 56 | void MeStepper::setCurrentPosition(long position) 57 | { 58 | _currentPos = position; 59 | } 60 | 61 | void MeStepper::computeNewSpeed() 62 | { 63 | setSpeed(desiredSpeed()); 64 | } 65 | 66 | float MeStepper::desiredSpeed() 67 | { 68 | long distanceTo = distanceToGo(); 69 | 70 | float requiredSpeed; 71 | if (distanceTo == 0) 72 | return 0.0; 73 | else if (distanceTo > 0) 74 | requiredSpeed = sqrt(2.0 * distanceTo * _acceleration); 75 | else 76 | requiredSpeed = -sqrt(2.0 * -distanceTo * _acceleration); 77 | 78 | if (requiredSpeed > _speed) 79 | { 80 | if (_speed == 0) 81 | requiredSpeed = sqrt(2.0 * _acceleration); 82 | else 83 | requiredSpeed = _speed + abs(_acceleration / _speed); 84 | if (requiredSpeed > _maxSpeed) 85 | requiredSpeed = _maxSpeed; 86 | } 87 | else if (requiredSpeed < _speed) 88 | { 89 | if (_speed == 0) 90 | requiredSpeed = -sqrt(2.0 * _acceleration); 91 | else 92 | requiredSpeed = _speed - abs(_acceleration / _speed); 93 | if (requiredSpeed < -_maxSpeed) 94 | requiredSpeed = -_maxSpeed; 95 | } 96 | // Serial.println(requiredSpeed); 97 | return requiredSpeed; 98 | } 99 | 100 | boolean MeStepper::run() 101 | { 102 | if (_targetPos == _currentPos) 103 | return false; 104 | 105 | if (runSpeed()) 106 | computeNewSpeed(); 107 | return true; 108 | } 109 | MeStepper::MeStepper(): MePort(0){ 110 | } 111 | MeStepper::MeStepper(uint8_t port): MePort(port) 112 | { 113 | _currentPos = 0; 114 | _targetPos = 0; 115 | _speed = 0.0; 116 | _maxSpeed = 3000.0; 117 | _acceleration = 3000.0; 118 | _stepInterval = 0; 119 | _lastStepTime = 0; 120 | _dir = 1; 121 | pinMode(s1,OUTPUT); 122 | pinMode(s2,OUTPUT); 123 | digitalWrite(s1,_dir); 124 | } 125 | void MeStepper::setMaxSpeed(float speed) 126 | { 127 | _maxSpeed = speed; 128 | computeNewSpeed(); 129 | } 130 | 131 | void MeStepper::setAcceleration(float acceleration) 132 | { 133 | _acceleration = acceleration; 134 | computeNewSpeed(); 135 | } 136 | 137 | void MeStepper::setSpeed(float speed) 138 | { 139 | _speed = speed; 140 | _stepInterval = abs(1000.0 / _speed)*1000.0; 141 | if(_speed>0){ 142 | _dir = 1; 143 | }else{ 144 | _dir = 0; 145 | } 146 | digitalWrite(s1,_dir); 147 | } 148 | 149 | float MeStepper::speed() 150 | { 151 | return _speed; 152 | } 153 | 154 | void MeStepper::step() 155 | { 156 | digitalWrite(s2, HIGH); 157 | delayMicroseconds(1); 158 | digitalWrite(s2, LOW); 159 | } 160 | 161 | // Blocks until the target position is reached 162 | void MeStepper::runToPosition() 163 | { 164 | while (run()) 165 | ; 166 | } 167 | 168 | boolean MeStepper::runSpeedToPosition() 169 | { 170 | return _targetPos!=_currentPos ? MeStepper::runSpeed() : false; 171 | } 172 | 173 | // Blocks until the new target position is reached 174 | void MeStepper::runToNewPosition(long position) 175 | { 176 | moveTo(position); 177 | runToPosition(); 178 | } 179 | 180 | -------------------------------------------------------------------------------- /mblock_firmware/MeStepper.h: -------------------------------------------------------------------------------- 1 | #ifndef MeStepper_h 2 | #define MeStepper_h 3 | #include "MePort.h" 4 | 5 | #if ARDUINO >= 100 6 | #include "Arduino.h" 7 | #else 8 | #include "WProgram.h" 9 | #include "stdlib.h" 10 | #include "wiring.h" 11 | #endif 12 | 13 | 14 | // These defs cause trouble on some versions of Arduino 15 | #undef round 16 | 17 | ///////////////////////////////////////////////////////////////////// 18 | /// \class MeStepper MeStepper.h 19 | class MeStepper:public MePort 20 | { 21 | public: 22 | MeStepper(); 23 | MeStepper(uint8_t port); 24 | 25 | void moveTo(long absolute); 26 | 27 | void move(long relative); 28 | boolean run(); 29 | boolean runSpeed(); 30 | void setMaxSpeed(float speed); 31 | void setAcceleration(float acceleration); 32 | void setSpeed(float speed); 33 | float speed(); 34 | long distanceToGo(); 35 | long targetPosition(); 36 | long currentPosition(); 37 | void setCurrentPosition(long position); 38 | void runToPosition(); 39 | boolean runSpeedToPosition(); 40 | void runToNewPosition(long position); 41 | void disableOutputs(); 42 | void enableOutputs(); 43 | 44 | protected: 45 | 46 | void computeNewSpeed(); 47 | virtual void step(); 48 | 49 | virtual float desiredSpeed(); 50 | 51 | private: 52 | uint8_t _dir; // 2 or 4 53 | uint8_t _dirPin, _stpPin; 54 | long _currentPos; // Steps 55 | long _targetPos; // Steps 56 | float _speed; // Steps per second 57 | float _maxSpeed; 58 | float _acceleration; 59 | unsigned long _stepInterval; 60 | unsigned long _lastStepTime; 61 | }; 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /mblock_firmware/MeTemperature.h: -------------------------------------------------------------------------------- 1 | #ifndef MeTemperature_h 2 | #define MeTemperature_h 3 | #include "MePort.h" 4 | #if defined(__AVR__) 5 | #define MePIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) 6 | #define MePIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 7 | #define MeIO_REG_TYPE uint8_t 8 | #define MeIO_REG_ASM asm("r30") 9 | #define MeDIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 10 | #define MeDIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)),((*((base)+2)) |= (mask))//INPUT_PULLUP 11 | #define MeDIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) 12 | #define MeDIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) 13 | #define MeDIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) 14 | #endif 15 | class MeOneWire 16 | { 17 | private: 18 | MeIO_REG_TYPE bitmask; 19 | volatile MeIO_REG_TYPE *baseReg; 20 | // global search state 21 | unsigned char ROM_NO[8]; 22 | uint8_t LastDiscrepancy; 23 | uint8_t LastFamilyDiscrepancy; 24 | uint8_t LastDeviceFlag; 25 | public: 26 | MeOneWire(); 27 | MeOneWire( uint8_t pin); 28 | bool readIO(void); 29 | void reset(uint8_t pin); 30 | // Perform a 1-Wire reset cycle. Returns 1 if a device responds 31 | // with a presence pulse. Returns 0 if there is no device or the 32 | // bus is shorted or otherwise held low for more than 250uS 33 | uint8_t reset(void); 34 | // Issue a 1-Wire rom select command, you do the reset first. 35 | void select(const uint8_t rom[8]); 36 | // Issue a 1-Wire rom skip command, to address all on bus. 37 | void skip(void); 38 | // Write a byte. If 'power' is one then the wire is held high at 39 | // the end for parasitically powered devices. You are responsible 40 | // for eventually depowering it by calling depower() or doing 41 | // another read or write. 42 | void write(uint8_t v, uint8_t power = 0); 43 | void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); 44 | // Read a byte. 45 | uint8_t read(void); 46 | void read_bytes(uint8_t *buf, uint16_t count); 47 | // Write a bit. The bus is always left powered at the end, see 48 | // note in write() about that. 49 | void write_bit(uint8_t v); 50 | // Read a bit. 51 | uint8_t read_bit(void); 52 | // Stop forcing power onto the bus. You only need to do this if 53 | // you used the 'power' flag to write() or used a write_bit() call 54 | // and aren't about to do another read or write. You would rather 55 | // not leave this powered if you don't have to, just in case 56 | // someone shorts your bus. 57 | void depower(void); 58 | // Clear the search state so that if will start from the beginning again. 59 | void reset_search(); 60 | // Setup the search to find the device type 'family_code' on the next call 61 | // to search(*newAddr) if it is present. 62 | void target_search(uint8_t family_code); 63 | // Look for the next device. Returns 1 if a new address has been 64 | // returned. A zero might mean that the bus is shorted, there are 65 | // no devices, or you have already retrieved all of them. It 66 | // might be a good idea to check the CRC to make sure you didn't 67 | // get garbage. The order is deterministic. You will always get 68 | // the same devices in the same order. 69 | uint8_t search(uint8_t *newAddr); 70 | }; 71 | ///@brief Class for temperature sensor 72 | class MeTemperature:public MePort{ 73 | public: 74 | MeTemperature(); 75 | MeTemperature(uint8_t port); 76 | MeTemperature(uint8_t port,uint8_t slot); 77 | void reset(uint8_t port, uint8_t slot); 78 | ///@brief get the celsius of temperature 79 | float temperature(); 80 | private: 81 | MeOneWire _ts; 82 | }; 83 | #endif 84 | -------------------------------------------------------------------------------- /mblock_firmware/MeUltrasonic.cpp: -------------------------------------------------------------------------------- 1 | #include "MeUltrasonic.h" 2 | /* UltrasonicSenser */ 3 | MeUltrasonic::MeUltrasonic(): MePort(0) 4 | { 5 | } 6 | MeUltrasonic::MeUltrasonic(uint8_t port): MePort(port) 7 | { 8 | } 9 | 10 | double MeUltrasonic::distanceCm(uint16_t maxCm) 11 | { 12 | long distance = measure(maxCm * 55 + 200); 13 | return (double)distance / 58.0; 14 | } 15 | 16 | double MeUltrasonic::distanceInch(uint16_t maxInch) 17 | { 18 | long distance = measure(maxInch * 145 + 200); 19 | return (double)(distance / 148.0); 20 | } 21 | 22 | double MeUltrasonic::distanceCm(){ 23 | return distanceCm(400); 24 | } 25 | double MeUltrasonic::distanceInch(){ 26 | return distanceInch(5); 27 | } 28 | long MeUltrasonic::measure(unsigned long timeout) 29 | { 30 | long duration; 31 | MePort::dWrite2(LOW); 32 | delayMicroseconds(2); 33 | MePort::dWrite2(HIGH); 34 | delayMicroseconds(10); 35 | MePort::dWrite2(LOW); 36 | pinMode(s2, INPUT); 37 | duration = pulseIn(s2, HIGH, timeout); 38 | return duration; 39 | } 40 | -------------------------------------------------------------------------------- /mblock_firmware/MeUltrasonic.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef MEULTRASONIC_H_ 3 | #define MEULTRASONIC_H_ 4 | #include "MePort.h" 5 | ///@brief Class for Ultrasonic Sensor Module 6 | class MeUltrasonic: public MePort 7 | { 8 | public : 9 | MeUltrasonic(); 10 | MeUltrasonic(uint8_t port); 11 | double distanceCm(); 12 | double distanceInch(); 13 | double distanceCm(uint16_t maxCm); 14 | double distanceInch(uint16_t maxInch); 15 | long measure(unsigned long timeout); 16 | }; 17 | #endif 18 | -------------------------------------------------------------------------------- /mblock_firmware/MeWire.cpp: -------------------------------------------------------------------------------- 1 | #include "MeWire.h" 2 | /* Wire */ 3 | MeWire::MeWire(uint8_t address): MePort() 4 | { 5 | _slaveAddress = address + 1; 6 | } 7 | MeWire::MeWire(uint8_t port, uint8_t address): MePort(port) 8 | { 9 | _slaveAddress = address + 1; 10 | } 11 | void MeWire::begin() 12 | { 13 | delay(1000); 14 | Wire.begin(); 15 | write(BEGIN_FLAG, 0x01); 16 | } 17 | bool MeWire::isRunning() 18 | { 19 | return read(BEGIN_STATE); 20 | } 21 | void MeWire::setI2CBaseAddress(uint8_t baseAddress) 22 | { 23 | byte w[2] = {0}; 24 | byte r[4] = {0}; 25 | w[0] = 0x21; 26 | w[1] = baseAddress; 27 | request(w, r, 2, 4); 28 | } 29 | 30 | byte MeWire::read(byte dataAddress) 31 | { 32 | byte *b = {0}; 33 | read(dataAddress, b, 1); 34 | return b[0]; 35 | } 36 | 37 | void MeWire::read(byte dataAddress, uint8_t *buf, int len) 38 | { 39 | byte rxByte; 40 | Wire.beginTransmission(_slaveAddress); // transmit to device 41 | Wire.write(dataAddress); // sends one byte 42 | Wire.endTransmission(); // stop transmitting 43 | delayMicroseconds(1); 44 | Wire.requestFrom(_slaveAddress, len); // request 6 bytes from slave device 45 | int index = 0; 46 | while(Wire.available()) // slave may send less than requested 47 | { 48 | rxByte = Wire.read(); // receive a byte as character 49 | buf[index] = rxByte; 50 | index++; 51 | } 52 | } 53 | 54 | void MeWire::write(byte dataAddress, byte data) 55 | { 56 | Wire.beginTransmission(_slaveAddress); // transmit to device 57 | Wire.write(dataAddress); // sends one byte 58 | Wire.endTransmission(); // stop transmitting 59 | 60 | Wire.beginTransmission(_slaveAddress); // transmit to device 61 | Wire.write(data); // sends one byte 62 | Wire.endTransmission(); // stop transmitting 63 | } 64 | void MeWire::request(byte *writeData, byte *readData, int wlen, int rlen) 65 | { 66 | 67 | uint8_t rxByte; 68 | uint8_t index = 0; 69 | 70 | Wire.beginTransmission(_slaveAddress); // transmit to device 71 | 72 | Wire.write(writeData, wlen); 73 | 74 | Wire.endTransmission(); 75 | delayMicroseconds(2); 76 | Wire.requestFrom(_slaveAddress, rlen); // request 6 bytes from slave device 77 | delayMicroseconds(2); 78 | while(Wire.available()) // slave may send less than requested 79 | { 80 | rxByte = Wire.read(); // receive a byte as character 81 | 82 | readData[index] = rxByte; 83 | index++; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /mblock_firmware/MeWire.h: -------------------------------------------------------------------------------- 1 | #ifndef MeWire_h 2 | #define MeWire_h 3 | #include 4 | #include "MePort.h" 5 | //Wire Setup 6 | #define BEGIN_FLAG 0x1E 7 | #define BEGIN_STATE 0x91 8 | ///@brief class of MeWire 9 | class MeWire: public MePort 10 | { 11 | public: 12 | MeWire(uint8_t address); 13 | ///@brief initialize 14 | ///@param port port number of device 15 | MeWire(uint8_t port, uint8_t address); 16 | ///@brief reset start index of i2c slave address. 17 | void setI2CBaseAddress(uint8_t baseAddress); 18 | bool isRunning(); 19 | ///@brief Initiate the Wire library and join the I2C bus as a master or slave. This should normally be called only once. 20 | ///@param address the 7-bit slave address (optional); if not specified, join the bus as a master. 21 | void begin(); 22 | ///@brief send one byte data request for read one byte from slave address. 23 | byte read(byte dataAddress); 24 | void read(byte dataAddress, uint8_t *buf, int len); 25 | ///@brief send one byte data request for write one byte to slave address. 26 | void write(byte dataAddress, byte data); 27 | void request(byte *writeData, byte *readData, int wlen, int rlen); 28 | protected: 29 | int _slaveAddress; 30 | }; 31 | #endif 32 | -------------------------------------------------------------------------------- /mbot_firmware/Me7SegmentDisplay.cpp: -------------------------------------------------------------------------------- 1 | #include "Me7SegmentDisplay.h" 2 | 3 | static int8_t TubeTab[] = {0x3f, 0x06, 0x5b, 0x4f, 4 | 0x66, 0x6d, 0x7d, 0x07, 5 | 0x7f, 0x6f, 0x77, 0x7c, 6 | 0x39, 0x5e, 0x79, 0x71, 7 | 0xbf, 0x86, 0xdb, 0xcf, 8 | 0xe6, 0xed, 0xfd, 0x87, 9 | 0xff, 0xef, 0xf7, 0xfc, 10 | 0xb9, 0xde, 0xf9, 0xf1, 0, 0x40 11 | };//0~9,A,b,C,d,E,F,'',- 12 | Me7SegmentDisplay::Me7SegmentDisplay(): MePort() 13 | { 14 | } 15 | Me7SegmentDisplay::Me7SegmentDisplay(uint8_t dataPin,uint8_t clkPin) 16 | { 17 | s1 = dataPin; 18 | s2 = clkPin; 19 | pinMode(s2, OUTPUT); 20 | pinMode(s1, OUTPUT); 21 | set(); 22 | clearDisplay(); 23 | } 24 | Me7SegmentDisplay::Me7SegmentDisplay(MEPORT port): MePort(port) 25 | { 26 | pinMode(s2, OUTPUT); 27 | pinMode(s1, OUTPUT); 28 | set(); 29 | clearDisplay(); 30 | } 31 | void Me7SegmentDisplay::reset(MEPORT port) 32 | { 33 | reset(port); 34 | s2 = s2; 35 | s1 = s1; 36 | pinMode(s2, OUTPUT); 37 | pinMode(s1, OUTPUT); 38 | set(); 39 | clearDisplay(); 40 | } 41 | void Me7SegmentDisplay::init(void) 42 | { 43 | clearDisplay(); 44 | } 45 | 46 | void Me7SegmentDisplay::writeByte(int8_t wr_data) 47 | { 48 | uint8_t i, count1; 49 | for(i = 0; i < 8; i++) //sent 8bit data 50 | { 51 | digitalWrite(s2, LOW); 52 | if(wr_data & 0x01)digitalWrite(s1, HIGH); //LSB first 53 | else digitalWrite(s1, LOW); 54 | wr_data >>= 1; 55 | digitalWrite(s2, HIGH); 56 | 57 | } 58 | digitalWrite(s2, LOW); //wait for the ACK 59 | digitalWrite(s1, HIGH); 60 | digitalWrite(s2, HIGH); 61 | pinMode(s1, INPUT); 62 | while(digitalRead(s1)) 63 | { 64 | count1 += 1; 65 | if(count1 == 200)// 66 | { 67 | pinMode(s1, OUTPUT); 68 | digitalWrite(s1, LOW); 69 | count1 = 0; 70 | } 71 | //pinMode(s1,INPUT); 72 | } 73 | pinMode(s1, OUTPUT); 74 | 75 | } 76 | //send start signal to TM1637 77 | void Me7SegmentDisplay::start(void) 78 | { 79 | digitalWrite(s2, HIGH); //send start signal to TM1637 80 | digitalWrite(s1, HIGH); 81 | digitalWrite(s1, LOW); 82 | digitalWrite(s2, LOW); 83 | } 84 | //End of transmission 85 | void Me7SegmentDisplay::stop(void) 86 | { 87 | digitalWrite(s2, LOW); 88 | digitalWrite(s1, LOW); 89 | digitalWrite(s2, HIGH); 90 | digitalWrite(s1, HIGH); 91 | } 92 | 93 | 94 | void Me7SegmentDisplay::display(uint16_t value) 95 | { 96 | display((int)value); 97 | // display((double)value,0); 98 | } 99 | 100 | void Me7SegmentDisplay::display(int16_t value) 101 | { 102 | display((double)value, 0); 103 | } 104 | 105 | void Me7SegmentDisplay::display(double value, uint8_t digits) 106 | { 107 | 108 | 109 | AA: 110 | int8_t buf[4] = {' ', ' ', ' ', ' '}; 111 | int8_t tempBuf[4]; 112 | uint8_t b = 0; 113 | uint8_t bit_num = 0; 114 | uint8_t int_num = 0; 115 | uint8_t isNeg = 0; 116 | double number = value; 117 | if (number >= 9999.5 || number <= -999.5); 118 | else 119 | { 120 | // Handle negative numbers 121 | if (number < 0.0) 122 | { 123 | number = -number; 124 | isNeg = 1 ; 125 | } 126 | // Round correctly so that print(1.999, 2) prints as "2.00" 127 | double rounding = 0.5; 128 | for (uint8_t i = 0; i < digits; ++i) 129 | rounding /= 10.0; 130 | number += rounding; 131 | 132 | // Extract the integer part of the number and print it 133 | uint16_t int_part = (uint16_t )number; 134 | double remainder = number - (double)int_part; 135 | do 136 | { 137 | uint16_t m = int_part; 138 | int_part /= 10; 139 | char c = m - 10 * int_part; 140 | tempBuf[int_num] = c; 141 | int_num++; 142 | } 143 | while(int_part); 144 | 145 | bit_num = isNeg + int_num + digits; 146 | 147 | if(bit_num > 4) 148 | { 149 | bit_num = 4; 150 | digits = 4 - (isNeg + int_num); 151 | goto AA; 152 | } 153 | b = 4 - bit_num; 154 | if(isNeg)buf[b++] = 0x21; 155 | 156 | for(uint8_t i = int_num; i > 0; i--)buf[b++] = tempBuf[i-1]; 157 | // Print the decimal point, but only if there are digits beyond 158 | if (digits > 0) 159 | { 160 | buf[b-1] += 0x10; 161 | // Extract digits from the remainder one at a time 162 | while (digits-- > 0) 163 | { 164 | remainder *= 10.0; 165 | int toPrint = int(remainder); 166 | buf[b++] = toPrint; 167 | remainder -= toPrint; 168 | } 169 | } 170 | } 171 | display(buf); 172 | } 173 | 174 | void Me7SegmentDisplay::write(int8_t SegData[]) 175 | { 176 | uint8_t i; 177 | start(); //start signal sent to TM1637 from MCU 178 | writeByte(ADDR_AUTO); 179 | stop(); 180 | start(); 181 | writeByte(Cmd_SetAddr); 182 | for(i = 0; i < 4; i ++) 183 | { 184 | writeByte(SegData[i]); 185 | } 186 | stop(); 187 | start(); 188 | writeByte(Cmd_DispCtrl); 189 | stop(); 190 | } 191 | void Me7SegmentDisplay::write(uint8_t BitAddr, int8_t SegData) 192 | { 193 | start(); //start signal sent to TM1637 from MCU 194 | writeByte(ADDR_FIXED); 195 | stop(); 196 | start(); 197 | writeByte(BitAddr | 0xc0); 198 | writeByte(SegData); 199 | stop(); 200 | start(); 201 | writeByte(Cmd_DispCtrl); 202 | stop(); 203 | } 204 | void Me7SegmentDisplay::display(int8_t DispData[]) 205 | { 206 | int8_t SegData[4]; 207 | uint8_t i; 208 | for(i = 0; i < 4; i ++) 209 | { 210 | SegData[i] = DispData[i]; 211 | } 212 | coding(SegData); 213 | write(SegData); 214 | } 215 | //****************************************** 216 | void Me7SegmentDisplay::display(uint8_t BitAddr, int8_t DispData) 217 | { 218 | int8_t SegData; 219 | 220 | if((DispData >= 'A' && DispData <= 'F'))DispData = DispData - 'A' + 10; 221 | else if((DispData >= 'a' && DispData <= 'f'))DispData = DispData - 'a' + 10; 222 | SegData = coding(DispData); 223 | write(BitAddr, SegData); // 224 | } 225 | 226 | void Me7SegmentDisplay::clearDisplay(void) 227 | { 228 | int8_t buf[4] = {' ', ' ', ' ', ' '}; 229 | display(buf); 230 | } 231 | //To take effect the next time it displays. 232 | void Me7SegmentDisplay::set(uint8_t brightness, uint8_t SetData, uint8_t SetAddr) 233 | { 234 | Cmd_SetData = SetData; 235 | Cmd_SetAddr = SetAddr; 236 | Cmd_DispCtrl = 0x88 + brightness;//Set the brightness and it takes effect the next time it displays. 237 | } 238 | 239 | 240 | void Me7SegmentDisplay::coding(int8_t DispData[]) 241 | { 242 | // uint8_t PointData = 0; 243 | for(uint8_t i = 0; i < 4; i ++) 244 | { 245 | DispData[i] = TubeTab[DispData[i]]; 246 | } 247 | } 248 | int8_t Me7SegmentDisplay::coding(int8_t DispData) 249 | { 250 | // uint8_t PointData = 0; 251 | DispData = TubeTab[DispData] ;//+ PointData; 252 | return DispData; 253 | } 254 | -------------------------------------------------------------------------------- /mbot_firmware/Me7SegmentDisplay.h: -------------------------------------------------------------------------------- 1 | #ifndef Me7SegmentDisplay_H 2 | #define Me7SegmentDisplay_H 3 | #include "MePort.h" 4 | //************definitions for TM1637********************* 5 | #define ADDR_AUTO 0x40 6 | #define ADDR_FIXED 0x44 7 | #define STARTADDR 0xc0 8 | /**** definitions for the clock point of the digit tube *******/ 9 | #define POINT_ON 1 10 | #define POINT_OFF 0 11 | /**************definitions for brightness***********************/ 12 | #define BRIGHT_DARKEST 0 13 | #define BRIGHT_TYPICAL 2 14 | #define BRIGHTEST 7 15 | ///@brief Class for numeric display module 16 | class Me7SegmentDisplay:public MePort 17 | { 18 | public: 19 | Me7SegmentDisplay(); 20 | Me7SegmentDisplay(uint8_t dataPin,uint8_t clkPin); 21 | Me7SegmentDisplay(MEPORT port); 22 | void init(void); //To clear the display 23 | void set(uint8_t = BRIGHT_TYPICAL,uint8_t = 0x40,uint8_t = 0xc0);//To take effect the next time it displays. 24 | void reset(MEPORT port); 25 | void write(int8_t SegData[]); 26 | void write(uint8_t BitAddr, int8_t SegData); 27 | void display(uint16_t value); 28 | void display(int16_t value); 29 | void display(double value, uint8_t = 1) ; 30 | void display(int8_t DispData[]); 31 | void display(uint8_t BitAddr, int8_t DispData); 32 | void clearDisplay(void); 33 | private: 34 | uint8_t Cmd_SetData; 35 | uint8_t Cmd_SetAddr; 36 | uint8_t Cmd_DispCtrl; 37 | boolean _PointFlag; //_PointFlag=1:the clock point on 38 | void writeByte(int8_t wr_data);//write 8bit data to tm1637 39 | void start(void);//send start bits 40 | void stop(void); //send stop bits 41 | void point(boolean PointFlag);//whether to light the clock point ":".To take effect the next time it displays. 42 | void coding(int8_t DispData[]); 43 | int8_t coding(int8_t DispData); 44 | int checkNum(float v,int b); 45 | uint8_t _clkPin; 46 | uint8_t _dataPin; 47 | }; 48 | #endif 49 | -------------------------------------------------------------------------------- /mbot_firmware/MeBuzzer.cpp: -------------------------------------------------------------------------------- 1 | #include "MeBuzzer.h" 2 | 3 | uint8_t buzzer_pin; 4 | volatile long timer2_toggle_count; 5 | volatile uint8_t *timer2_pin_port; 6 | volatile uint8_t timer2_pin_mask; 7 | 8 | // timer in CTC mode 9 | // Set the OCR for the given timer, 10 | // set the toggle count, 11 | // then turn on the interrupts 12 | // OCR2A = ocr; 13 | void Timer2Init(uint32_t TimerFreq) 14 | { 15 | 16 | static const uint16_t pscLst_alt[] = {0, 1, 8, 32, 64, 128, 256, 1024}; 17 | 18 | //Set frequency of timer2 19 | //setting the waveform generation mode 20 | uint8_t wgm = 2; 21 | TCCR2A = 0; 22 | TCCR2B = 0; 23 | TCCR2A = (TCCR2A & B11111100) | (wgm & 3); 24 | TCCR2B = (TCCR2B & B11110111) | ((wgm & 12) << 1); 25 | 26 | uint16_t multiplier = F_CPU / 2 / TimerFreq / 256; 27 | byte iterate = 0; 28 | while(multiplier > pscLst_alt[++iterate]); 29 | multiplier = pscLst_alt[iterate]; 30 | OCR2A = F_CPU/2/TimerFreq/ multiplier-1; 31 | TCCR2B = (TCCR2B & ~7) | (iterate & 7); 32 | 33 | //enable interrupt 34 | bitSet(TIMSK2, OCIE2B); 35 | } 36 | 37 | MeBuzzer::MeBuzzer() 38 | { 39 | buzzer_pin = 8; 40 | } 41 | MeBuzzer::MeBuzzer(uint8_t pin) 42 | { 43 | buzzer_pin = pin; 44 | } 45 | MeBuzzer::MeBuzzer(MEPORT port):MePort(port) 46 | { 47 | buzzer_pin = s2; 48 | } 49 | 50 | MeBuzzer::MeBuzzer(MEPORT port, uint8_t slot):MePort(port) 51 | { 52 | buzzer_pin = s2; 53 | if(slot == SLOT2) 54 | { 55 | buzzer_pin = s2; 56 | }else 57 | { 58 | buzzer_pin = s1; 59 | } 60 | } 61 | 62 | // frequency (in hertz) and duration (in milliseconds). 63 | void MeBuzzer::tone(uint16_t frequency, uint32_t duration) 64 | { 65 | uint8_t prescalarbits = 0b001; 66 | long toggle_count = 0; 67 | uint32_t ocr = 0; 68 | timer2_pin_port = portOutputRegister(digitalPinToPort(buzzer_pin)); 69 | timer2_pin_mask = digitalPinToBitMask(buzzer_pin); 70 | // Set the pinMode as OUTPUT 71 | pinMode(buzzer_pin, OUTPUT); 72 | // Calculate the toggle count 73 | if (duration > 0) 74 | { 75 | toggle_count = 2 * frequency * duration / 1000; 76 | } 77 | else 78 | { 79 | toggle_count = -1; 80 | } 81 | 82 | timer2_toggle_count = toggle_count; 83 | Timer2Init(frequency); 84 | } 85 | 86 | void MeBuzzer::noTone() 87 | { 88 | bitWrite(TIMSK2, OCIE2B, 0); // disable interrupt 89 | digitalWrite(buzzer_pin, LOW); 90 | } 91 | 92 | ISR(TIMER2_COMPB_vect) 93 | { 94 | 95 | if (timer2_toggle_count != 0) 96 | { 97 | // toggle the pin 98 | *timer2_pin_port ^= timer2_pin_mask; 99 | 100 | if (timer2_toggle_count > 0) 101 | timer2_toggle_count--; 102 | } 103 | else 104 | { 105 | bitWrite(TIMSK2, OCIE2B, 0); // disable interrupt 106 | digitalWrite(buzzer_pin, LOW); 107 | } 108 | } -------------------------------------------------------------------------------- /mbot_firmware/MeBuzzer.h: -------------------------------------------------------------------------------- 1 | #ifndef MeBuzzer_H 2 | #define MeBuzzer_H 3 | 4 | #include "MePort.h" 5 | 6 | ///@brief Class for MeBuzzer module 7 | class MeBuzzer : public MePort 8 | { 9 | public: 10 | MeBuzzer(); 11 | MeBuzzer(uint8_t pin); 12 | MeBuzzer(MEPORT port); 13 | MeBuzzer(MEPORT port, uint8_t slot); 14 | void tone(uint16_t frequency, uint32_t duration = 0); 15 | void noTone(); 16 | }; 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /mbot_firmware/MeDCMotor.cpp: -------------------------------------------------------------------------------- 1 | #include "MeDCMotor.h" 2 | MeDCMotor::MeDCMotor(): MePort(PORT_0) 3 | { 4 | 5 | } 6 | MeDCMotor::MeDCMotor(MEPORT port): MePort(port) 7 | { 8 | pinMode(_dirPin,OUTPUT); 9 | } 10 | 11 | MeDCMotor::MeDCMotor(uint8_t pwmPin,uint8_t dirPin) 12 | { 13 | s1 = pwmPin; 14 | s2 = dirPin; 15 | pinMode(s2,OUTPUT); 16 | } 17 | void MeDCMotor::run(int speed) 18 | { 19 | speed = speed > 255 ? 255 : speed; 20 | speed = speed < -255 ? -255 : speed; 21 | // constrain(speed,-255,255); 22 | if(speed >= 0) { 23 | pinMode(s1,OUTPUT); 24 | pinMode(s2,OUTPUT); 25 | digitalWrite(s2,HIGH); 26 | analogWrite(s1,speed); 27 | // MePort::dWrite2(HIGH); 28 | // MePort::aWrite1(speed); 29 | } else { 30 | pinMode(s1,OUTPUT); 31 | pinMode(s2,OUTPUT); 32 | digitalWrite(s2,LOW); 33 | analogWrite(s1,-speed); 34 | // MePort::dWrite2(LOW); 35 | // MePort::aWrite1(-speed); 36 | } 37 | } 38 | void MeDCMotor::stop() 39 | { 40 | MeDCMotor::run(0); 41 | } 42 | -------------------------------------------------------------------------------- /mbot_firmware/MeDCMotor.h: -------------------------------------------------------------------------------- 1 | #ifndef MEDCMOTOR_H_ 2 | #define MEDCMOTOR_H_ 3 | #include "MePort.h" 4 | ///@brief Class for DC Motor Module 5 | class MeDCMotor: public MePort 6 | { 7 | public: 8 | MeDCMotor(); 9 | MeDCMotor(MEPORT port); 10 | MeDCMotor(uint8_t pwmPin,uint8_t dirPin); 11 | void run(int speed); 12 | void stop(); 13 | private: 14 | uint8_t _dirPin; 15 | uint8_t _pwmPin; 16 | }; 17 | #endif 18 | -------------------------------------------------------------------------------- /mbot_firmware/MeIR.cpp: -------------------------------------------------------------------------------- 1 | #include "MeIR.h" 2 | 3 | // Provides ISR 4 | #include 5 | 6 | volatile irparams_t irparams; 7 | bool MATCH(uint8_t measured_ticks, uint8_t desired_us) 8 | { 9 | // Serial.print(measured_ticks);Serial.print(",");Serial.println(desired_us); 10 | return(measured_ticks >= desired_us - (desired_us>>2)-1 && measured_ticks <= desired_us + (desired_us>>2)+1);//判断前后25%的误差 11 | } 12 | 13 | ISR(TIMER_INTR_NAME) 14 | { 15 | uint8_t irdata = (uint8_t)digitalRead(2); 16 | // uint32_t new_time = micros(); 17 | // uint8_t timer = (new_time - irparams.lastTime)>>6; 18 | irparams.timer++; // One more 50us tick 19 | if (irparams.rawlen >= RAWBUF) { 20 | // Buffer overflow 21 | irparams.rcvstate = STATE_STOP; 22 | } 23 | switch(irparams.rcvstate) { 24 | case STATE_IDLE: // In the middle of a gap 25 | if (irdata == MARK) { 26 | irparams.rawlen = 0; 27 | irparams.timer = 0; 28 | irparams.rcvstate = STATE_MARK; 29 | } 30 | break; 31 | case STATE_MARK: // timing MARK 32 | if (irdata == SPACE) { // MARK ended, record time 33 | irparams.rawbuf[irparams.rawlen++] = irparams.timer; 34 | irparams.timer = 0; 35 | irparams.rcvstate = STATE_SPACE; 36 | } 37 | break; 38 | case STATE_SPACE: // timing SPACE 39 | if (irdata == MARK) { // SPACE just ended, record it 40 | irparams.rawbuf[irparams.rawlen++] = irparams.timer; 41 | irparams.timer = 0; 42 | irparams.rcvstate = STATE_MARK; 43 | } 44 | else { // SPACE 45 | if (irparams.timer > GAP_TICKS) { 46 | // big SPACE, indicates gap between codes 47 | // Mark current code as ready for processing 48 | // Switch to STOP 49 | // Don't reset timer; keep counting space width 50 | irparams.rcvstate = STATE_STOP; 51 | } 52 | } 53 | break; 54 | case STATE_STOP: // waiting, measuring gap 55 | if (irdata == MARK) { // reset gap timer 56 | irparams.timer = 0; 57 | } 58 | break; 59 | } 60 | // irparams.lastTime = new_time; 61 | } 62 | 63 | MeIR::MeIR() 64 | { 65 | pinMode(2,INPUT); 66 | // attachInterrupt(INT0, irISR, CHANGE); 67 | begin(); 68 | pinMode(3, OUTPUT); 69 | digitalWrite(3, LOW); // When not sending PWM, we want it low 70 | } 71 | 72 | void MeIR::begin() 73 | { 74 | cli(); 75 | // setup pulse clock timer interrupt 76 | //Prescale /8 (16M/8 = 0.5 microseconds per tick) 77 | // Therefore, the timer interval can range from 0.5 to 128 microseconds 78 | // depending on the reset value (255 to 0) 79 | TIMER_CONFIG_NORMAL(); 80 | 81 | //Timer2 Overflow Interrupt Enable 82 | TIMER_ENABLE_INTR; 83 | 84 | // TIMER_RESET; 85 | 86 | sei(); // enable interrupts 87 | 88 | // initialize state machine variables 89 | irparams.rcvstate = STATE_IDLE; 90 | irparams.rawlen = 0; 91 | 92 | lastIRTime = 0.0; 93 | irDelay = 0; 94 | irIndex = 0; 95 | irRead = 0; 96 | irReady = false; 97 | irBuffer = ""; 98 | irPressed = false; 99 | // set pin modes 100 | // pinMode(2, INPUT); 101 | // pinMode(irparams.recvpin, INPUT); 102 | } 103 | 104 | void MeIR::end() { 105 | EIMSK &= ~(1 << INT0); 106 | } 107 | 108 | 109 | 110 | 111 | // Decodes the received IR message 112 | // Returns 0 if no data ready, 1 if data ready. 113 | // Results of decoding are stored in results 114 | ErrorStatus MeIR::decode() { 115 | rawbuf = irparams.rawbuf; 116 | rawlen = irparams.rawlen; 117 | // if(irparams.rcvstate == STATE_SPACE) 118 | // { 119 | // uint32_t time = micros() -irparams.lastTime; 120 | // if(time> _GAP && time < _GAP+1000) 121 | // { 122 | // irparams.rcvstate = STATE_STOP; 123 | // } 124 | // } 125 | if (irparams.rcvstate != STATE_STOP) { 126 | return ERROR; 127 | } 128 | 129 | if (decodeNEC()) { 130 | begin(); 131 | return SUCCESS; 132 | } 133 | begin(); 134 | return ERROR; 135 | } 136 | 137 | // NECs have a repeat only 4 items long 138 | ErrorStatus MeIR::decodeNEC() { 139 | uint32_t data = 0; 140 | int offset = 0; // Skip first space 141 | // Initial mark 142 | if (!MATCH(rawbuf[offset], NEC_HDR_MARK/50)) { 143 | return ERROR; 144 | } 145 | offset++; 146 | // Check for repeat 147 | if (rawlen == 3 && 148 | MATCH(rawbuf[offset], NEC_RPT_SPACE/50) && 149 | MATCH(rawbuf[offset+1], NEC_BIT_MARK/50)) { 150 | bits = 0; 151 | // results->value = REPEAT; 152 | // Serial.println("REPEAT"); 153 | decode_type = NEC; 154 | return SUCCESS; 155 | } 156 | if (rawlen < 2 * NEC_BITS + 3) { 157 | return ERROR; 158 | } 159 | // Initial space 160 | if (!MATCH(rawbuf[offset], NEC_HDR_SPACE/50)) { 161 | return ERROR; 162 | } 163 | offset++; 164 | for (int i = 0; i < NEC_BITS; i++) { 165 | if (!MATCH(rawbuf[offset], NEC_BIT_MARK/50)) { 166 | return ERROR; 167 | } 168 | offset++; 169 | if (MATCH(rawbuf[offset], NEC_ONE_SPACE/50)) { 170 | //data = (data << 1) | 1; 171 | data = (data >> 1) | 0x80000000; 172 | } 173 | else if (MATCH(rawbuf[offset], NEC_ZERO_SPACE/50)) { 174 | //data <<= 1; 175 | data >>= 1; 176 | } 177 | else { 178 | return ERROR; 179 | 180 | } 181 | offset++; 182 | } 183 | // Success 184 | bits = NEC_BITS; 185 | value = data; 186 | decode_type = NEC; 187 | return SUCCESS; 188 | } 189 | 190 | void MeIR::mark(uint16_t us) { 191 | // Sends an IR mark for the specified number of microseconds. 192 | // The mark output is modulated at the PWM frequency. 193 | TIMER_ENABLE_PWM; // Enable pin 3 PWM output 194 | delayMicroseconds(us); 195 | } 196 | 197 | /* Leave pin off for time (given in microseconds) */ 198 | void MeIR::space(uint16_t us) { 199 | // Sends an IR space for the specified number of microseconds. 200 | // A space is no output, so the PWM output is disabled. 201 | TIMER_DISABLE_PWM; // Disable pin 3 PWM output 202 | delayMicroseconds(us); 203 | } 204 | 205 | void MeIR::enableIROut(uint8_t khz) { 206 | TIMER_DISABLE_INTR; //Timer2 disable Interrupt 207 | TIMER_CONFIG_KHZ(khz); 208 | } 209 | 210 | void MeIR::sendRaw(unsigned int buf[], int len, uint8_t hz) 211 | { 212 | enableIROut(hz); 213 | for (int i = 0; i < len; i++) { 214 | if (i & 1) { 215 | space(buf[i]); 216 | } 217 | else { 218 | mark(buf[i]); 219 | } 220 | } 221 | space(0); // Just to be sure 222 | } 223 | String MeIR::getString(){ 224 | if(decode()) 225 | { 226 | irRead = ((value>>8)>>8)&0xff; 227 | if(irRead==0xa||irRead==0xd){ 228 | irIndex = 0; 229 | irReady = true; 230 | }else{ 231 | irBuffer+=irRead; 232 | irIndex++; 233 | } 234 | irDelay = 0; 235 | }else{ 236 | irDelay++; 237 | if(irRead>0){ 238 | if(irDelay>5000){ 239 | irRead = 0; 240 | irDelay = 0; 241 | } 242 | } 243 | } 244 | if(irReady){ 245 | irReady = false; 246 | String s = String(irBuffer); 247 | irBuffer = ""; 248 | return s; 249 | } 250 | return ""; 251 | } 252 | unsigned char MeIR::getCode(){ 253 | if(decode()) 254 | { 255 | irRead = ((value>>8)>>8)&0xff; 256 | } 257 | return irRead; 258 | } 259 | void MeIR::sendString(String s){ 260 | unsigned long l; 261 | for(int i=0;i>= 1; 288 | } 289 | mark(NEC_BIT_MARK); 290 | space(0); 291 | } 292 | void MeIR::loop(){ 293 | if(decode()) 294 | { 295 | irRead = ((value>>8)>>8)&0xff; 296 | lastIRTime = millis()/1000.0; 297 | irPressed = true; 298 | if(irRead==0xa||irRead==0xd){ 299 | irIndex = 0; 300 | irReady = true; 301 | }else{ 302 | irBuffer+=irRead; 303 | irIndex++; 304 | if(irIndex>64){ 305 | irIndex = 0; 306 | irBuffer = ""; 307 | } 308 | } 309 | irDelay = 0; 310 | }else{ 311 | irDelay++; 312 | if(irRead>0){ 313 | if(irDelay>5000){ 314 | irRead = 0; 315 | irDelay = 0; 316 | } 317 | } 318 | } 319 | } 320 | boolean MeIR::keyPressed(unsigned char r){ 321 | irIndex = 0; 322 | if(millis()/1000.0-lastIRTime>0.2){ 323 | return false; 324 | } 325 | return irRead==r; 326 | } 327 | -------------------------------------------------------------------------------- /mbot_firmware/MeIR.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef MeIR_h 4 | #define MeIR_h 5 | 6 | #define MARK 0 7 | #define SPACE 1 8 | #define NEC_BITS 32 9 | 10 | #define USECPERTICK 50 // microseconds per clock interrupt tick 11 | #define RAWBUF 100 // Length of raw duration buffer 12 | 13 | typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; 14 | 15 | #define NEC_HDR_MARK 9000 16 | #define NEC_HDR_SPACE 4500 17 | #define NEC_BIT_MARK 560 18 | #define NEC_ONE_SPACE 1600 19 | #define NEC_ZERO_SPACE 560 20 | #define NEC_RPT_SPACE 2250 21 | #define NEC_RPT_PERIOD 110000 22 | 23 | 24 | // #define TOLERANCE 25 // percent tolerance in measurements 25 | // #define LTOL (1.0 - TOLERANCE/100.) 26 | // #define UTOL (1.0 + TOLERANCE/100.) 27 | 28 | #define _GAP 5000 // Minimum map between transmissions 29 | // #define GAP_TICKS 5000//(_GAP/USECPERTICK) 30 | 31 | // #define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK)) 32 | // #define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1)) 33 | 34 | // receiver states 35 | #define STATE_IDLE 2 36 | #define STATE_MARK 3 37 | #define STATE_SPACE 4 38 | #define STATE_STOP 5 39 | 40 | 41 | // Values for decode_type 42 | #define NEC 1 43 | #define SONY 2 44 | #define RC5 3 45 | #define RC6 4 46 | #define DISH 5 47 | #define SHARP 6 48 | #define PANASONIC 7 49 | #define JVC 8 50 | #define SANYO 9 51 | #define MITSUBISHI 10 52 | #define SAMSUNG 11 53 | #define LG 12 54 | #define UNKNOWN -1 55 | 56 | #define TOPBIT 0x80000000 57 | 58 | 59 | #ifdef F_CPU 60 | #define SYSCLOCK F_CPU // main Arduino clock 61 | #else 62 | #define SYSCLOCK 16000000 // main Arduino clock 63 | #endif 64 | 65 | 66 | #define _GAP 5000 // Minimum map between transmissions 67 | #define GAP_TICKS (_GAP/USECPERTICK) 68 | 69 | 70 | #define TIMER_DISABLE_INTR (TIMSK2 = 0) 71 | #define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) 72 | #define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) 73 | #define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) 74 | #define TIMER_DISABLE_INTR (TIMSK2 = 0) 75 | #define TIMER_INTR_NAME TIMER2_COMPA_vect 76 | #define TIMER_CONFIG_KHZ(val) ({ \ 77 | const uint8_t pwmval = F_CPU / 2000 / (val); \ 78 | TCCR2A = _BV(WGM20); \ 79 | TCCR2B = _BV(WGM22) | _BV(CS20); \ 80 | OCR2A = pwmval; \ 81 | OCR2B = pwmval / 3; \ 82 | }) 83 | 84 | #define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) 85 | #if (TIMER_COUNT_TOP < 256) 86 | #define TIMER_CONFIG_NORMAL() ({ \ 87 | TCCR2A = _BV(WGM21); \ 88 | TCCR2B = _BV(CS20); \ 89 | OCR2A = TIMER_COUNT_TOP; \ 90 | TCNT2 = 0; \ 91 | }) 92 | #else 93 | #define TIMER_CONFIG_NORMAL() ({ \ 94 | TCCR2A = _BV(WGM21); \ 95 | TCCR2B = _BV(CS21); \ 96 | OCR2A = TIMER_COUNT_TOP / 8; \ 97 | TCNT2 = 0; \ 98 | }) 99 | #endif 100 | 101 | // information for the interrupt handler 102 | typedef struct { 103 | uint8_t recvpin; // pin for IR data from detector 104 | volatile uint8_t rcvstate; // state machine 105 | volatile uint32_t lastTime; 106 | unsigned int timer; // 107 | volatile uint8_t rawbuf[RAWBUF]; // raw data 108 | volatile uint8_t rawlen; // counter of entries in rawbuf 109 | } 110 | irparams_t; 111 | 112 | 113 | 114 | 115 | 116 | // main class for receiving IR 117 | class MeIR 118 | { 119 | public: 120 | MeIR(); 121 | 122 | 123 | ErrorStatus decode(); 124 | void begin(); 125 | void end(); 126 | void loop(); 127 | boolean keyPressed(unsigned char r); 128 | // void resume(); 129 | int8_t decode_type; // NEC, SONY, RC5, UNKNOWN 130 | unsigned long value; // Decoded value 131 | uint8_t bits; // Number of bits in decoded value 132 | volatile uint8_t *rawbuf; // Raw intervals in .5 us ticks 133 | int rawlen; // Number of records in rawbuf. 134 | String getString(); 135 | unsigned char getCode(); 136 | void sendString(String s); 137 | void sendString(float v); 138 | void sendNEC(unsigned long data, int nbits); 139 | void sendSony(unsigned long data, int nbits); 140 | // Neither Sanyo nor Mitsubishi send is implemented yet 141 | // void sendSanyo(unsigned long data, int nbits); 142 | // void sendMitsubishi(unsigned long data, int nbits); 143 | void sendRaw(unsigned int buf[], int len, uint8_t hz); 144 | void sendRC5(unsigned long data, int nbits); 145 | void sendRC6(unsigned long data, int nbits); 146 | void sendDISH(unsigned long data, int nbits); 147 | void sendSharp(unsigned int address, unsigned int command); 148 | void sendSharpRaw(unsigned long data, int nbits); 149 | void sendPanasonic(unsigned int address, unsigned long data); 150 | void sendJVC(unsigned long data, int nbits, int repeat); // *Note instead of sending the REPEAT constant if you want the JVC repeat signal sent, send the original code value and change the repeat argument from 0 to 1. JVC protocol repeats by skipping the header NOT by sending a separate code value like NEC does. 151 | // private: 152 | void sendSAMSUNG(unsigned long data, int nbits); 153 | void enableIROut(uint8_t khz); 154 | void mark(uint16_t us); 155 | void space(uint16_t us); 156 | private: 157 | // These are called by decode 158 | ErrorStatus decodeNEC(); 159 | int irDelay; 160 | int irIndex; 161 | char irRead; 162 | boolean irReady; 163 | boolean irPressed; 164 | String irBuffer; 165 | double lastIRTime; 166 | char floatString[5]; 167 | 168 | }; 169 | 170 | #endif 171 | -------------------------------------------------------------------------------- /mbot_firmware/MeInfraredReceiver.cpp: -------------------------------------------------------------------------------- 1 | #include "MeInfraredReceiver.h" 2 | 3 | MeInfraredReceiver::MeInfraredReceiver():MePort(){ 4 | 5 | } 6 | 7 | MeInfraredReceiver::MeInfraredReceiver(MEPORT port):MePort(port){ 8 | pinMode(s1,INPUT); 9 | pinMode(s2,INPUT); 10 | } 11 | int MeInfraredReceiver::available(){ 12 | char c = poll(); 13 | if(c>0){ 14 | _buffer = c; 15 | return 1; 16 | } 17 | return 0; 18 | } 19 | unsigned char MeInfraredReceiver::read(){ 20 | unsigned char c = _buffer; 21 | _buffer = 0; 22 | return c; 23 | } 24 | 25 | bool MeInfraredReceiver::buttonState(){ 26 | 27 | if(getPort()>0){ 28 | return dRead1()==0; 29 | } 30 | return 0; 31 | } 32 | unsigned char MeInfraredReceiver::poll() 33 | { 34 | //noInterrupts(); 35 | unsigned char val = 0; 36 | int bitDelay = 1000000.0/9600.0 - clockCyclesToMicroseconds(50); 37 | if (digitalRead(s2) == LOW) { 38 | for(int offset=0;offset<8;offset++){ 39 | delayMicroseconds(bitDelay); 40 | val |= digitalRead(s2) << offset; 41 | } 42 | delayMicroseconds(bitDelay); 43 | //interrupts(); 44 | return val&0xff; 45 | } 46 | //interrupts(); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /mbot_firmware/MeInfraredReceiver.h: -------------------------------------------------------------------------------- 1 | #ifndef MeInfraredReceiver_H_ 2 | #define MeInfraredReceiver_H_ 3 | #include "MePort.h" 4 | 5 | //NEC Code table 6 | #define IR_BUTTON_POWER 0x45 7 | #define IR_BUTTON_A 0x45 8 | #define IR_BUTTON_B 0x46 9 | #define IR_BUTTON_MENU 0x47 10 | #define IR_BUTTON_C 0x47 11 | #define IR_BUTTON_TEST 0x44 12 | #define IR_BUTTON_D 0x44 13 | #define IR_BUTTON_PLUS 0x40 14 | #define IR_BUTTON_UP 0x40 15 | #define IR_BUTTON_RETURN 0x43 16 | #define IR_BUTTON_E 0x43 17 | #define IR_BUTTON_PREVIOUS 0x07 18 | #define IR_BUTTON_LEFT 0x07 19 | #define IR_BUTTON_PLAY 0x15 20 | #define IR_BUTTON_SETTING 0x15 21 | #define IR_BUTTON_NEXT 0x09 22 | #define IR_BUTTON_RIGHT 0x09 23 | #define IR_BUTTON_MINUS 0x19 24 | #define IR_BUTTON_DOWN 0x19 25 | #define IR_BUTTON_CLR 0x0D 26 | #define IR_BUTTON_F 0x0D 27 | #define IR_BUTTON_0 0x16 28 | #define IR_BUTTON_1 0x0C 29 | #define IR_BUTTON_2 0x18 30 | #define IR_BUTTON_3 0x5E 31 | #define IR_BUTTON_4 0x08 32 | #define IR_BUTTON_5 0x1C 33 | #define IR_BUTTON_6 0x5A 34 | #define IR_BUTTON_7 0x42 35 | #define IR_BUTTON_8 0x52 36 | #define IR_BUTTON_9 0x4A 37 | 38 | class MeInfraredReceiver:public MePort{ 39 | public : 40 | MeInfraredReceiver(); 41 | MeInfraredReceiver(MEPORT port); 42 | int available(); 43 | unsigned char read(); 44 | unsigned char poll(); 45 | bool buttonState(); 46 | private: 47 | unsigned char _buffer; 48 | }; 49 | #endif 50 | -------------------------------------------------------------------------------- /mbot_firmware/MeOneWire.h: -------------------------------------------------------------------------------- 1 | #ifndef MeOneWire_h 2 | #define MeOneWire_h 3 | #include "MePort.h" 4 | #if defined(__AVR__) 5 | #define MePIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) 6 | #define MePIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 7 | #define MeIO_REG_TYPE uint8_t 8 | #define MeIO_REG_ASM asm("r30") 9 | #define MeDIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 10 | #define MeDIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)),((*((base)+2)) |= (mask))//INPUT_PULLUP 11 | #define MeDIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) 12 | #define MeDIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) 13 | #define MeDIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) 14 | #endif 15 | 16 | ///@brief Class for MeOneWire 17 | class MeOneWire 18 | { 19 | public: 20 | MeOneWire(); 21 | MeOneWire( uint8_t pin); 22 | bool readIO(void); 23 | void reset(uint8_t pin); 24 | // Perform a 1-Wire reset cycle. Returns 1 if a device responds 25 | // with a presence pulse. Returns 0 if there is no device or the 26 | // bus is shorted or otherwise held low for more than 250uS 27 | uint8_t reset(void); 28 | // Issue a 1-Wire rom select command, you do the reset first. 29 | void select(const uint8_t rom[8]); 30 | // Issue a 1-Wire rom skip command, to address all on bus. 31 | void skip(void); 32 | // Write a byte. If 'power' is one then the wire is held high at 33 | // the end for parasitically powered devices. You are responsible 34 | // for eventually depowering it by calling depower() or doing 35 | // another read or write. 36 | void write(uint8_t v, uint8_t power = 0); 37 | void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); 38 | // Read a byte. 39 | uint8_t read(void); 40 | void read_bytes(uint8_t *buf, uint16_t count); 41 | // Write a bit. The bus is always left powered at the end, see 42 | // note in write() about that. 43 | void write_bit(uint8_t v); 44 | // Read a bit. 45 | uint8_t read_bit(void); 46 | // Stop forcing power onto the bus. You only need to do this if 47 | // you used the 'power' flag to write() or used a write_bit() call 48 | // and aren't about to do another read or write. You would rather 49 | // not leave this powered if you don't have to, just in case 50 | // someone shorts your bus. 51 | void depower(void); 52 | // Clear the search state so that if will start from the beginning again. 53 | void reset_search(); 54 | // Setup the search to find the device type 'family_code' on the next call 55 | // to search(*newAddr) if it is present. 56 | void target_search(uint8_t family_code); 57 | // Look for the next device. Returns 1 if a new address has been 58 | // returned. A zero might mean that the bus is shorted, there are 59 | // no devices, or you have already retrieved all of them. It 60 | // might be a good idea to check the CRC to make sure you didn't 61 | // get garbage. The order is deterministic. You will always get 62 | // the same devices in the same order. 63 | uint8_t search(uint8_t *newAddr); 64 | 65 | private: 66 | MeIO_REG_TYPE bitmask; 67 | volatile MeIO_REG_TYPE *baseReg; 68 | // global search state 69 | unsigned char ROM_NO[8]; 70 | uint8_t LastDiscrepancy; 71 | uint8_t LastFamilyDiscrepancy; 72 | uint8_t LastDeviceFlag; 73 | }; 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /mbot_firmware/MePort.cpp: -------------------------------------------------------------------------------- 1 | #include "MePort.h" 2 | 3 | #if defined(__AVR_ATmega32U4__) //MeBaseBoard use ATmega32U4 as MCU 4 | 5 | MePort_Sig mePort[11] = {{NC, NC}, {11, A8}, {13, A11}, {10, 9}, {1, 0}, 6 | {MISO, SCK}, {A0, A1}, {A2, A3}, {A4, A5}, {6, 7}, {5, 4} 7 | }; 8 | #else // else ATmega328 9 | MePort_Sig mePort[11] = {{NC, NC}, {11, 10}, {3, 9}, {12, 13}, {8, 2}, 10 | {NC, NC}, {A2, A3}, {A6, A1}, {A7, A0}, {6, 7}, {5, 4} 11 | }; 12 | 13 | #endif 14 | 15 | union{ 16 | byte b[4]; 17 | float fVal; 18 | long lVal; 19 | }u; 20 | 21 | /* Port */ 22 | MePort::MePort(){ 23 | s1 = mePort[0].s1; 24 | s2 = mePort[0].s2; 25 | _port = 0; 26 | } 27 | MePort::MePort(MEPORT port) 28 | { 29 | s1 = mePort[port].s1; 30 | s2 = mePort[port].s2; 31 | _port = port; 32 | } 33 | MePort::MePort(MEPORT port,uint8_t slot) 34 | { 35 | s1 = mePort[port].s1; 36 | s2 = mePort[port].s2; 37 | _port = port; 38 | _slot = slot; 39 | } 40 | uint8_t MePort::getPort(){ 41 | return _port; 42 | } 43 | uint8_t MePort::getSlot(){ 44 | return _slot; 45 | } 46 | bool MePort::dRead1() 47 | { 48 | bool val; 49 | pinMode(s1, INPUT); 50 | val = digitalRead(s1); 51 | return val; 52 | } 53 | 54 | bool MePort::dRead2() 55 | { 56 | bool val; 57 | pinMode(s2, INPUT); 58 | val = digitalRead(s2); 59 | return val; 60 | } 61 | 62 | void MePort::dWrite1(bool value) 63 | { 64 | pinMode(s1, OUTPUT); 65 | digitalWrite(s1, value); 66 | } 67 | 68 | void MePort::dWrite2(bool value) 69 | { 70 | pinMode(s2, OUTPUT); 71 | digitalWrite(s2, value); 72 | } 73 | 74 | int MePort::aRead1() 75 | { 76 | int val; 77 | val = analogRead(s1); 78 | return val; 79 | } 80 | 81 | int MePort::aRead2() 82 | { 83 | int val; 84 | val = analogRead(s2); 85 | return val; 86 | } 87 | 88 | void MePort::aWrite1(int value) 89 | { 90 | analogWrite(s1, value); 91 | } 92 | 93 | void MePort::aWrite2(int value) 94 | { 95 | analogWrite(s2, value); 96 | } 97 | void MePort::reset(uint8_t port){ 98 | s1 = mePort[port].s1; 99 | s2 = mePort[port].s2; 100 | _port = port; 101 | } 102 | void MePort::reset(uint8_t port,uint8_t slot){ 103 | s1 = mePort[port].s1; 104 | s2 = mePort[port].s2; 105 | _port = port; 106 | _slot = slot; 107 | } 108 | uint8_t MePort::pin1(){ 109 | return s1; 110 | } 111 | uint8_t MePort::pin2(){ 112 | return s2; 113 | } 114 | 115 | uint8_t MePort::pin(){ 116 | return _slot==SLOT1?s1:s2; 117 | } 118 | uint8_t MePort::pin(uint8_t port,uint8_t slot){ 119 | return slot==SLOT1?mePort[port].s1:mePort[port].s2; 120 | } 121 | -------------------------------------------------------------------------------- /mbot_firmware/MePort.h: -------------------------------------------------------------------------------- 1 | #ifndef MEPORT_H_ 2 | #define MEPORT_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "wiring_private.h" 8 | #ifndef F_CPU 9 | #define F_CPU 16000000UL 10 | #endif 11 | #include 12 | #include 13 | #include 14 | 15 | typedef struct 16 | { 17 | uint8_t s1; 18 | uint8_t s2; 19 | } MePort_Sig; 20 | extern MePort_Sig mePort[11];//mePort[0] is nonsense 21 | 22 | #define NC -1 23 | 24 | // #define PORT_1 0x01 25 | // #define PORT_2 0x02 26 | // #define PORT_3 0x03 27 | // #define PORT_4 0x04 28 | // #define PORT_5 0x05 29 | // #define PORT_6 0x06 30 | // #define PORT_7 0x07 31 | // #define PORT_8 0x08 32 | // #define M1 0x09 33 | // #define M2 0x0a 34 | 35 | typedef enum 36 | { 37 | PORT_0, 38 | PORT_1, 39 | PORT_2, 40 | PORT_3, 41 | PORT_4, 42 | PORT_5, 43 | PORT_6, 44 | PORT_7, 45 | PORT_8, 46 | M1, 47 | M2, 48 | }MEPORT; 49 | 50 | // #if defined(__AVR_ATmega32U4__) 51 | // // buzzer 52 | // #define buzzerOn() DDRE |= 0x04,PORTE |= B00000100 53 | // #define buzzerOff() DDRE |= 0x04,PORTE &= B11111011 54 | // #else 55 | // #define buzzerOn() DDRC |= 0x20,PORTC |= B00100000; 56 | // #define buzzerOff() DDRC |= 0x20,PORTC &= B11011111; 57 | // #endif 58 | #define SLOT1 1 59 | #define SLOT2 2 60 | #define SLOT_1 SLOT1 61 | #define SLOT_2 SLOT2 62 | 63 | #define FALSE 0 64 | #define TRUE 1 65 | 66 | // Platform specific I/O definitions 67 | 68 | // #if defined(__AVR__) 69 | // #define MePIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) 70 | // #define MePIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 71 | // #define MeIO_REG_TYPE uint8_t 72 | // #define MeIO_REG_ASM asm("r30") 73 | // #define MeDIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 74 | // #define MeDIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)),((*((base)+2)) |= (mask))//INPUT_PULLUP 75 | // #define MeDIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) 76 | // #define MeDIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) 77 | // #define MeDIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) 78 | // #endif 79 | 80 | //#define MeDIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)),((*((base)+2)) |= (mask))//INPUT_PULLUP 81 | 82 | ///@brief class of MePort,it contains two pin. 83 | class MePort 84 | { 85 | public: 86 | MePort(); 87 | ///@brief initialize the Port 88 | ///@param port port number of device 89 | MePort(MEPORT port); 90 | MePort(MEPORT port,uint8_t slot); 91 | ///@return the level of pin 1 of port 92 | ///@retval true on HIGH. 93 | ///@retval false on LOW. 94 | uint8_t getPort(); 95 | uint8_t getSlot(); 96 | ///@return the level of pin 1 of port 97 | ///@retval true on HIGH. 98 | ///@retval false on LOW. 99 | bool dRead1(); 100 | ///@return the level of pin 2 of port 101 | ///@retval true on HIGH. 102 | ///@retval false on LOW. 103 | bool dRead2(); 104 | ///@brief set the analog value of pin 1 of port 105 | ///@param value is HIGH or LOW 106 | void dWrite1(bool value); 107 | ///@brief set the level of pin 1 of port 108 | ///@param value is HIGH or LOW 109 | void dWrite2(bool value); 110 | ///@return the analog signal of pin 1 of port between 0 to 1023 111 | int aRead1(); 112 | ///@return the analog signal of pin 2 of port between 0 to 1023 113 | int aRead2(); 114 | ///@brief set the PWM outpu value of pin 1 of port 115 | ///@param value between 0 to 255 116 | void aWrite1(int value); 117 | ///@brief set the PWM outpu value of pin 2 of port 118 | ///@param value between 0 to 255 119 | void aWrite2(int value); 120 | void reset(uint8_t port); 121 | void reset(uint8_t port,uint8_t slot); 122 | uint8_t pin1(); 123 | uint8_t pin2(); 124 | uint8_t pin(); 125 | uint8_t pin(uint8_t port,uint8_t slot); 126 | protected: 127 | uint8_t s1; 128 | uint8_t s2; 129 | uint8_t _port; 130 | uint8_t _slot; 131 | uint8_t _pin; 132 | }; 133 | #endif 134 | -------------------------------------------------------------------------------- /mbot_firmware/MeRGBLed.h: -------------------------------------------------------------------------------- 1 | #ifndef MeRGBLed_h 2 | #define MeRGBLed_h 3 | #include "MePort.h" 4 | struct cRGB { 5 | uint8_t g; 6 | uint8_t r; 7 | uint8_t b; 8 | }; 9 | 10 | ///@brief Class for RGB Led Module(http://www.makeblock.cc/me-rgb-led-v1-0/) and Led Strip(http://www.makeblock.cc/led-rgb-strip-addressable-sealed-1m/) 11 | class MeRGBLed:public MePort { 12 | public: 13 | MeRGBLed(); 14 | MeRGBLed(uint8_t pin); 15 | MeRGBLed(MEPORT port); 16 | MeRGBLed(MEPORT port,uint8_t slot); 17 | ~MeRGBLed(); 18 | void reset(MEPORT port); 19 | void reset(MEPORT port,uint8_t slot); 20 | void reset(int pin); 21 | ///@brief set the count of leds. 22 | void setNumber(uint8_t num_led); 23 | ///@brief get the count of leds. 24 | uint8_t getNumber(); 25 | ///@brief get the rgb value of the led with the index. 26 | cRGB getColorAt(uint8_t index); 27 | ///@brief set the rgb value of the led with the index. 28 | bool setColorAt(uint8_t index, uint8_t red,uint8_t green,uint8_t blue); 29 | bool setColorAt(uint8_t index, long value); 30 | void setColor(uint8_t index, uint8_t red,uint8_t green,uint8_t blue); 31 | void setColor(uint8_t red,uint8_t green,uint8_t blue); 32 | void setColor(long value); 33 | void clear(); 34 | ///@brief become effective of all led's change. 35 | void show(); 36 | 37 | private: 38 | uint16_t count_led; 39 | uint8_t *pixels; 40 | 41 | void rgbled_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask,uint8_t *port); 42 | 43 | const volatile uint8_t *ws2812_port; 44 | uint8_t pinMask; 45 | }; 46 | #endif 47 | -------------------------------------------------------------------------------- /mbot_firmware/MeTemperature.cpp: -------------------------------------------------------------------------------- 1 | #include "MeTemperature.h" 2 | 3 | // DS18B20 commands 4 | #define STARTCONVO 0x44 // Tells device to take a temperature reading and put it on the scratchpad 5 | #define COPYSCRATCH 0x48 // Copy EEPROM 6 | #define READSCRATCH 0xBE // Read EEPROM 7 | #define WRITESCRATCH 0x4E // Write to EEPROM 8 | #define RECALLSCRATCH 0xB8 // Reload from last known 9 | #define READPOWERSUPPLY 0xB4 // Determine if device needs parasite power 10 | #define ALARMSEARCH 0xEC // Query bus for devices with an alarm condition 11 | 12 | MeTemperature::MeTemperature():MePort(){ 13 | } 14 | MeTemperature::MeTemperature(MEPORT port):MePort(port){ 15 | 16 | } 17 | MeTemperature::MeTemperature(uint8_t pin){ 18 | _ts.reset(pin); 19 | } 20 | MeTemperature::MeTemperature(MEPORT port,uint8_t slot):MePort(port){ 21 | MePort::reset(port, slot); 22 | _ts.reset( slot == SLOT_2 ? s2 : s1); 23 | } 24 | void MeTemperature::reset(uint8_t port,uint8_t slot){ 25 | MePort::reset(port, slot); 26 | _ts.reset( slot == SLOT_2 ? s2 : s1); 27 | } 28 | float MeTemperature::temperature(){ 29 | byte i; 30 | byte present = 0; 31 | byte type_s; 32 | byte data[12]; 33 | // byte addr[8]; 34 | float celsius; 35 | long time; 36 | _ts.reset(); 37 | _ts.skip(); 38 | _ts.write(STARTCONVO); // start conversion, with parasite power on at the end 39 | time = millis(); 40 | while(!_ts.readIO() && (millis()-time)<750); 41 | present = _ts.reset(); 42 | _ts.skip(); 43 | _ts.write(READSCRATCH); 44 | for ( i = 0; i < 5; i++) { // we need 9 bytes 45 | data[i] = _ts.read(); 46 | } 47 | int16_t rawTemperature = (data[1] << 8) | data[0]; 48 | return (float)rawTemperature * 0.0625;// 12 bit 49 | } 50 | -------------------------------------------------------------------------------- /mbot_firmware/MeTemperature.h: -------------------------------------------------------------------------------- 1 | #ifndef MeTemperature_h 2 | #define MeTemperature_h 3 | #include "MePort.h" 4 | #include "MeOneWire.h" 5 | 6 | ///@brief Class for temperature sensor 7 | class MeTemperature:public MePort{ 8 | public: 9 | MeTemperature(); 10 | MeTemperature(MEPORT port); 11 | MeTemperature(uint8_t pin); 12 | MeTemperature(MEPORT port,uint8_t slot); 13 | void reset(uint8_t port, uint8_t slot); 14 | ///@brief get the celsius of temperature 15 | float temperature(); 16 | private: 17 | MeOneWire _ts; 18 | }; 19 | #endif 20 | -------------------------------------------------------------------------------- /mbot_firmware/MeUltrasonic.cpp: -------------------------------------------------------------------------------- 1 | #include "MeUltrasonic.h" 2 | /* UltrasonicSenser */ 3 | MeUltrasonic::MeUltrasonic(): MePort(PORT_0) 4 | { 5 | } 6 | MeUltrasonic::MeUltrasonic(uint8_t pin) 7 | { 8 | s2 = pin; 9 | } 10 | MeUltrasonic::MeUltrasonic(MEPORT port): MePort(port) 11 | { 12 | } 13 | 14 | double MeUltrasonic::distanceCm(uint16_t maxCm) 15 | { 16 | long distance = measure(maxCm * 55 + 200); 17 | return (double)distance / 58.0; 18 | } 19 | 20 | double MeUltrasonic::distanceInch(uint16_t maxInch) 21 | { 22 | long distance = measure(maxInch * 145 + 200); 23 | return (double)(distance / 148.0); 24 | } 25 | 26 | double MeUltrasonic::distanceCm(){ 27 | return distanceCm(400); 28 | } 29 | double MeUltrasonic::distanceInch(){ 30 | return distanceInch(5); 31 | } 32 | long MeUltrasonic::measure(unsigned long timeout) 33 | { 34 | long duration; 35 | // MePort::dWrite2(LOW); 36 | // delayMicroseconds(2); 37 | // MePort::dWrite2(HIGH); 38 | // delayMicroseconds(10); 39 | // MePort::dWrite2(LOW); 40 | // pinMode(s2, INPUT); 41 | // duration = pulseIn(s2, HIGH, timeout); 42 | digitalWrite(s2,LOW); 43 | delayMicroseconds(2); 44 | digitalWrite(s2,HIGH); 45 | delayMicroseconds(10); 46 | digitalWrite(s2,LOW); 47 | pinMode(s2,INPUT); 48 | duration = pulseIn(s2,HIGH,timeout); 49 | return duration; 50 | } 51 | -------------------------------------------------------------------------------- /mbot_firmware/MeUltrasonic.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef MEULTRASONIC_H_ 3 | #define MEULTRASONIC_H_ 4 | #include "MePort.h" 5 | ///@brief Class for Ultrasonic Sensor Module 6 | class MeUltrasonic: public MePort 7 | { 8 | public: 9 | MeUltrasonic(); 10 | MeUltrasonic(uint8_t pin); 11 | MeUltrasonic(MEPORT port); 12 | double distanceCm(); 13 | double distanceInch(); 14 | double distanceCm(uint16_t maxCm); 15 | double distanceInch(uint16_t maxInch); 16 | long measure(unsigned long timeout); 17 | private: 18 | uint8_t _pin; 19 | }; 20 | #endif 21 | -------------------------------------------------------------------------------- /mbot_firmware/mBot.cpp: -------------------------------------------------------------------------------- 1 | #include "mBot.h" 2 | #include "MePort.h" 3 | 4 | #include "wiring_private.h" 5 | #include "pins_arduino.h" 6 | 7 | // MePort_Sig mePort[11] = {{NC, NC}, {11, 12}, {9, 10}, {A2, A3}, {A0, A1}, {NC, NC}, {NC, NC}, {NC, NC}, {NC, NC}, {6, 7}, {5, 4}}; 8 | 9 | MeBoard::MeBoard(uint8_t boards) 10 | { 11 | MePort_Sig *port = &mePort[1]; 12 | if(boards == mBot)//MePort_Sig mePort[] = {{NC, NC}, {11, 12}, {9, 10}, {A2, A3}, {A0, A1}}; 13 | 14 | { 15 | port -> s1 = 11;//port1 16 | port -> s2 = 12; 17 | 18 | port++; 19 | port -> s1 = 9; //port2 20 | port -> s2 = 10; 21 | 22 | port++; 23 | port -> s1 = A2;//port3 24 | port -> s2 = A3; 25 | 26 | port++; 27 | port -> s1 = A0;//port4 28 | port -> s2 = A1; 29 | port++; 30 | port -> s1 = 6;//M1 31 | port -> s2 = 7; 32 | port++; 33 | port -> s1 = 5;//M2 34 | port -> s2 = 4; 35 | 36 | port++; 37 | port -> s1 = A7;//port7 38 | port -> s2 = 13; 39 | 40 | port++; 41 | port -> s1 = 8;//port8 42 | port -> s2 = A6; 43 | port++; 44 | port -> s1 = 6;//M1 45 | port -> s2 = 7; 46 | port++; 47 | port -> s1 = 5;//M2 48 | port -> s2 = 4; 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /mbot_firmware/mBot.h: -------------------------------------------------------------------------------- 1 | ///@file Makeblock.h head file of Makeblock Library V2.1.0625 2 | ///Define the interface of Makeblock Library 3 | 4 | //#include 5 | 6 | #ifndef Mbot_h 7 | #define Mbot_h 8 | 9 | #include "MeDCMotor.h" 10 | #include "MeBuzzer.h" 11 | #include "MeTemperature.h" 12 | #include "Me7SegmentDisplay.h" 13 | #include "MeRGBLed.h" 14 | #include "MeUltrasonic.h" 15 | #include "MeInfraredReceiver.h" 16 | 17 | #include 18 | // #include 19 | // #include 20 | #include 21 | #include 22 | #ifndef F_CPU 23 | #define F_CPU 16000000UL 24 | #endif 25 | #include 26 | #include 27 | #include 28 | 29 | 30 | 31 | 32 | #define MeBaseBoard 1 33 | #define MakeblockOrion 2 34 | #define mBot 3 35 | 36 | 37 | ///@brief Class for MeBoard 38 | class MeBoard 39 | { 40 | public: 41 | MeBoard(uint8_t boards); 42 | }; 43 | 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /resources/firmware/mblock_firmware.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Makeblock-official/Makeblock-Firmware/2cc3e393b8b1aa157062567ddb59fb84355e9246/resources/firmware/mblock_firmware.zip -------------------------------------------------------------------------------- /resources/firmware/mbot_firmware.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Makeblock-official/Makeblock-Firmware/2cc3e393b8b1aa157062567ddb59fb84355e9246/resources/firmware/mbot_firmware.zip -------------------------------------------------------------------------------- /resources/libraries/arduino.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Makeblock-official/Makeblock-Firmware/2cc3e393b8b1aa157062567ddb59fb84355e9246/resources/libraries/arduino.zip -------------------------------------------------------------------------------- /resources/libraries/makeblock.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Makeblock-official/Makeblock-Firmware/2cc3e393b8b1aa157062567ddb59fb84355e9246/resources/libraries/makeblock.zip -------------------------------------------------------------------------------- /resources/libraries/mbot.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Makeblock-official/Makeblock-Firmware/2cc3e393b8b1aa157062567ddb59fb84355e9246/resources/libraries/mbot.zip -------------------------------------------------------------------------------- /resources/libraries/serial.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Makeblock-official/Makeblock-Firmware/2cc3e393b8b1aa157062567ddb59fb84355e9246/resources/libraries/serial.zip -------------------------------------------------------------------------------- /resources/locale/locale.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Makeblock-official/Makeblock-Firmware/2cc3e393b8b1aa157062567ddb59fb84355e9246/resources/locale/locale.zip -------------------------------------------------------------------------------- /resources/tools/hex.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Makeblock-official/Makeblock-Firmware/2cc3e393b8b1aa157062567ddb59fb84355e9246/resources/tools/hex.zip -------------------------------------------------------------------------------- /tool/ArduinoTool.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Makeblock-official/Makeblock-Firmware/2cc3e393b8b1aa157062567ddb59fb84355e9246/tool/ArduinoTool.zip --------------------------------------------------------------------------------