├── README.md ├── mBot-default-program ├── MakeblockOrion.h ├── Me1Wire.cpp ├── Me1Wire.h ├── Me7SegmentDisplay.cpp ├── Me7SegmentDisplay.h ├── MeBaseBoard.h ├── MeBuzzer.cpp ├── MeBuzzer.h ├── MeDCMotor.cpp ├── MeDCMotor.h ├── MeIR.cpp ├── MeIR.h ├── MeInfraredReceiver.cpp ├── MeInfraredReceiver.h ├── MeLEDMatrix.cpp ├── MeLEDMatrix.h ├── MeLEDMatrixData.h ├── MeLineFollower.cpp ├── MeLineFollower.h ├── MePort.cpp ├── MePort.h ├── MeRGBLed.cpp ├── MeRGBLed.h ├── MeTemperature.cpp ├── MeTemperature.h ├── MeUltrasonic.cpp ├── MeUltrasonic.h ├── mBot-default-program.ino └── mCore.h └── pcb └── mCore.pdf /README.md: -------------------------------------------------------------------------------- 1 | # mBot 2 | 3 | ###Learn more from Makeblock official website: www.makeblock.com 4 | -------------------------------------------------------------------------------- /mBot-default-program/MakeblockOrion.h: -------------------------------------------------------------------------------- 1 | ///@file Makeblock.h head file of Makeblock Library V2.1.0625 2 | ///Define the interface of Makeblock Library 3 | 4 | #ifndef MakeblockOrion_h 5 | #define MakeblockOrion_h 6 | 7 | #include "MePort.h" 8 | #include "MeDCMotor.h" 9 | #include "MeBuzzer.h" 10 | #include "MeTemperature.h" 11 | #include "Me7SegmentDisplay.h" 12 | #include "MeRGBLed.h" 13 | #include "MeUltrasonic.h" 14 | #include "MeInfraredReceiver.h" 15 | #include "MeIR.h" 16 | #include "MeLineFollower.h" 17 | // #include "Wire.h" 18 | Board_type MakeblockBoard = MakeblockOrion; 19 | 20 | MePort_Sig mePort[11] = {{NC, NC}, {11, 10}, {3, 9}, {12, 13}, {8, 2}, 21 | {1, 0}, {A2, A3}, {A6, A1}, {A7, A0}, {6, 7}, {5, 4} 22 | }; 23 | 24 | ///@brief Class for MeBoard 25 | // class MeBoard 26 | // { 27 | // public: 28 | // MeBoard(uint8_t boards); 29 | // }; 30 | 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /mBot-default-program/Me1Wire.cpp: -------------------------------------------------------------------------------- 1 | #include "Me1Wire.h" 2 | 3 | Me1Wire::Me1Wire(){ 4 | } 5 | Me1Wire::Me1Wire(uint8_t pin) 6 | { 7 | bitmask = MePIN_TO_BITMASK(pin); 8 | baseReg = MePIN_TO_BASEREG(pin); 9 | // reset_search(); 10 | } 11 | void Me1Wire::reset(uint8_t pin) 12 | { 13 | bitmask = MePIN_TO_BITMASK(pin); 14 | baseReg = MePIN_TO_BASEREG(pin); 15 | // reset_search(); 16 | } 17 | bool Me1Wire::readIO(void) 18 | { 19 | MeIO_REG_TYPE mask = bitmask; 20 | volatile MeIO_REG_TYPE *reg MeIO_REG_ASM = baseReg; 21 | uint8_t r; 22 | MeDIRECT_MODE_INPUT(reg, mask); // allow it to float 23 | delayMicroseconds(10); 24 | r = MeDIRECT_READ(reg, mask); 25 | return r; 26 | } 27 | // Perform the Me1Wire reset function. We will wait up to 250uS for 28 | // the bus to come high, if it doesn't then it is broken or shorted 29 | // and we return a 0; 30 | // 31 | // Returns 1 if a device asserted a presence pulse, 0 otherwise. 32 | // 33 | uint8_t Me1Wire::reset(void) 34 | { 35 | MeIO_REG_TYPE mask = bitmask; 36 | volatile MeIO_REG_TYPE *reg MeIO_REG_ASM = baseReg; 37 | uint8_t r; 38 | uint8_t retries = 125; 39 | noInterrupts(); 40 | MeDIRECT_MODE_INPUT(reg, mask); 41 | interrupts(); 42 | // wait until the wire is high... just in case 43 | do { 44 | if (--retries == 0) return 0; 45 | delayMicroseconds(2); 46 | } while ( !MeDIRECT_READ(reg, mask)); 47 | noInterrupts(); 48 | MeDIRECT_WRITE_LOW(reg, mask); 49 | MeDIRECT_MODE_OUTPUT(reg, mask); // drive output low 50 | interrupts(); 51 | delayMicroseconds(480); 52 | noInterrupts(); 53 | MeDIRECT_MODE_INPUT(reg, mask); // allow it to float 54 | delayMicroseconds(70); 55 | r = !MeDIRECT_READ(reg, mask); 56 | interrupts(); 57 | delayMicroseconds(410); 58 | return r; 59 | } 60 | // 61 | // Write a bit. Port and bit is used to cut lookup time and provide 62 | // more certain timing. 63 | // 64 | void Me1Wire::write_bit(uint8_t v) 65 | { 66 | MeIO_REG_TYPE mask=bitmask; 67 | volatile MeIO_REG_TYPE *reg MeIO_REG_ASM = baseReg; 68 | if (v & 1) { 69 | noInterrupts(); 70 | MeDIRECT_WRITE_LOW(reg, mask); 71 | MeDIRECT_MODE_OUTPUT(reg, mask); // drive output low 72 | delayMicroseconds(10); 73 | MeDIRECT_WRITE_HIGH(reg, mask); // drive output high 74 | interrupts(); 75 | delayMicroseconds(55); 76 | } else { 77 | noInterrupts(); 78 | MeDIRECT_WRITE_LOW(reg, mask); 79 | MeDIRECT_MODE_OUTPUT(reg, mask); // drive output low 80 | delayMicroseconds(65); 81 | MeDIRECT_WRITE_HIGH(reg, mask); // drive output high 82 | interrupts(); 83 | delayMicroseconds(5); 84 | } 85 | } 86 | // 87 | // Read a bit. Port and bit is used to cut lookup time and provide 88 | // more certain timing. 89 | // 90 | uint8_t Me1Wire::read_bit(void) 91 | { 92 | MeIO_REG_TYPE mask=bitmask; 93 | volatile MeIO_REG_TYPE *reg MeIO_REG_ASM = baseReg; 94 | uint8_t r; 95 | noInterrupts(); 96 | MeDIRECT_MODE_OUTPUT(reg, mask); 97 | MeDIRECT_WRITE_LOW(reg, mask); 98 | delayMicroseconds(3); 99 | MeDIRECT_MODE_INPUT(reg, mask); // let pin float, pull up will raise 100 | delayMicroseconds(10); 101 | r = MeDIRECT_READ(reg, mask); 102 | interrupts(); 103 | delayMicroseconds(53); 104 | return r; 105 | } 106 | // 107 | // Write a byte. The writing code uses the active drivers to raise the 108 | // pin high, if you need power after the write (e.g. DS18S20 in 109 | // parasite power mode) then set 'power' to 1, otherwise the pin will 110 | // go tri-state at the end of the write to avoid heating in a short or 111 | // other mishap. 112 | // 113 | void Me1Wire::write(uint8_t v, uint8_t power /* = 0 */) { 114 | uint8_t bitMask; 115 | for (bitMask = 0x01; bitMask; bitMask <<= 1) { 116 | Me1Wire::write_bit( (bitMask & v)?1:0); 117 | } 118 | if ( !power) { 119 | noInterrupts(); 120 | MeDIRECT_MODE_INPUT(baseReg, bitmask); 121 | MeDIRECT_WRITE_LOW(baseReg, bitmask); 122 | interrupts(); 123 | } 124 | } 125 | void Me1Wire::write_bytes(const uint8_t *buf, uint16_t count, bool power /* = 0 */) { 126 | for (uint16_t i = 0 ; i < count ; i++) 127 | write(buf[i]); 128 | if (!power) { 129 | noInterrupts(); 130 | MeDIRECT_MODE_INPUT(baseReg, bitmask); 131 | MeDIRECT_WRITE_LOW(baseReg, bitmask); 132 | interrupts(); 133 | } 134 | } 135 | // 136 | // Read a byte 137 | // 138 | uint8_t Me1Wire::read() { 139 | uint8_t bitMask; 140 | uint8_t r = 0; 141 | for (bitMask = 0x01; bitMask; bitMask <<= 1) { 142 | if ( Me1Wire::read_bit()) r |= bitMask; 143 | } 144 | return r; 145 | } 146 | void Me1Wire::read_bytes(uint8_t *buf, uint16_t count) { 147 | for (uint16_t i = 0 ; i < count ; i++) 148 | buf[i] = read(); 149 | } 150 | // 151 | // Do a ROM select 152 | // 153 | void Me1Wire::select(const uint8_t rom[8]) 154 | { 155 | uint8_t i; 156 | write(0x55); // Choose ROM 157 | for (i = 0; i < 8; i++) write(rom[i]); 158 | } 159 | // 160 | // Do a ROM skip 161 | // 162 | void Me1Wire::skip() 163 | { 164 | write(0xCC); // Skip ROM 165 | } 166 | void Me1Wire::depower() 167 | { 168 | noInterrupts(); 169 | MeDIRECT_MODE_INPUT(baseReg, bitmask); 170 | interrupts(); 171 | } 172 | void Me1Wire::reset_search() 173 | { 174 | // reset the search state 175 | LastDiscrepancy = 0; 176 | LastDeviceFlag = false; 177 | LastFamilyDiscrepancy = 0; 178 | for(int i = 7; ; i--) { 179 | ROM_NO[i] = 0; 180 | if ( i == 0) break; 181 | } 182 | } 183 | // Setup the search to find the device type 'family_code' on the next call 184 | // to search(*newAddr) if it is present. 185 | // 186 | void Me1Wire::target_search(uint8_t family_code) 187 | { 188 | // set the search state to find SearchFamily type devices 189 | ROM_NO[0] = family_code; 190 | for (uint8_t i = 1; i < 8; i++) 191 | ROM_NO[i] = 0; 192 | LastDiscrepancy = 64; 193 | LastFamilyDiscrepancy = 0; 194 | LastDeviceFlag = false; 195 | } 196 | // 197 | // Perform a search. If this function returns a '1' then it has 198 | // enumerated the next device and you may retrieve the ROM from the 199 | // Me1Wire::address variable. If there are no devices, no further 200 | // devices, or something horrible happens in the middle of the 201 | // enumeration then a 0 is returned. If a new device is found then 202 | // its address is copied to newAddr. Use Me1Wire::reset_search() to 203 | // start over. 204 | // 205 | // --- Replaced by the one from the Dallas Semiconductor web site --- 206 | //-------------------------------------------------------------------------- 207 | // Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing 208 | // search state. 209 | // Return true : device found, ROM number in ROM_NO buffer 210 | // false : device not found, end of search 211 | 212 | uint8_t Me1Wire::search(uint8_t *newAddr) 213 | { 214 | uint8_t id_bit_number; 215 | uint8_t last_zero, rom_byte_number, search_result; 216 | uint8_t id_bit, cmp_id_bit; 217 | unsigned char rom_byte_mask, search_direction; 218 | // initialize for search 219 | id_bit_number = 1; 220 | last_zero = 0; 221 | rom_byte_number = 0; 222 | rom_byte_mask = 1; 223 | search_result = 0; 224 | // if the last call was not the last one 225 | if (!LastDeviceFlag) 226 | { 227 | // 1-Wire reset 228 | if (!reset()) 229 | { 230 | // reset the search 231 | LastDiscrepancy = 0; 232 | LastDeviceFlag = false; 233 | LastFamilyDiscrepancy = 0; 234 | return false; 235 | } 236 | // issue the search command 237 | write(0xF0); 238 | // loop to do the search 239 | do 240 | { 241 | // read a bit and its complement 242 | id_bit = read_bit(); 243 | cmp_id_bit = read_bit(); 244 | // check for no devices on 1-wire 245 | if ((id_bit == 1) && (cmp_id_bit == 1)) 246 | break; 247 | else 248 | { 249 | // all devices coupled have 0 or 1 250 | if (id_bit != cmp_id_bit) 251 | search_direction = id_bit; // bit write value for search 252 | else 253 | { 254 | // if this discrepancy if before the Last Discrepancy 255 | // on a previous next then pick the same as last time 256 | if (id_bit_number < LastDiscrepancy) 257 | search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); 258 | else 259 | // if equal to last pick 1, if not then pick 0 260 | search_direction = (id_bit_number == LastDiscrepancy); 261 | // if 0 was picked then record its position in LastZero 262 | if (search_direction == 0) 263 | { 264 | last_zero = id_bit_number; 265 | // check for Last discrepancy in family 266 | if (last_zero < 9) 267 | LastFamilyDiscrepancy = last_zero; 268 | } 269 | } 270 | // set or clear the bit in the ROM byte rom_byte_number 271 | // with mask rom_byte_mask 272 | if (search_direction == 1) 273 | ROM_NO[rom_byte_number] |= rom_byte_mask; 274 | else 275 | ROM_NO[rom_byte_number] &= ~rom_byte_mask; 276 | // serial number search direction write bit 277 | write_bit(search_direction); 278 | // increment the byte counter id_bit_number 279 | // and shift the mask rom_byte_mask 280 | id_bit_number++; 281 | rom_byte_mask <<= 1; 282 | // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask 283 | if (rom_byte_mask == 0) 284 | { 285 | rom_byte_number++; 286 | rom_byte_mask = 1; 287 | } 288 | } 289 | } 290 | while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 291 | // if the search was successful then 292 | if (!(id_bit_number < 65)) 293 | { 294 | // search successful so set LastDiscrepancy,LastDeviceFlag,search_result 295 | LastDiscrepancy = last_zero; 296 | // check for last device 297 | if (LastDiscrepancy == 0) 298 | LastDeviceFlag = true; 299 | search_result = true; 300 | } 301 | } 302 | // if no device found then reset counters so next 'search' will be like a first 303 | if (!search_result || !ROM_NO[0]) 304 | { 305 | LastDiscrepancy = 0; 306 | LastDeviceFlag = false; 307 | LastFamilyDiscrepancy = 0; 308 | search_result = false; 309 | } 310 | for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i]; 311 | return search_result; 312 | } 313 | -------------------------------------------------------------------------------- /mBot-default-program/Me1Wire.h: -------------------------------------------------------------------------------- 1 | #ifndef Me1Wire_h 2 | #define Me1Wire_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 Me1Wire 17 | class Me1Wire 18 | { 19 | public: 20 | Me1Wire(); 21 | Me1Wire( 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-default-program/Me7SegmentDisplay.cpp: -------------------------------------------------------------------------------- 1 | #include "Me7SegmentDisplay.h" 2 | 3 | static uint8_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 | _dataPin = dataPin; 18 | _clkPin = clkPin; 19 | pinMode(_clkPin, OUTPUT); 20 | pinMode(_dataPin, OUTPUT); 21 | set(); 22 | clearDisplay(); 23 | } 24 | Me7SegmentDisplay::Me7SegmentDisplay(MEPORT port): MePort(port) 25 | { 26 | _dataPin = s1; 27 | _clkPin = s2; 28 | pinMode(_clkPin, OUTPUT); 29 | pinMode(_dataPin, OUTPUT); 30 | set(); 31 | clearDisplay(); 32 | } 33 | void Me7SegmentDisplay::reset(uint8_t port) 34 | { 35 | reset(port); 36 | _clkPin = s2; 37 | _dataPin = s1; 38 | pinMode(_clkPin, OUTPUT); 39 | pinMode(_dataPin, OUTPUT); 40 | set(); 41 | clearDisplay(); 42 | } 43 | void Me7SegmentDisplay::init(void) 44 | { 45 | clearDisplay(); 46 | } 47 | 48 | void Me7SegmentDisplay::writeByte(uint8_t wr_data) 49 | { 50 | uint8_t i, count1; 51 | for(i = 0; i < 8; i++) //sent 8bit data 52 | { 53 | digitalWrite(_clkPin, LOW); 54 | if(wr_data & 0x01)digitalWrite(_dataPin, HIGH); //LSB first 55 | else digitalWrite(_dataPin, LOW); 56 | wr_data >>= 1; 57 | digitalWrite(_clkPin, HIGH); 58 | 59 | } 60 | digitalWrite(_clkPin, LOW); //wait for the ACK 61 | digitalWrite(_dataPin, HIGH); 62 | digitalWrite(_clkPin, HIGH); 63 | pinMode(_dataPin, INPUT); 64 | while(digitalRead(_dataPin)) 65 | { 66 | count1 += 1; 67 | if(count1 == 200)// 68 | { 69 | pinMode(_dataPin, OUTPUT); 70 | digitalWrite(_dataPin, LOW); 71 | count1 = 0; 72 | } 73 | //pinMode(_dataPin,INPUT); 74 | } 75 | pinMode(_dataPin, OUTPUT); 76 | 77 | } 78 | //send start signal to TM1637 79 | void Me7SegmentDisplay::start(void) 80 | { 81 | digitalWrite(_clkPin, HIGH); //send start signal to TM1637 82 | digitalWrite(_dataPin, HIGH); 83 | digitalWrite(_dataPin, LOW); 84 | digitalWrite(_clkPin, LOW); 85 | } 86 | //End of transmission 87 | void Me7SegmentDisplay::stop(void) 88 | { 89 | digitalWrite(_clkPin, LOW); 90 | digitalWrite(_dataPin, LOW); 91 | digitalWrite(_clkPin, HIGH); 92 | digitalWrite(_dataPin, HIGH); 93 | } 94 | 95 | 96 | void Me7SegmentDisplay::display(uint16_t value) 97 | { 98 | display((int)value); 99 | // display((double)value,0); 100 | } 101 | 102 | void Me7SegmentDisplay::display(int16_t value) 103 | { 104 | display((double)value, 0); 105 | } 106 | 107 | void Me7SegmentDisplay::display(double value, uint8_t digits) 108 | { 109 | 110 | 111 | AA: 112 | uint8_t buf[4] = {' ', ' ', ' ', ' '}; 113 | uint8_t tempBuf[4]; 114 | uint8_t b = 0; 115 | uint8_t bit_num = 0; 116 | uint8_t int_num = 0; 117 | uint8_t isNeg = 0; 118 | double number = value; 119 | if (number >= 9999.5 || number <= -999.5); 120 | else 121 | { 122 | // Handle negative numbers 123 | if (number < 0.0) 124 | { 125 | number = -number; 126 | isNeg = 1 ; 127 | } 128 | // Round correctly so that print(1.999, 2) prints as "2.00" 129 | double rounding = 0.5; 130 | for (uint8_t i = 0; i < digits; ++i) 131 | rounding /= 10.0; 132 | number += rounding; 133 | 134 | // Extract the integer part of the number and print it 135 | uint16_t int_part = (uint16_t )number; 136 | double remainder = number - (double)int_part; 137 | do 138 | { 139 | uint16_t m = int_part; 140 | int_part /= 10; 141 | int8_t c = m - 10 * int_part; 142 | tempBuf[int_num] = c; 143 | int_num++; 144 | } 145 | while(int_part); 146 | 147 | bit_num = isNeg + int_num + digits; 148 | 149 | if(bit_num > 4) 150 | { 151 | bit_num = 4; 152 | digits = 4 - (isNeg + int_num); 153 | goto AA; 154 | } 155 | b = 4 - bit_num; 156 | if(isNeg)buf[b++] = 0x21; 157 | 158 | for(uint8_t i = int_num; i > 0; i--)buf[b++] = tempBuf[i-1]; 159 | // Print the decimal point, but only if there are digits beyond 160 | if (digits > 0) 161 | { 162 | buf[b-1] += 0x10; 163 | // Extract digits from the remainder one at a time 164 | while (digits-- > 0) 165 | { 166 | remainder *= 10.0; 167 | int toPrint = int(remainder); 168 | buf[b++] = toPrint; 169 | remainder -= toPrint; 170 | } 171 | } 172 | } 173 | display(buf); 174 | } 175 | 176 | void Me7SegmentDisplay::write(uint8_t SegData[]) 177 | { 178 | uint8_t i; 179 | start(); //start signal sent to TM1637 from MCU 180 | writeByte(ADDR_AUTO); 181 | stop(); 182 | start(); 183 | writeByte(Cmd_SetAddr); 184 | for(i = 0; i < 4; i ++) 185 | { 186 | writeByte(SegData[i]); 187 | } 188 | stop(); 189 | start(); 190 | writeByte(Cmd_DispCtrl); 191 | stop(); 192 | } 193 | void Me7SegmentDisplay::write(uint8_t BitAddr, uint8_t SegData) 194 | { 195 | start(); //start signal sent to TM1637 from MCU 196 | writeByte(ADDR_FIXED); 197 | stop(); 198 | start(); 199 | writeByte(BitAddr | 0xc0); 200 | writeByte(SegData); 201 | stop(); 202 | start(); 203 | writeByte(Cmd_DispCtrl); 204 | stop(); 205 | } 206 | void Me7SegmentDisplay::display(uint8_t DispData[]) 207 | { 208 | uint8_t SegData[4]; 209 | uint8_t i; 210 | for(i = 0; i < 4; i ++) 211 | { 212 | SegData[i] = DispData[i]; 213 | } 214 | coding(SegData); 215 | write(SegData); 216 | } 217 | //****************************************** 218 | void Me7SegmentDisplay::display(uint8_t BitAddr, uint8_t DispData) 219 | { 220 | uint8_t SegData; 221 | 222 | if((DispData >= 'A' && DispData <= 'F'))DispData = DispData - 'A' + 10; 223 | else if((DispData >= 'a' && DispData <= 'f'))DispData = DispData - 'a' + 10; 224 | SegData = coding(DispData); 225 | write(BitAddr, SegData); // 226 | } 227 | 228 | void Me7SegmentDisplay::clearDisplay(void) 229 | { 230 | uint8_t buf[4] = {' ', ' ', ' ', ' '}; 231 | display(buf); 232 | } 233 | //To take effect the next time it displays. 234 | void Me7SegmentDisplay::set(uint8_t brightness, uint8_t SetData, uint8_t SetAddr) 235 | { 236 | Cmd_SetData = SetData; 237 | Cmd_SetAddr = SetAddr; 238 | Cmd_DispCtrl = 0x88 + brightness;//Set the brightness and it takes effect the next time it displays. 239 | } 240 | 241 | 242 | void Me7SegmentDisplay::coding(uint8_t DispData[]) 243 | { 244 | // uint8_t PointData = 0; 245 | for(uint8_t i = 0; i < 4; i ++) 246 | { 247 | DispData[i] = TubeTab[DispData[i]]; 248 | } 249 | } 250 | uint8_t Me7SegmentDisplay::coding(uint8_t DispData) 251 | { 252 | // uint8_t PointData = 0; 253 | DispData = TubeTab[DispData] ;//+ PointData; 254 | return DispData; 255 | } 256 | -------------------------------------------------------------------------------- /mBot-default-program/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(uint8_t port); 25 | void write(uint8_t SegData[]); 26 | void write(uint8_t BitAddr, uint8_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(uint8_t DispData[]); 31 | void display(uint8_t BitAddr, uint8_t DispData); 32 | void clearDisplay(void); 33 | void coding(uint8_t DispData[]); 34 | uint8_t coding(uint8_t DispData); 35 | private: 36 | uint8_t Cmd_SetData; 37 | uint8_t Cmd_SetAddr; 38 | uint8_t Cmd_DispCtrl; 39 | boolean _PointFlag; //_PointFlag=1:the clock point on 40 | void writeByte(uint8_t wr_data);//write 8bit data to tm1637 41 | void start(void);//send start bits 42 | void stop(void); //send stop bits 43 | void point(boolean PointFlag);//whether to light the clock point ":".To take effect the next time it displays. 44 | uint8_t _clkPin; 45 | uint8_t _dataPin; 46 | }; 47 | #endif 48 | -------------------------------------------------------------------------------- /mBot-default-program/MeBaseBoard.h: -------------------------------------------------------------------------------- 1 | ///@file Makeblock.h head file of Makeblock Library V2.1.0625 2 | ///Define the interface of Makeblock Library 3 | 4 | #ifndef MeBaseBoard_h 5 | #define MeBaseBoard_h 6 | 7 | #include "MePort.h" 8 | #include "MeDCMotor.h" 9 | // #include "MeBuzzer.h" 10 | #include "MeTemperature.h" 11 | #include "Me7SegmentDisplay.h" 12 | #include "MeRGBLed.h" 13 | #include "MeUltrasonic.h" 14 | #include "MeInfraredReceiver.h" 15 | #include "MeIR.h" 16 | 17 | Board_type MakeblockBoard = MeBaseBoard; 18 | 19 | MePort_Sig mePort[11] = {{NC, NC}, {11, A8}, {13, A11}, {A10, A9}, {1, 0}, 20 | {MISO, SCK}, {A0, A1}, {A2, A3}, {A4, A5}, {6, 7}, {5, 4} 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /mBot-default-program/MeBuzzer.cpp: -------------------------------------------------------------------------------- 1 | #include "MeBuzzer.h" 2 | #include "arduino.h" 3 | 4 | #include 5 | #include 6 | #if defined(__AVR_ATmega328P__) 7 | 8 | static uint8_t buzzer_pin; 9 | volatile long timer2_toggle_count; 10 | volatile uint8_t *timer2_pin_port; 11 | volatile uint8_t timer2_pin_mask; 12 | 13 | // timer in CTC mode 14 | // Set the OCR for the given timer, 15 | // set the toggle count, 16 | // then turn on the interrupts 17 | // OCR2A = ocr; 18 | void Timer2Init(uint32_t TimerFreq) 19 | { 20 | 21 | static const uint16_t pscLst_alt[] = {0, 1, 8, 32, 64, 128, 256, 1024}; 22 | 23 | //Set frequency of timer2 24 | //setting the waveform generation mode 25 | uint8_t wgm = 2; 26 | TCCR2A = 0; 27 | TCCR2B = 0; 28 | TCCR2A = (TCCR2A & B11111100) | (wgm & 3); 29 | TCCR2B = (TCCR2B & B11110111) | ((wgm & 12) << 1); 30 | 31 | uint16_t multiplier = F_CPU / 2 / TimerFreq / 256; 32 | byte iterate = 0; 33 | while(multiplier > pscLst_alt[++iterate]); 34 | multiplier = pscLst_alt[iterate]; 35 | OCR2A = F_CPU / 2 / TimerFreq / multiplier - 1; 36 | TCCR2B = (TCCR2B & ~7) | (iterate & 7); 37 | 38 | //enable interrupt 39 | bitSet(TIMSK2, OCIE2B); 40 | } 41 | 42 | MeBuzzer::MeBuzzer() 43 | { 44 | buzzer_pin = 8; 45 | } 46 | MeBuzzer::MeBuzzer(uint8_t pin) 47 | { 48 | buzzer_pin = pin; 49 | } 50 | MeBuzzer::MeBuzzer(MEPORT port): MePort(port) 51 | { 52 | buzzer_pin = s2; 53 | } 54 | 55 | MeBuzzer::MeBuzzer(MEPORT port, uint8_t slot): MePort(port) 56 | { 57 | buzzer_pin = s2; 58 | if(slot == SLOT2) 59 | { 60 | buzzer_pin = s2; 61 | } 62 | else 63 | { 64 | buzzer_pin = s1; 65 | } 66 | } 67 | 68 | // frequency (in hertz) and duration (in milliseconds). 69 | void MeBuzzer::tone(uint16_t frequency, uint32_t duration) 70 | { 71 | long toggle_count = 0; 72 | timer2_pin_port = portOutputRegister(digitalPinToPort(buzzer_pin)); 73 | timer2_pin_mask = digitalPinToBitMask(buzzer_pin); 74 | // Set the pinMode as OUTPUT 75 | pinMode(buzzer_pin, OUTPUT); 76 | // Calculate the toggle count 77 | if (duration > 0) 78 | { 79 | toggle_count = 2 * frequency * duration / 1000; 80 | } 81 | else 82 | { 83 | toggle_count = -1; 84 | } 85 | 86 | timer2_toggle_count = toggle_count; 87 | Timer2Init(frequency); 88 | } 89 | 90 | void MeBuzzer::noTone() 91 | { 92 | bitWrite(TIMSK2, OCIE2B, 0); // disable interrupt 93 | digitalWrite(buzzer_pin, LOW); 94 | } 95 | 96 | ISR(TIMER2_COMPB_vect) 97 | { 98 | 99 | if (timer2_toggle_count != 0) 100 | { 101 | // toggle the pin 102 | *timer2_pin_port ^= timer2_pin_mask; 103 | 104 | if (timer2_toggle_count > 0) 105 | timer2_toggle_count--; 106 | } 107 | else 108 | { 109 | bitWrite(TIMSK2, OCIE2B, 0); // disable interrupt 110 | digitalWrite(buzzer_pin, LOW); 111 | } 112 | } 113 | 114 | #endif -------------------------------------------------------------------------------- /mBot-default-program/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 | #endif 18 | -------------------------------------------------------------------------------- /mBot-default-program/MeDCMotor.cpp: -------------------------------------------------------------------------------- 1 | #include "MeDCMotor.h" 2 | // MeDCMotor::MeDCMotor(): MePort(0) 3 | // { 4 | 5 | // } 6 | MeDCMotor::MeDCMotor(MEPORT port): MePort(port) 7 | { 8 | _pwmPin = s1; 9 | _dirPin = s2; 10 | pinMode(_dirPin,OUTPUT); 11 | } 12 | 13 | MeDCMotor::MeDCMotor(uint8_t pwmPin,uint8_t dirPin) 14 | { 15 | _pwmPin = pwmPin; 16 | _dirPin = dirPin; 17 | pinMode(_dirPin,OUTPUT); 18 | } 19 | void MeDCMotor::run(int speed) 20 | { 21 | speed = speed > 255 ? 255 : speed; 22 | speed = speed < -255 ? -255 : speed; 23 | // constrain(speed,-255,255); 24 | if(speed >= 0) { 25 | digitalWrite(_dirPin,HIGH); 26 | analogWrite(_pwmPin,speed); 27 | // MePort::dWrite2(HIGH); 28 | // MePort::aWrite1(speed); 29 | } else { 30 | digitalWrite(_dirPin,LOW); 31 | analogWrite(_pwmPin,-speed); 32 | // MePort::dWrite2(LOW); 33 | // MePort::aWrite1(-speed); 34 | } 35 | } 36 | void MeDCMotor::stop() 37 | { 38 | MeDCMotor::run(0); 39 | } 40 | -------------------------------------------------------------------------------- /mBot-default-program/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-default-program/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 | static long decode_time = millis(); 116 | if(millis()-decode_time >1000) 117 | { 118 | // Serial.println("ERROR"); 119 | begin(); 120 | decode_time = millis(); 121 | value = 0; 122 | return ERROR; 123 | } 124 | rawbuf = irparams.rawbuf; 125 | rawlen = irparams.rawlen; 126 | // if(irparams.rcvstate == STATE_SPACE) 127 | // { 128 | // uint32_t time = micros() -irparams.lastTime; 129 | // if(time> _GAP && time < _GAP+1000) 130 | // { 131 | // irparams.rcvstate = STATE_STOP; 132 | // } 133 | // } 134 | if (irparams.rcvstate != STATE_STOP) { 135 | return ERROR; 136 | } 137 | 138 | if (decodeNEC()) { 139 | begin(); 140 | decode_time = millis(); 141 | return SUCCESS; 142 | } 143 | begin(); 144 | return ERROR; 145 | } 146 | 147 | // NECs have a repeat only 4 items long 148 | ErrorStatus MeIR::decodeNEC() { 149 | uint32_t data = 0; 150 | int offset = 0; // Skip first space 151 | // Initial mark 152 | if (!MATCH(rawbuf[offset], NEC_HDR_MARK/50)) { 153 | return ERROR; 154 | } 155 | offset++; 156 | // Check for repeat 157 | if (rawlen == 3 && 158 | MATCH(rawbuf[offset], NEC_RPT_SPACE/50) && 159 | MATCH(rawbuf[offset+1], NEC_BIT_MARK/50)) { 160 | bits = 0; 161 | // results->value = REPEAT; 162 | // Serial.println("REPEAT"); 163 | decode_type = NEC; 164 | return SUCCESS; 165 | } 166 | if (rawlen < 2 * NEC_BITS + 3) { 167 | return ERROR; 168 | } 169 | // Initial space 170 | if (!MATCH(rawbuf[offset], NEC_HDR_SPACE/50)) { 171 | return ERROR; 172 | } 173 | offset++; 174 | for (int i = 0; i < NEC_BITS; i++) { 175 | if (!MATCH(rawbuf[offset], NEC_BIT_MARK/50)) { 176 | return ERROR; 177 | } 178 | offset++; 179 | if (MATCH(rawbuf[offset], NEC_ONE_SPACE/50)) { 180 | //data = (data << 1) | 1; 181 | data = (data >> 1) | 0x80000000; 182 | } 183 | else if (MATCH(rawbuf[offset], NEC_ZERO_SPACE/50)) { 184 | //data <<= 1; 185 | data >>= 1; 186 | } 187 | else { 188 | return ERROR; 189 | 190 | } 191 | offset++; 192 | } 193 | // Success 194 | bits = NEC_BITS; 195 | value = data; 196 | decode_type = NEC; 197 | return SUCCESS; 198 | } 199 | 200 | void MeIR::mark(uint16_t us) { 201 | // Sends an IR mark for the specified number of microseconds. 202 | // The mark output is modulated at the PWM frequency. 203 | TIMER_ENABLE_PWM; // Enable pin 3 PWM output 204 | delayMicroseconds(us); 205 | } 206 | 207 | /* Leave pin off for time (given in microseconds) */ 208 | void MeIR::space(uint16_t us) { 209 | // Sends an IR space for the specified number of microseconds. 210 | // A space is no output, so the PWM output is disabled. 211 | TIMER_DISABLE_PWM; // Disable pin 3 PWM output 212 | delayMicroseconds(us); 213 | } 214 | 215 | void MeIR::enableIROut(uint8_t khz) { 216 | TIMER_DISABLE_INTR; //Timer2 disable Interrupt 217 | TIMER_CONFIG_KHZ(khz); 218 | } 219 | 220 | void MeIR::sendRaw(unsigned int buf[], int len, uint8_t hz) 221 | { 222 | enableIROut(hz); 223 | for (int i = 0; i < len; i++) { 224 | if (i & 1) { 225 | space(buf[i]); 226 | } 227 | else { 228 | mark(buf[i]); 229 | } 230 | } 231 | space(0); // Just to be sure 232 | } 233 | String MeIR::getString(){ 234 | if(decode()) 235 | { 236 | irRead = ((value>>8)>>8)&0xff; 237 | if(irRead==0xa||irRead==0xd){ 238 | irIndex = 0; 239 | irReady = true; 240 | }else{ 241 | irBuffer+=irRead; 242 | irIndex++; 243 | } 244 | irDelay = 0; 245 | }else{ 246 | irDelay++; 247 | if(irRead>0){ 248 | if(irDelay>5000){ 249 | irRead = 0; 250 | irDelay = 0; 251 | } 252 | } 253 | } 254 | if(irReady){ 255 | irReady = false; 256 | String s = String(irBuffer); 257 | irBuffer = ""; 258 | return s; 259 | } 260 | return ""; 261 | } 262 | unsigned char MeIR::getCode(){ 263 | if(decode()) 264 | { 265 | irRead = ((value>>8)>>8)&0xff; 266 | } 267 | return irRead; 268 | } 269 | void MeIR::sendString(String s){ 270 | unsigned long l; 271 | for(int i=0;i>= 1; 298 | } 299 | mark(NEC_BIT_MARK); 300 | space(0); 301 | } 302 | void MeIR::loop(){ 303 | if(decode()) 304 | { 305 | irRead = ((value>>8)>>8)&0xff; 306 | lastIRTime = millis()/1000.0; 307 | irPressed = true; 308 | if(irRead==0xa||irRead==0xd){ 309 | irIndex = 0; 310 | irReady = true; 311 | }else{ 312 | irBuffer+=irRead; 313 | irIndex++; 314 | if(irIndex>64){ 315 | irIndex = 0; 316 | irBuffer = ""; 317 | } 318 | } 319 | irDelay = 0; 320 | }else{ 321 | irDelay++; 322 | if(irRead>0){ 323 | if(irDelay>5000){ 324 | irRead = 0; 325 | irDelay = 0; 326 | } 327 | } 328 | } 329 | } 330 | boolean MeIR::keyPressed(unsigned char r){ 331 | irIndex = 0; 332 | if(millis()/1000.0-lastIRTime>0.2){ 333 | return false; 334 | } 335 | return irRead==r; 336 | } 337 | -------------------------------------------------------------------------------- /mBot-default-program/MeIR.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef MeIR_h 4 | #define MeIR_h 5 | 6 | #include "MePort.h" 7 | 8 | #define MARK 0 9 | #define SPACE 1 10 | #define NEC_BITS 32 11 | 12 | #define USECPERTICK 50 // microseconds per clock interrupt tick 13 | #define RAWBUF 100 // Length of raw duration buffer 14 | 15 | typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; 16 | 17 | #define NEC_HDR_MARK 9000 18 | #define NEC_HDR_SPACE 4500 19 | #define NEC_BIT_MARK 560 20 | #define NEC_ONE_SPACE 1600 21 | #define NEC_ZERO_SPACE 560 22 | #define NEC_RPT_SPACE 2250 23 | #define NEC_RPT_PERIOD 110000 24 | 25 | 26 | // #define TOLERANCE 25 // percent tolerance in measurements 27 | // #define LTOL (1.0 - TOLERANCE/100.) 28 | // #define UTOL (1.0 + TOLERANCE/100.) 29 | 30 | #define _GAP 5000 // Minimum map between transmissions 31 | // #define GAP_TICKS 5000//(_GAP/USECPERTICK) 32 | 33 | // #define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK)) 34 | // #define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1)) 35 | 36 | // receiver states 37 | #define STATE_IDLE 2 38 | #define STATE_MARK 3 39 | #define STATE_SPACE 4 40 | #define STATE_STOP 5 41 | 42 | 43 | // Values for decode_type 44 | #define NEC 1 45 | #define SONY 2 46 | #define RC5 3 47 | #define RC6 4 48 | #define DISH 5 49 | #define SHARP 6 50 | #define PANASONIC 7 51 | #define JVC 8 52 | #define SANYO 9 53 | #define MITSUBISHI 10 54 | #define SAMSUNG 11 55 | #define LG 12 56 | #define UNKNOWN -1 57 | 58 | #define TOPBIT 0x80000000 59 | 60 | 61 | #ifdef F_CPU 62 | #define SYSCLOCK F_CPU // main Arduino clock 63 | #else 64 | #define SYSCLOCK 16000000 // main Arduino clock 65 | #endif 66 | 67 | 68 | #define _GAP 5000 // Minimum map between transmissions 69 | #define GAP_TICKS (_GAP/USECPERTICK) 70 | 71 | 72 | #define TIMER_DISABLE_INTR (TIMSK2 = 0) 73 | #define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) 74 | #define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) 75 | #define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) 76 | #define TIMER_DISABLE_INTR (TIMSK2 = 0) 77 | #define TIMER_INTR_NAME TIMER2_COMPA_vect 78 | #define TIMER_CONFIG_KHZ(val) ({ \ 79 | const uint8_t pwmval = F_CPU / 2000 / (val); \ 80 | TCCR2A = _BV(WGM20); \ 81 | TCCR2B = _BV(WGM22) | _BV(CS20); \ 82 | OCR2A = pwmval; \ 83 | OCR2B = pwmval / 3; \ 84 | }) 85 | 86 | #define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) 87 | #if (TIMER_COUNT_TOP < 256) 88 | #define TIMER_CONFIG_NORMAL() ({ \ 89 | TCCR2A = _BV(WGM21); \ 90 | TCCR2B = _BV(CS20); \ 91 | OCR2A = TIMER_COUNT_TOP; \ 92 | TCNT2 = 0; \ 93 | }) 94 | #else 95 | #define TIMER_CONFIG_NORMAL() ({ \ 96 | TCCR2A = _BV(WGM21); \ 97 | TCCR2B = _BV(CS21); \ 98 | OCR2A = TIMER_COUNT_TOP / 8; \ 99 | TCNT2 = 0; \ 100 | }) 101 | #endif 102 | 103 | // information for the interrupt handler 104 | typedef struct { 105 | uint8_t recvpin; // pin for IR data from detector 106 | volatile uint8_t rcvstate; // state machine 107 | volatile uint32_t lastTime; 108 | unsigned int timer; // 109 | volatile uint8_t rawbuf[RAWBUF]; // raw data 110 | volatile uint8_t rawlen; // counter of entries in rawbuf 111 | } 112 | irparams_t; 113 | 114 | 115 | 116 | 117 | 118 | // main class for receiving IR 119 | class MeIR 120 | { 121 | public: 122 | MeIR(); 123 | 124 | 125 | ErrorStatus decode(); 126 | void begin(); 127 | void end(); 128 | void loop(); 129 | boolean keyPressed(unsigned char r); 130 | // void resume(); 131 | int8_t decode_type; // NEC, SONY, RC5, UNKNOWN 132 | unsigned long value; // Decoded value 133 | uint8_t bits; // Number of bits in decoded value 134 | volatile uint8_t *rawbuf; // Raw intervals in .5 us ticks 135 | int rawlen; // Number of records in rawbuf. 136 | String getString(); 137 | unsigned char getCode(); 138 | void sendString(String s); 139 | void sendString(float v); 140 | void sendNEC(unsigned long data, int nbits); 141 | void sendSony(unsigned long data, int nbits); 142 | // Neither Sanyo nor Mitsubishi send is implemented yet 143 | // void sendSanyo(unsigned long data, int nbits); 144 | // void sendMitsubishi(unsigned long data, int nbits); 145 | void sendRaw(unsigned int buf[], int len, uint8_t hz); 146 | void sendRC5(unsigned long data, int nbits); 147 | void sendRC6(unsigned long data, int nbits); 148 | void sendDISH(unsigned long data, int nbits); 149 | void sendSharp(unsigned int address, unsigned int command); 150 | void sendSharpRaw(unsigned long data, int nbits); 151 | void sendPanasonic(unsigned int address, unsigned long data); 152 | 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. 153 | // private: 154 | void sendSAMSUNG(unsigned long data, int nbits); 155 | void enableIROut(uint8_t khz); 156 | void mark(uint16_t us); 157 | void space(uint16_t us); 158 | private: 159 | // These are called by decode 160 | ErrorStatus decodeNEC(); 161 | int irDelay; 162 | int irIndex; 163 | char irRead; 164 | boolean irReady; 165 | boolean irPressed; 166 | String irBuffer; 167 | double lastIRTime; 168 | char floatString[5]; 169 | 170 | }; 171 | 172 | #endif 173 | -------------------------------------------------------------------------------- /mBot-default-program/MeInfraredReceiver.cpp: -------------------------------------------------------------------------------- 1 | #include "MeInfraredReceiver.h" 2 | MeInfraredReceiver::MeInfraredReceiver():MePort(),SoftwareSerial(NC, NC){ 3 | 4 | } 5 | 6 | MeInfraredReceiver::MeInfraredReceiver(MEPORT port):MePort(port),SoftwareSerial(mePort[port].s2, mePort[port].s1){ 7 | // SoftwareSerial::begin(9600); 8 | _staPin = s1; 9 | } 10 | 11 | MeInfraredReceiver::MeInfraredReceiver(uint8_t staPin,uint8_t datPin):SoftwareSerial(datPin, staPin){ 12 | // SoftwareSerial::begin(9600); 13 | _staPin = staPin; 14 | 15 | // pinMode(s2,INPUT); 16 | } 17 | 18 | int MeInfraredReceiver::available(){ 19 | // pinMode(s1, INPUT); 20 | // pinMode(_staPin, INPUT); 21 | if(SoftwareSerial::available() || digitalRead(_staPin)==0)return 1; 22 | return 0; 23 | } 24 | 25 | bool MeInfraredReceiver::buttonState(){ 26 | 27 | if(getPort()>0){ 28 | return dRead1()==0; 29 | } 30 | return 0; 31 | } 32 | 33 | int MeInfraredReceiver::read() 34 | { 35 | uint8_t val; 36 | uint16_t i; 37 | do 38 | { 39 | i++; 40 | if(++i > 2000)break; 41 | if(SoftwareSerial::available()) 42 | val = SoftwareSerial::read(); //Read serial infrared data 43 | val &= 0xff; 44 | } 45 | while(val == 0x0 || val == 0xFF); //0x0 and 0xff are the user code of BC7210A IC 46 | delayMicroseconds(10); 47 | return val; 48 | 49 | } 50 | 51 | void MeInfraredReceiver::begin() 52 | { 53 | SoftwareSerial::begin(9600); 54 | pinMode(_staPin, INPUT); 55 | } -------------------------------------------------------------------------------- /mBot-default-program/MeInfraredReceiver.h: -------------------------------------------------------------------------------- 1 | #ifndef MeInfraredReceiver_H_ 2 | #define MeInfraredReceiver_H_ 3 | #include "MePort.h" 4 | //NEC Code table 5 | #define IR_BUTTON_POWER 0x45 6 | #define IR_BUTTON_A 0x45 7 | #define IR_BUTTON_B 0x46 8 | #define IR_BUTTON_MENU 0x47 9 | #define IR_BUTTON_C 0x47 10 | #define IR_BUTTON_TEST 0x44 11 | #define IR_BUTTON_D 0x44 12 | #define IR_BUTTON_PLUS 0x40 13 | #define IR_BUTTON_UP 0x40 14 | #define IR_BUTTON_RETURN 0x43 15 | #define IR_BUTTON_E 0x43 16 | #define IR_BUTTON_PREVIOUS 0x07 17 | #define IR_BUTTON_LEFT 0x07 18 | #define IR_BUTTON_PLAY 0x15 19 | #define IR_BUTTON_SETTING 0x15 20 | #define IR_BUTTON_NEXT 0x09 21 | #define IR_BUTTON_RIGHT 0x09 22 | #define IR_BUTTON_MINUS 0x19 23 | #define IR_BUTTON_DOWN 0x19 24 | #define IR_BUTTON_CLR 0x0D 25 | #define IR_BUTTON_F 0x0D 26 | #define IR_BUTTON_0 0x16 27 | #define IR_BUTTON_1 0x0C 28 | #define IR_BUTTON_2 0x18 29 | #define IR_BUTTON_3 0x5E 30 | #define IR_BUTTON_4 0x08 31 | #define IR_BUTTON_5 0x1C 32 | #define IR_BUTTON_6 0x5A 33 | #define IR_BUTTON_7 0x42 34 | #define IR_BUTTON_8 0x52 35 | #define IR_BUTTON_9 0x4A 36 | 37 | class MeInfraredReceiver:public MePort,public SoftwareSerial{ 38 | public: 39 | MeInfraredReceiver(); 40 | MeInfraredReceiver(MEPORT port); 41 | MeInfraredReceiver(uint8_t staPin,uint8_t datPin); 42 | int available(); 43 | int read(); 44 | bool buttonState(); 45 | void begin(); 46 | private: 47 | uint8_t _staPin; 48 | }; 49 | #endif 50 | -------------------------------------------------------------------------------- /mBot-default-program/MeLEDMatrix.cpp: -------------------------------------------------------------------------------- 1 | #include "MeLEDMatrix.h" 2 | #include "MeLEDMatrixData.h" 3 | 4 | MeLEDMatrix::MeLEDMatrix():MePort() 5 | { 6 | 7 | } 8 | 9 | 10 | MeLEDMatrix::MeLEDMatrix(uint8_t port): MePort(port) 11 | { 12 | pinMode(s1, OUTPUT); 13 | pinMode(s2, OUTPUT); 14 | digitalWrite(s1,HIGH); 15 | digitalWrite(s2,HIGH); 16 | 17 | writeByte(Mode_Address_Auto_Add_1); 18 | setBrightness(Brightness_5); 19 | clearScreen(); 20 | } 21 | 22 | 23 | MeLEDMatrix::MeLEDMatrix(uint8_t SCK_Pin, uint8_t DIN_Pin) 24 | { 25 | s1 = SCK_Pin; 26 | s2 = DIN_Pin; 27 | 28 | pinMode(s1, OUTPUT); 29 | pinMode(s2, OUTPUT); 30 | digitalWrite(s1,HIGH); 31 | digitalWrite(s2,HIGH); 32 | 33 | writeByte(Mode_Address_Auto_Add_1); 34 | setBrightness(Brightness_5); 35 | clearScreen(); 36 | } 37 | 38 | 39 | void MeLEDMatrix::writeByte(uint8_t data) 40 | { 41 | //Start 42 | digitalWrite(s1, HIGH); 43 | digitalWrite(s2, LOW); 44 | 45 | for(char i=0;i<8;i++) 46 | { 47 | digitalWrite(s1, LOW); 48 | digitalWrite(s2, (data & 0x01)); 49 | digitalWrite(s1, HIGH); 50 | data = data >> 1; 51 | } 52 | 53 | //End 54 | digitalWrite(s1, LOW); 55 | digitalWrite(s2, LOW); 56 | digitalWrite(s1, HIGH); 57 | digitalWrite(s2, HIGH); 58 | // delayMicroseconds(1); 59 | } 60 | 61 | 62 | 63 | 64 | void MeLEDMatrix::writeBytesToAddress(uint8_t Address, const uint8_t *P_data, uint8_t count_of_data) 65 | { 66 | uint8_t T_data; 67 | 68 | if(Address > 15 || count_of_data==0) 69 | return; 70 | 71 | Address = ADDRESS(Address); 72 | 73 | //Start 74 | digitalWrite(s1, HIGH); 75 | digitalWrite(s2, LOW); 76 | 77 | //write Address 78 | for(char i=0;i<8;i++) 79 | { 80 | digitalWrite(s1, LOW); 81 | digitalWrite(s2, (Address & 0x01)); 82 | digitalWrite(s1, HIGH); 83 | Address = Address >> 1; 84 | } 85 | 86 | 87 | //write data 88 | for(uint8_t k=0; k8) 129 | { 130 | Bright = Brightness_8; 131 | } 132 | 133 | if((uint8_t)Bright != 0) 134 | { 135 | Bright = (LED_Matrix_Brightness_TypeDef)((uint8_t)(Bright-1)|0x08); 136 | 137 | } 138 | writeByte(0x80 | (uint8_t)Bright); 139 | 140 | } 141 | 142 | 143 | void MeLEDMatrix::setColorIndex(bool Color_Number) 144 | { 145 | b_Color_Index = Color_Number; 146 | } 147 | 148 | void MeLEDMatrix::drawBitmap(int8_t x, int8_t y, uint8_t Bitmap_Width, uint8_t *Bitmap) 149 | { 150 | 151 | if(x>15 || y>7 || Bitmap_Width==0) 152 | return; 153 | 154 | 155 | if(b_Color_Index == 1) 156 | { 157 | for(uint8_t k=0;k=0){ 160 | u8_Display_Buffer[x+k] = (u8_Display_Buffer[x+k] & (0xff << (8-y))) | (y>0?(Bitmap[k] >> y):(Bitmap[k] << (-y))); 161 | } 162 | } 163 | } 164 | else if(b_Color_Index == 0) 165 | { 166 | for(uint8_t k=0;k=0){ 169 | u8_Display_Buffer[x+k] = (u8_Display_Buffer[x+k] & (0xff << (8-y))) | (y>0?(~Bitmap[k] >> y):(~Bitmap[k] << (-y))); 170 | } 171 | } 172 | } 173 | 174 | writeBytesToAddress(0,u8_Display_Buffer,LED_BUFFER_SIZE); 175 | } 176 | 177 | 178 | 179 | void MeLEDMatrix::drawStr(int16_t X_position, int8_t Y_position, const char *str) 180 | { 181 | b_Draw_Str_Flag = 1; 182 | 183 | for(i16_Number_of_Character_of_Str = 0; str[i16_Number_of_Character_of_Str] != '\0'; i16_Number_of_Character_of_Str++) 184 | { 185 | if(i16_Number_of_Character_of_Str < STRING_DISPLAY_BUFFER_SIZE - 1) 186 | { 187 | i8_Str_Display_Buffer[i16_Number_of_Character_of_Str] = str[i16_Number_of_Character_of_Str]; 188 | } 189 | else 190 | { 191 | break; 192 | } 193 | } 194 | i8_Str_Display_Buffer[i16_Number_of_Character_of_Str] = '\0'; 195 | 196 | 197 | if(X_position < -(i16_Number_of_Character_of_Str * 6)) 198 | { 199 | X_position = -(i16_Number_of_Character_of_Str * 6); 200 | } 201 | else if(X_position > 16) 202 | { 203 | X_position = 16; 204 | } 205 | i16_Str_Display_X_Position = X_position; 206 | 207 | 208 | if(Y_position < -1) 209 | { 210 | Y_position = -1; 211 | } 212 | else if(Y_position >15) 213 | { 214 | Y_position = 15; 215 | } 216 | i8_Str_Display_Y_Position = Y_position; 217 | 218 | showStr(); 219 | 220 | } 221 | 222 | 223 | void MeLEDMatrix::showStr() 224 | { 225 | 226 | uint8_t display_buffer_label = 0; 227 | 228 | if(i16_Str_Display_X_Position > 0) 229 | { 230 | for(display_buffer_label = 0; display_buffer_label < i16_Str_Display_X_Position && display_buffer_label < LED_BUFFER_SIZE; display_buffer_label++) 231 | { 232 | u8_Display_Buffer[display_buffer_label] = 0x00; 233 | } 234 | 235 | if(display_buffer_label < LED_BUFFER_SIZE) 236 | { 237 | uint8_t num; 238 | 239 | for(uint8_t k=0;display_buffer_label < LED_BUFFER_SIZE && k < i16_Number_of_Character_of_Str;k++) 240 | { 241 | for(num=0; pgm_read_byte(&Character_font_6x8[num].Character[0]) != '@'; num++) 242 | { 243 | if(i8_Str_Display_Buffer[k] == pgm_read_byte(&Character_font_6x8[num].Character[0])) 244 | { 245 | for(uint8_t j=0;j<6;j++) 246 | { 247 | u8_Display_Buffer[display_buffer_label] = pgm_read_byte(&Character_font_6x8[num].data[j]); 248 | display_buffer_label++; 249 | 250 | if(display_buffer_label >= LED_BUFFER_SIZE) 251 | { 252 | break; 253 | } 254 | } 255 | break; 256 | } 257 | } 258 | 259 | if(pgm_read_byte(&Character_font_6x8[num].Character[0]) == '@') 260 | { 261 | i8_Str_Display_Buffer[k] = ' '; 262 | k--; 263 | } 264 | } 265 | 266 | if(display_buffer_label < LED_BUFFER_SIZE) 267 | { 268 | for(display_buffer_label = display_buffer_label; display_buffer_label < LED_BUFFER_SIZE; display_buffer_label++) 269 | { 270 | u8_Display_Buffer[display_buffer_label] = 0x00; 271 | } 272 | } 273 | } 274 | } 275 | 276 | else if(i16_Str_Display_X_Position <= 0) 277 | { 278 | if(i16_Str_Display_X_Position == -(i16_Number_of_Character_of_Str * 6)) 279 | { 280 | for(; display_buffer_label < LED_BUFFER_SIZE; display_buffer_label++) 281 | { 282 | u8_Display_Buffer[display_buffer_label] = 0x00; 283 | } 284 | } 285 | else 286 | { 287 | int8_t j = (-i16_Str_Display_X_Position) % 6; 288 | uint8_t num; 289 | 290 | i16_Str_Display_X_Position = -i16_Str_Display_X_Position; 291 | 292 | for(int16_t k=i16_Str_Display_X_Position/6; display_buffer_label < LED_BUFFER_SIZE && k < i16_Number_of_Character_of_Str;k++) 293 | { 294 | for(num=0; pgm_read_byte(&Character_font_6x8[num].Character[0]) != '@'; num++) 295 | { 296 | if(i8_Str_Display_Buffer[k] == pgm_read_byte(&Character_font_6x8[num].Character[0])) 297 | { 298 | for(;j<6;j++) 299 | { 300 | u8_Display_Buffer[display_buffer_label] = pgm_read_byte(&Character_font_6x8[num].data[j]); 301 | display_buffer_label++; 302 | 303 | if(display_buffer_label >= LED_BUFFER_SIZE) 304 | { 305 | break; 306 | } 307 | } 308 | j=0; 309 | break; 310 | } 311 | } 312 | 313 | if(pgm_read_byte(&Character_font_6x8[num].Character[0]) == '@') 314 | { 315 | i8_Str_Display_Buffer[k] = ' '; 316 | k--; 317 | } 318 | 319 | } 320 | 321 | if(display_buffer_label < LED_BUFFER_SIZE) 322 | { 323 | for(; display_buffer_label < LED_BUFFER_SIZE; display_buffer_label++) 324 | { 325 | u8_Display_Buffer[display_buffer_label] = 0x00; 326 | } 327 | } 328 | 329 | i16_Str_Display_X_Position = -i16_Str_Display_X_Position; 330 | } 331 | } 332 | 333 | 334 | if(7 - i8_Str_Display_Y_Position >= 0) 335 | { 336 | for(uint8_t k=0; k> (i8_Str_Display_Y_Position - 7); 346 | } 347 | } 348 | 349 | 350 | if(b_Color_Index == 0) 351 | { 352 | for(uint8_t k=0; k 5 | 6 | 7 | typedef struct 8 | { 9 | uint8_t Character[1]; 10 | uint8_t data[6]; 11 | }LED_Matrix_Font_6x8_TypeDef; 12 | const LED_Matrix_Font_6x8_TypeDef Character_font_6x8[] PROGMEM = 13 | { 14 | ' ', 0x00,0x00,0x00,0x00,0x00,0x00, 15 | 16 | '0', 0x00,0x7C,0x82,0x82,0x7C,0x00, 17 | '1', 0x00,0x42,0xFE,0x02,0x00,0x00, 18 | '2', 0x00,0x46,0x8A,0x92,0x62,0x00, 19 | '3', 0x00,0x44,0x92,0x92,0x6C,0x00, 20 | '4', 0x00,0x1C,0x64,0xFE,0x04,0x00, 21 | '5', 0x00,0xF2,0x92,0x92,0x8C,0x00, 22 | '6', 0x00,0x7C,0x92,0x92,0x4C,0x00, 23 | '7', 0x00,0xC0,0x8E,0x90,0xE0,0x00, 24 | '8', 0x00,0x6C,0x92,0x92,0x6C,0x00, 25 | '9', 0x00,0x64,0x92,0x92,0x7C,0x00, 26 | 27 | 'a', 0x00,0x04,0x2A,0x2A,0x1E,0x00, 28 | 'b', 0x00,0xFE,0x12,0x12,0x0C,0x00, 29 | 'c', 0x00,0x0C,0x12,0x12,0x12,0x00, 30 | 'd', 0x00,0x0C,0x12,0x12,0xFE,0x00, 31 | 'e', 0x00,0x1C,0x2A,0x2A,0x18,0x00, 32 | 'f', 0x00,0x10,0x3E,0x50,0x50,0x00, 33 | 'g', 0x00,0x08,0x15,0x15,0x1E,0x00, 34 | 'h', 0x00,0xFE,0x10,0x1E,0x00,0x00, 35 | 'i', 0x00,0x00,0x2E,0x00,0x00,0x00, 36 | 'j', 0x00,0x02,0x01,0x2E,0x00,0x00, 37 | 'k', 0x00,0xFE,0x08,0x14,0x12,0x00, 38 | 'l', 0x00,0x00,0xFE,0x02,0x00,0x00, 39 | 'm', 0x00,0x1E,0x10,0x0E,0x10,0x0E, 40 | 'n', 0x00,0x1E,0x10,0x10,0x0E,0x00, 41 | 'o', 0x00,0x0C,0x12,0x12,0x0C,0x00, 42 | 'p', 0x00,0x1F,0x12,0x12,0x0C,0x00, 43 | 'q', 0x00,0x0C,0x12,0x12,0x1F,0x00, 44 | 'r', 0x00,0x1E,0x08,0x10,0x10,0x00, 45 | 's', 0x00,0x12,0x29,0x25,0x12,0x00, 46 | 't', 0x00,0x10,0x3E,0x12,0x00,0x00, 47 | 'u', 0x00,0x1C,0x02,0x02,0x1E,0x00, 48 | 'v', 0x18,0x04,0x02,0x04,0x18,0x00, 49 | 'w', 0x18,0x06,0x1C,0x06,0x18,0x00, 50 | 'x', 0x00,0x12,0x0C,0x0C,0x12,0x00, 51 | 'y', 0x00,0x18,0x05,0x05,0x1E,0x00, 52 | 'z', 0x00,0x12,0x16,0x1A,0x12,0x00, 53 | 54 | 'A', 0x00,0x7E,0x88,0x88,0x7E,0x00, 55 | 'B', 0x00,0xFE,0x92,0x92,0x6C,0x00, 56 | 'C', 0x00,0x7C,0x82,0x82,0x44,0x00, 57 | 'D', 0x00,0xFE,0x82,0x82,0x7C,0x00, 58 | 'E', 0x00,0xFE,0x92,0x92,0x82,0x00, 59 | 'F', 0x00,0xFE,0x90,0x90,0x80,0x00, 60 | 'G', 0x00,0x7C,0x82,0x92,0x5C,0x00, 61 | 'H', 0x00,0xFE,0x10,0x10,0xFE,0x00, 62 | 'I', 0x00,0x82,0xFE,0x82,0x00,0x00, 63 | 'J', 0x00,0x0C,0x02,0x02,0xFC,0x00, 64 | 'K', 0x00,0xFE,0x10,0x28,0xC6,0x00, 65 | 'L', 0x00,0xFE,0x02,0x02,0x02,0x00, 66 | 'M', 0x00,0xFE,0x40,0x30,0x40,0xFE, 67 | 'N', 0x00,0xFE,0x40,0x30,0x08,0xFE, 68 | 'O', 0x00,0x7C,0x82,0x82,0x82,0x7C, 69 | 'P', 0x00,0xFE,0x90,0x90,0x60,0x00, 70 | 'Q', 0x00,0x7C,0x82,0x8A,0x84,0x7A, 71 | 'R', 0x00,0xFE,0x98,0x94,0x62,0x00, 72 | 'S', 0x00,0x64,0x92,0x92,0x4C,0x00, 73 | 'T', 0x00,0x80,0xFE,0x80,0x80,0x00, 74 | 'U', 0x00,0xFC,0x02,0x02,0xFC,0x00, 75 | 'V', 0x00,0xF0,0x0C,0x02,0x0C,0xF0, 76 | 'W', 0x00,0xFE,0x04,0x38,0x04,0xFE, 77 | 'X', 0x00,0xC6,0x38,0x38,0xC6,0x00, 78 | 'Y', 0xC0,0x20,0x1E,0x20,0xC0,0x00, 79 | 'Z', 0x00,0x86,0x9A,0xB2,0xC2,0x00, 80 | ',', 0x00,0x01,0x0e,0x0c,0x00,0x00, 81 | '.', 0x00,0x00,0x06,0x06,0x00,0x00, 82 | '%', 0x72,0x54,0x78,0x1e,0x2a,0x4e, 83 | '!', 0x00,0x00,0x7a,0x00,0x00,0x00, 84 | '?', 0x00,0x20,0x4a,0x30,0x00,0x00, 85 | '-', 0x00,0x10,0x10,0x10,0x10,0x00, 86 | '+', 0x08,0x08,0x3e,0x08,0x08,0x00, 87 | '/', 0x00,0x02,0x0c,0x30,0x40,0x00, 88 | '*', 0x22,0x14,0x08,0x14,0x22,0x00, 89 | ':', 0x00,0x00,0x14,0x00,0x00,0x00, 90 | '@', 0x00,0x00,0x00,0x00,0x00,0x00 // End mark of Character_font_6x8 91 | }; 92 | 93 | 94 | 95 | 96 | 97 | 98 | typedef struct 99 | { 100 | uint8_t data[3]; 101 | }LED_Matrix_Clock_Number_Font_3x8_TypeDef; 102 | 103 | const LED_Matrix_Clock_Number_Font_3x8_TypeDef Clock_Number_font_3x8[] PROGMEM = 104 | { 105 | 0x7C,0x44,0x7C, //0 106 | 0x00,0x00,0x7C, //1 107 | 0x5C,0x54,0x74, //2 108 | 0x54,0x54,0x7C, //3 109 | 0x70,0x10,0x7C, //4 110 | 0x74,0x54,0x5C, //5 111 | 0x7C,0x54,0x5C, //6 112 | 0x40,0x40,0x7C, //7 113 | 0x7C,0x54,0x7C, //8 114 | 0x74,0x54,0x7C, //9 115 | }; 116 | 117 | 118 | #endif 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /mBot-default-program/MeLineFollower.cpp: -------------------------------------------------------------------------------- 1 | #include "MeLineFollower.h" 2 | /* LineFinder */ 3 | 4 | MeLineFollower::MeLineFollower(uint8_t pin1,uint8_t pin2) 5 | { 6 | _pin1 = pin1; 7 | _pin2 = pin2; 8 | pinMode(_pin1,INPUT); 9 | pinMode(_pin2,INPUT); 10 | } 11 | 12 | MeLineFollower::MeLineFollower(MEPORT port): MePort(port) 13 | { 14 | _pin1 = s1; 15 | _pin2 = s2; 16 | pinMode(_pin1,INPUT); 17 | pinMode(_pin2,INPUT); 18 | } 19 | uint8_t MeLineFollower::readSensors() 20 | { 21 | // uint8_t state = S1_IN_S2_IN; 22 | uint8_t state = digitalRead(_pin1); 23 | state = (state << 1) | digitalRead(_pin2); 24 | // state = ((1 & s1State) << 1) | s2State; 25 | return state; 26 | } 27 | bool MeLineFollower::readSensor1() 28 | { 29 | return digitalRead(_pin1); 30 | } 31 | bool MeLineFollower::readSensor2() 32 | { 33 | return digitalRead(_pin2); 34 | } -------------------------------------------------------------------------------- /mBot-default-program/MeLineFollower.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef MELINEFOLLOWER_H_ 3 | #define MELINEFOLLOWER_H_ 4 | #include "MePort.h" 5 | 6 | //states of two lineFollower sensors 7 | 8 | #define S1_IN_S2_IN 0x00 //sensor1 and sensor2 are both inside of black line 9 | #define S1_IN_S2_OUT 0x01 //sensor1 is inside of black line and sensor is outside of black line 10 | #define S1_OUT_S2_IN 0x02 //sensor1 is outside of black line and sensor is inside of black line 11 | #define S1_OUT_S2_OUT 0x03 //sensor1 is outside of black line and sensor is outside of black line 12 | ///@brief Class for Line Follower Module 13 | class MeLineFollower: public MePort 14 | { 15 | public: 16 | ///@brief initialize 17 | MeLineFollower(uint8_t pin1,uint8_t pin2); 18 | MeLineFollower(MEPORT port); 19 | ///@brief state of all sensors 20 | ///@return state of sensors 21 | uint8_t readSensors(); 22 | ///@brief state of left sensors 23 | bool readSensor1(); 24 | ///@brief state of right sensors 25 | bool readSensor2(); 26 | private: 27 | uint8_t _pin1; 28 | uint8_t _pin2; 29 | }; 30 | #endif 31 | -------------------------------------------------------------------------------- /mBot-default-program/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 | // #define _usemCore 16 | 17 | 18 | 19 | /* Port */ 20 | MePort::MePort(){ 21 | s1 = mePort[0].s1; 22 | s2 = mePort[0].s2; 23 | _port = 0; 24 | } 25 | MePort::MePort(uint8_t port) 26 | { 27 | s1 = mePort[port].s1; 28 | s2 = mePort[port].s2; 29 | _port = port; 30 | } 31 | MePort::MePort(uint8_t port,uint8_t slot) 32 | { 33 | s1 = mePort[port].s1; 34 | s2 = mePort[port].s2; 35 | _port = port; 36 | _slot = slot; 37 | } 38 | uint8_t MePort::getPort(){ 39 | return _port; 40 | } 41 | uint8_t MePort::getSlot(){ 42 | return _slot; 43 | } 44 | bool MePort::dRead1() 45 | { 46 | bool val; 47 | pinMode(s1, INPUT); 48 | val = digitalRead(s1); 49 | return val; 50 | } 51 | 52 | bool MePort::dRead2() 53 | { 54 | bool val; 55 | pinMode(s2, INPUT); 56 | val = digitalRead(s2); 57 | return val; 58 | } 59 | 60 | void MePort::dWrite1(bool value) 61 | { 62 | pinMode(s1, OUTPUT); 63 | digitalWrite(s1, value); 64 | } 65 | 66 | void MePort::dWrite2(bool value) 67 | { 68 | pinMode(s2, OUTPUT); 69 | digitalWrite(s2, value); 70 | } 71 | 72 | int MePort::aRead1() 73 | { 74 | int val; 75 | val = analogRead(s1); 76 | return val; 77 | } 78 | 79 | int MePort::aRead2() 80 | { 81 | int val; 82 | val = analogRead(s2); 83 | return val; 84 | } 85 | 86 | void MePort::aWrite1(int value) 87 | { 88 | analogWrite(s1, value); 89 | } 90 | 91 | void MePort::aWrite2(int value) 92 | { 93 | analogWrite(s2, value); 94 | } 95 | void MePort::reset(uint8_t port){ 96 | s1 = mePort[port].s1; 97 | s2 = mePort[port].s2; 98 | _port = port; 99 | } 100 | void MePort::reset(uint8_t port,uint8_t slot){ 101 | s1 = mePort[port].s1; 102 | s2 = mePort[port].s2; 103 | _port = port; 104 | _slot = slot; 105 | } 106 | uint8_t MePort::pin1(){ 107 | return s1; 108 | } 109 | uint8_t MePort::pin2(){ 110 | return s2; 111 | } 112 | 113 | uint8_t MePort::pin(){ 114 | return _slot==SLOT1?s1:s2; 115 | } 116 | uint8_t MePort::pin(uint8_t port,uint8_t slot){ 117 | return slot==SLOT1?mePort[port].s1:mePort[port].s2; 118 | } 119 | 120 | 121 | /* I2C */ 122 | static uint32_t neutralizeTime = 0; 123 | static int16_t i2c_errors_count = 0; 124 | void i2c_init(void) { 125 | // #if defined(INTERNAL_I2C_PULLUPS) 126 | // I2C_PULLUPS_ENABLE 127 | // #else 128 | // I2C_PULLUPS_DISABLE 129 | // #endif 130 | TWSR = 0; // no prescaler => prescaler = 1 131 | TWBR = ((F_CPU / 1000000) - 16) / 2; // change the I2C clock rate 132 | TWCR = 1< we don't insist 140 | TWCR = 0; //and we force a reset on TWINT register 141 | neutralizeTime = micros(); //we take a timestamp here to neutralize the value during a short delay 142 | i2c_errors_count++; 143 | Serial.println("i2cerr"); 144 | break; 145 | } 146 | } 147 | } 148 | 149 | void i2c_rep_start(uint8_t address) { 150 | TWCR = (1< 0); 192 | /* TODO catch I2C errors here and abort */ 193 | bytes_read++; 194 | } 195 | return bytes_read; 196 | } 197 | 198 | size_t i2c_read_reg_to_buf(uint8_t add, uint8_t reg, void *buf, size_t size) { 199 | i2c_rep_start(add<<1); // I2C write direction 200 | i2c_write(reg); // register selection 201 | return i2c_read_to_buf(add, buf, size); 202 | } 203 | 204 | void i2c_writeReg(uint8_t add, uint8_t reg, uint8_t val) { 205 | i2c_rep_start(add<<1); // I2C write direction 206 | i2c_write(reg); // register selection 207 | i2c_write(val); // value to write in register 208 | i2c_stop(); 209 | } 210 | 211 | uint8_t i2c_readReg(uint8_t add, uint8_t reg) { 212 | uint8_t val; 213 | i2c_read_reg_to_buf(add, reg, &val, 1); 214 | return val; 215 | } 216 | int8_t i2c_readBit(uint8_t add, uint8_t reg, uint8_t bitNum) { 217 | uint8_t b; 218 | b = i2c_readReg(add, reg); 219 | return b & (1 << bitNum); 220 | } 221 | int8_t i2c_readBits(uint8_t dev, uint8_t reg, uint8_t bitStart, uint8_t length) { 222 | uint8_t b; 223 | b = i2c_readReg(dev, reg); 224 | uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); 225 | b &= mask; 226 | b >>= (bitStart - length + 1); 227 | return b; 228 | } 229 | void i2c_writeBits(uint8_t dev, uint8_t reg, uint8_t bitStart, uint8_t length,uint8_t data) { 230 | // 010 value to write 231 | // 76543210 bit numbers 232 | // xxx args: bitStart=4, length=3 233 | // 00011100 mask byte 234 | // 10101111 original value (sample) 235 | // 10100011 original & ~mask 236 | // 10101011 masked | value 237 | uint8_t b; 238 | b = i2c_readReg(dev, reg); 239 | uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); 240 | data <<= (bitStart - length + 1); // shift data into correct position 241 | data &= mask; // zero all non-important bits in data 242 | b &= ~(mask); // zero all important bits in existing byte 243 | b |= data; // combine data with existing byte 244 | i2c_writeReg(dev, reg, b); 245 | } 246 | 247 | //Wire Setup 248 | #define BEGIN_FLAG 0x1E 249 | #define BEGIN_STATE 0x91 250 | 251 | /* Wire */ 252 | MeWire::MeWire(uint8_t address): MePort() 253 | { 254 | _slaveAddress = address + 1; 255 | } 256 | MeWire::MeWire(MEPORT port, uint8_t address): MePort(port) 257 | { 258 | _slaveAddress = address + 1; 259 | } 260 | void MeWire::begin() 261 | { 262 | delay(1000); 263 | Wire.begin(); 264 | write(BEGIN_FLAG, 0x01); 265 | } 266 | bool MeWire::isRunning() 267 | { 268 | return read(BEGIN_STATE); 269 | } 270 | void MeWire::setI2CBaseAddress(uint8_t baseAddress) 271 | { 272 | byte w[2] = {0}; 273 | byte r[4] = {0}; 274 | w[0] = 0x21; 275 | w[1] = baseAddress; 276 | request(w, r, 2, 4); 277 | } 278 | 279 | byte MeWire::read(byte dataAddress) 280 | { 281 | byte *b = {0}; 282 | read(dataAddress, b, 1); 283 | return b[0]; 284 | } 285 | 286 | void MeWire::read(byte dataAddress, uint8_t *buf, int len) 287 | { 288 | byte rxByte; 289 | Wire.beginTransmission(_slaveAddress); // transmit to device 290 | Wire.write(dataAddress); // sends one byte 291 | Wire.endTransmission(); // stop transmitting 292 | // delayMicroseconds(1); 293 | delay(100); 294 | Wire.requestFrom(_slaveAddress, len); // request 6 bytes from slave device 295 | int index = 0; 296 | while(Wire.available()) // slave may send less than requested 297 | { 298 | rxByte = Wire.read(); // receive a byte as character 299 | buf[index] = rxByte; 300 | index++; 301 | } 302 | } 303 | 304 | void MeWire::write(byte dataAddress, byte data) 305 | { 306 | Wire.beginTransmission(_slaveAddress); // transmit to device 307 | Wire.write(dataAddress); // sends one byte 308 | // Wire.endTransmission(); // stop transmitting 309 | 310 | // Wire.beginTransmission(_slaveAddress); // transmit to device 311 | Wire.write(data); // sends one byte 312 | Wire.endTransmission(); // stop transmitting 313 | } 314 | void MeWire::request(byte *writeData, byte *readData, int wlen, int rlen) 315 | { 316 | 317 | uint8_t rxByte; 318 | uint8_t index = 0; 319 | delay(10); 320 | Wire.beginTransmission(_slaveAddress); // transmit to device 321 | 322 | Wire.write(writeData, wlen); 323 | 324 | Wire.endTransmission();//delay(10); 325 | delayMicroseconds(2); 326 | Wire.requestFrom(_slaveAddress, rlen); // request 6 bytes from slave device 327 | // delayMicroseconds(2); 328 | while(Wire.available()) // slave may send less than requested 329 | { 330 | rxByte = Wire.read(); // receive a byte as character 331 | 332 | readData[index] = rxByte; 333 | index++; 334 | } 335 | } 336 | 337 | // function: pack data into a package to send 338 | // param: buf buffer to save package 339 | // bufSize size of buf 340 | // module the associated module of package 341 | // data the data to pack 342 | // length the length(size) of data 343 | // return: 0 error 344 | // other package size 345 | uint32_t MeHost_Pack(uint8_t * buf, 346 | uint32_t bufSize, 347 | uint8_t module, 348 | uint8_t * data, 349 | uint32_t length) 350 | { 351 | uint32_t i = 0; 352 | 353 | // head: 0xA5 354 | buf[i++] = 0xA5; 355 | buf[i++] = module; 356 | // pack length 357 | buf[i++] = *((uint8_t *)&length + 0); 358 | buf[i++] = *((uint8_t *)&length + 1); 359 | buf[i++] = *((uint8_t *)&length + 2); 360 | buf[i++] = *((uint8_t *)&length + 3); 361 | // pack data 362 | for(uint32_t j = 0; j < length; ++j) 363 | { 364 | buf[i++] = data[j]; 365 | } 366 | 367 | // calculate the LRC 368 | uint8_t check = 0x00; 369 | for(uint32_t j = 0; j < length; ++j) 370 | { 371 | check ^= data[j]; 372 | } 373 | buf[i++] = check; 374 | 375 | // tail: 0x5A 376 | buf[i++] = 0x5A; 377 | 378 | if (i > bufSize) 379 | { 380 | return 0; 381 | } 382 | else 383 | { 384 | return i; 385 | } 386 | } 387 | 388 | #define BUF_SIZE 256 389 | #define MASK 255 390 | 391 | class MeHost_Parser 392 | { 393 | public: 394 | MeHost_Parser(); 395 | ~MeHost_Parser(); 396 | 397 | // push data to buffer 398 | uint8_t PushStr(uint8_t * str, uint32_t length); 399 | uint8_t PushByte(uint8_t ch); 400 | // run state machine 401 | uint8_t Run(); 402 | // get the package ready state 403 | uint8_t PackageReady(); 404 | // copy data to user's buffer 405 | uint8_t GetData(uint8_t *buf, uint32_t size); 406 | 407 | void Print(char *str, uint32_t * cnt); 408 | private: 409 | int state; 410 | uint8_t buffer[BUF_SIZE]; 411 | uint32_t in; 412 | uint32_t out; 413 | uint8_t packageReady; 414 | 415 | uint8_t module; 416 | uint32_t length; 417 | uint8_t *data; 418 | uint8_t check; 419 | 420 | uint32_t lengthRead; 421 | uint32_t currentDataPos; 422 | 423 | uint8_t GetByte(uint8_t * ch); 424 | }; 425 | 426 | 427 | #define HEAD 0xA5 428 | #define TAIL 0x5A 429 | 430 | // states 431 | #define ST_WAIT_4_START 0x01 432 | #define ST_HEAD_READ 0x02 433 | #define ST_MODULE_READ 0x03 434 | #define ST_LENGTH_READ 0x04 435 | #define ST_DATA_READ 0x05 436 | #define ST_CHECK_READ 0x06 437 | 438 | MeHost_Parser::MeHost_Parser() 439 | { 440 | state = ST_WAIT_4_START; 441 | in = 0; 442 | out = 0; 443 | packageReady = 0; 444 | 445 | module = 0; 446 | length = 0; 447 | data = NULL; 448 | check = 0; 449 | 450 | lengthRead = 0; 451 | currentDataPos = 0; 452 | } 453 | 454 | MeHost_Parser::~MeHost_Parser() 455 | { 456 | ; 457 | } 458 | 459 | uint8_t MeHost_Parser::PackageReady() 460 | { 461 | return (1 == packageReady); 462 | } 463 | 464 | uint8_t MeHost_Parser::PushStr(uint8_t * str, uint32_t length) 465 | { 466 | if (length > ((in + BUF_SIZE - out - 1) & MASK)) 467 | { 468 | return 0; 469 | } 470 | else 471 | { 472 | for (int i = 0; i < length; ++i) 473 | { 474 | PushByte(str[i]); 475 | } 476 | } 477 | } 478 | 479 | uint8_t MeHost_Parser::PushByte(uint8_t ch) 480 | { 481 | if (((in + 1) & MASK) != out) 482 | { 483 | buffer[in] = ch; 484 | ++in; 485 | in &= MASK; 486 | return 1; 487 | } 488 | else 489 | { 490 | return 0; 491 | } 492 | } 493 | 494 | uint8_t MeHost_Parser::GetByte(uint8_t * ch) 495 | { 496 | if (in != out) 497 | { 498 | *ch = buffer[out]; 499 | ++out; 500 | out &= MASK; 501 | return 1; 502 | } 503 | else 504 | { 505 | // Serial.println("GET error!"); 506 | return 0; 507 | } 508 | } 509 | 510 | uint8_t CalculateLRC(uint8_t *data, uint32_t length) 511 | { 512 | uint8_t LRC = 0; 513 | for (uint32_t i = 0; i < length; ++i) 514 | { 515 | LRC ^= data[i]; 516 | } 517 | return LRC; 518 | } 519 | 520 | uint8_t MeHost_Parser::Run(void) 521 | { 522 | uint8_t ch = 0; 523 | while (GetByte(&ch)) 524 | { 525 | switch (state) 526 | { 527 | case ST_WAIT_4_START: 528 | if (HEAD == ch) 529 | { 530 | state = ST_HEAD_READ; 531 | } 532 | break; 533 | case ST_HEAD_READ: 534 | module = ch; 535 | state = ST_MODULE_READ; 536 | break; 537 | case ST_MODULE_READ: 538 | // read 4 bytes as "length" 539 | *(((uint8_t *)&length) + lengthRead) = ch; 540 | ++lengthRead; 541 | if (4 == lengthRead) 542 | { 543 | lengthRead = 0; 544 | state = ST_LENGTH_READ; 545 | } 546 | break; 547 | case ST_LENGTH_READ: 548 | // alloc space for data 549 | if (0 == currentDataPos) 550 | { 551 | if (length > 255) 552 | { 553 | state = ST_WAIT_4_START; 554 | currentDataPos = 0; 555 | lengthRead = 0; 556 | length = 0; 557 | module = 0; 558 | check = 0; 559 | break; 560 | } 561 | data = (uint8_t *)malloc(length + 1); 562 | if (NULL == data) 563 | { 564 | state = ST_WAIT_4_START; 565 | currentDataPos = 0; 566 | lengthRead = 0; 567 | length = 0; 568 | module = 0; 569 | check = 0; 570 | break; 571 | } 572 | } 573 | // read data 574 | data[currentDataPos] = ch; 575 | ++currentDataPos; 576 | if (currentDataPos == length) 577 | { 578 | currentDataPos = 0; 579 | state = ST_DATA_READ; 580 | } 581 | break; 582 | case ST_DATA_READ: 583 | check = ch; 584 | if (check != CalculateLRC(data, length)) 585 | { 586 | state = ST_WAIT_4_START; 587 | if (NULL != data) 588 | { 589 | free(data); 590 | data = NULL; 591 | } 592 | currentDataPos = 0; 593 | lengthRead = 0; 594 | length = 0; 595 | module = 0; 596 | check = 0; 597 | } 598 | else 599 | { 600 | state = ST_CHECK_READ; 601 | } 602 | break; 603 | case ST_CHECK_READ: 604 | if (TAIL != ch) 605 | { 606 | if (NULL != data) 607 | { 608 | free(data); 609 | data = NULL; 610 | } 611 | length = 0; 612 | } 613 | else 614 | { 615 | packageReady = 1; 616 | } 617 | state = ST_WAIT_4_START; 618 | currentDataPos = 0; 619 | lengthRead = 0; 620 | module = 0; 621 | check = 0; 622 | break; 623 | default: 624 | break; 625 | } 626 | } 627 | return state; 628 | } 629 | 630 | 631 | 632 | uint8_t MeHost_Parser::GetData(uint8_t *buf, uint32_t size) 633 | { 634 | int copySize = (size > length) ? length : size; 635 | if ((NULL != data) && (NULL != buf)) 636 | { 637 | memcpy(buf, data, copySize); 638 | free(data); 639 | data = NULL; 640 | length = 0; 641 | packageReady = 0; 642 | 643 | return copySize; 644 | } 645 | else 646 | { 647 | return 0; 648 | } 649 | } 650 | 651 | // frame type 652 | #define ENCODER_MOTOR_GET_PARAM 0x01 653 | #define ENCODER_MOTOR_SAVE_PARAM 0x02 654 | #define ENCODER_MOTOR_TEST_PARAM 0x03 655 | #define ENCODER_MOTOR_SHOW_PARAM 0x04 656 | #define ENCODER_MOTOR_RUN_STOP 0x05 657 | #define ENCODER_MOTOR_GET_DIFF_POS 0x06 658 | #define ENCODER_MOTOR_RESET 0x07 659 | #define ENCODER_MOTOR_SPEED_TIME 0x08 660 | #define ENCODER_MOTOR_GET_SPEED 0x09 661 | #define ENCODER_MOTOR_GET_POS 0x10 662 | #define ENCODER_MOTOR_MOVE 0x11 663 | #define ENCODER_MOTOR_MOVE_TO 0x12 664 | #define ENCODER_MOTOR_DEBUG_STR 0xCC 665 | #define ENCODER_MOTOR_ACKNOWLEDGE 0xFF 666 | 667 | MeHost_Parser encoderParser = MeHost_Parser(); 668 | 669 | /* EncoderMotor */ 670 | MeEncoderMotor::MeEncoderMotor(uint8_t addr,uint8_t slot):MeWire(addr - 1) 671 | { 672 | _slot = slot - 1; 673 | } 674 | 675 | void MeEncoderMotor::begin() 676 | { 677 | MeWire::begin(); 678 | Reset(); 679 | } 680 | 681 | boolean MeEncoderMotor::Reset() 682 | { 683 | uint8_t w[10] = {0}; 684 | uint8_t r[10] = {0}; 685 | 686 | uint8_t data[2] = {0}; 687 | data[0] = _slot; 688 | data[1] = ENCODER_MOTOR_RESET; 689 | 690 | MeHost_Pack(w, 10, 0x01, data, 2); 691 | request(w, r, 10, 10); 692 | encoderParser.PushStr(r, 10); 693 | 694 | uint8_t ack[2] = {0}; 695 | encoderParser.GetData(ack, 2); 696 | return ack[1]; 697 | } 698 | 699 | boolean MeEncoderMotor::MoveTo(float angle, float speed) 700 | { 701 | uint8_t w[18] = {0}; 702 | uint8_t r[10] = {0}; 703 | 704 | uint8_t data[10] = {0}; 705 | data[0] = _slot; 706 | data[1] = ENCODER_MOTOR_MOVE_TO; 707 | *((float *)(data + 2)) = angle; 708 | *((float *)(data + 6)) = speed; 709 | 710 | MeHost_Pack(w, 18, 0x01, data, 10); 711 | request(w, r, 18, 10); 712 | encoderParser.PushStr(r, 10); 713 | encoderParser.Run(); 714 | 715 | uint8_t ack[2] = {0}; 716 | encoderParser.GetData(ack, 2); 717 | return ack[1]; 718 | } 719 | 720 | boolean MeEncoderMotor::Move(float angle, float speed) 721 | { 722 | uint8_t w[18] = {0}; 723 | uint8_t r[10] = {0}; 724 | 725 | uint8_t data[10] = {0}; 726 | data[0] = _slot; 727 | data[1] = ENCODER_MOTOR_MOVE; 728 | *((float *)(data + 2)) = angle; 729 | *((float *)(data + 6)) = speed; 730 | 731 | MeHost_Pack(w, 18, 0x01, data, 10); 732 | request(w, r, 18, 10); 733 | encoderParser.PushStr(r, 10); 734 | encoderParser.Run(); 735 | 736 | uint8_t ack[2] = {0}; 737 | encoderParser.GetData(ack, 2); 738 | return ack[1]; 739 | } 740 | 741 | boolean MeEncoderMotor::RunTurns(float turns, float speed) 742 | { 743 | return Move(turns * 360, speed); 744 | } 745 | 746 | boolean MeEncoderMotor::RunSpeed(float speed) 747 | { 748 | uint8_t w[14] = {0}; 749 | uint8_t r[10] = {0}; 750 | 751 | uint8_t data[6] = {0}; 752 | data[0] = _slot; 753 | data[1] = ENCODER_MOTOR_RUN_STOP; 754 | *((float *)(data + 2)) = speed; 755 | 756 | MeHost_Pack(w, 14, 0x01, data, 6); 757 | request(w, r, 14, 10); 758 | encoderParser.PushStr(r, 10); 759 | encoderParser.Run(); 760 | 761 | // uint8_t ack[2] = {0}; 762 | // encoderParser.GetData(ack, 2); 763 | // return ack[1]; 764 | return 0; 765 | } 766 | 767 | boolean MeEncoderMotor::RunSpeedAndTime(float speed, float time) 768 | { 769 | uint8_t w[18] = {0}; 770 | uint8_t r[10] = {0}; 771 | 772 | uint8_t data[10] = {0}; 773 | data[0] = _slot; 774 | data[1] = ENCODER_MOTOR_SPEED_TIME; 775 | *((float *)(data + 2)) = speed; 776 | *((float *)(data + 6)) = time; 777 | 778 | MeHost_Pack(w, 18, 0x01, data, 10); 779 | request(w, r, 18, 10); 780 | encoderParser.PushStr(r, 10); 781 | encoderParser.Run(); 782 | 783 | // uint8_t ack[2] = {0}; 784 | // encoderParser.GetData(ack, 2); 785 | // return ack[1]; 786 | return 0; 787 | } 788 | 789 | float MeEncoderMotor::GetCurrentSpeed() 790 | { 791 | uint8_t w[10] = {0}; 792 | uint8_t r[14] = {0}; 793 | 794 | uint8_t data[2] = {0}; 795 | data[0] = _slot; 796 | data[1] = ENCODER_MOTOR_GET_SPEED; 797 | 798 | MeHost_Pack(w, 10, 0x01, data, 2); 799 | request(w, r, 10, 14); 800 | encoderParser.PushStr(r, 14); 801 | encoderParser.Run(); 802 | 803 | uint8_t temp[6] = {0}; 804 | encoderParser.GetData(temp, 6); 805 | float speed = *((float *)(temp + 2)); 806 | return speed; 807 | } 808 | 809 | float MeEncoderMotor::GetCurrentPosition() 810 | { 811 | uint8_t w[10] = {0}; 812 | uint8_t r[14] = {0}; 813 | 814 | uint8_t data[2] = {0}; 815 | data[0] = _slot; 816 | data[1] = ENCODER_MOTOR_GET_POS; 817 | 818 | MeHost_Pack(w, 10, 0x01, data, 2); 819 | request(w, r, 10, 14); 820 | encoderParser.PushStr(r, 14); 821 | 822 | encoderParser.Run(); 823 | 824 | uint8_t temp[6] = {0}; 825 | uint8_t size = encoderParser.GetData(temp, 6); 826 | float pos = *((float *)(temp + 2)); 827 | return pos; 828 | } 829 | -------------------------------------------------------------------------------- /mBot-default-program/MePort.h: -------------------------------------------------------------------------------- 1 | #ifndef MEPORT_H_ 2 | #define MEPORT_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "wiring_private.h" 8 | #include "pins_arduino.h" 9 | #ifndef F_CPU 10 | #define F_CPU 16000000UL 11 | #endif 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | typedef enum 19 | { 20 | MeBaseBoard, 21 | MakeblockOrion, 22 | mCore, 23 | UNOShield 24 | }Board_type; 25 | 26 | extern Board_type MakeblockBoard; 27 | typedef struct 28 | { 29 | uint8_t s1; 30 | uint8_t s2; 31 | } MePort_Sig; 32 | extern MePort_Sig mePort[11];//mePort[0] is nonsense 33 | 34 | #define NC -1 35 | 36 | // MePort_Sig mePort[11]={{NC, NC}, {11, 12}, {9, 10}, {A2, A3}, {A0, A1}, 37 | // {NC, NC}, {NC, NC}, {NC, NC}, {NC, NC}, {6, 7}, {5, 4}}; 38 | 39 | // #define PORT_1 0x01 40 | // #define PORT_2 0x02 41 | // #define PORT_3 0x03 42 | // #define PORT_4 0x04 43 | // #define PORT_5 0x05 44 | // #define PORT_6 0x06 45 | // #define PORT_7 0x07 46 | // #define PORT_8 0x08 47 | // #define M1 0x09 48 | // #define M2 0x0a 49 | 50 | typedef enum 51 | { 52 | PORT_0, 53 | PORT_1, 54 | PORT_2, 55 | PORT_3, 56 | PORT_4, 57 | PORT_5, 58 | PORT_6, 59 | PORT_7, 60 | PORT_8, 61 | M1, 62 | M2, 63 | }MEPORT; 64 | 65 | // #if defined(__AVR_ATmega32U4__) 66 | // // buzzer 67 | // #define buzzerOn() DDRE |= 0x04,PORTE |= B00000100 68 | // #define buzzerOff() DDRE |= 0x04,PORTE &= B11111011 69 | // #else 70 | // #define buzzerOn() DDRC |= 0x20,PORTC |= B00100000; 71 | // #define buzzerOff() DDRC |= 0x20,PORTC &= B11011111; 72 | // #endif 73 | #define SLOT1 1 74 | #define SLOT2 2 75 | #define SLOT_1 SLOT1 76 | #define SLOT_2 SLOT2 77 | 78 | #define FALSE 0 79 | #define TRUE 1 80 | 81 | ///@brief class of MePort,it contains two pin. 82 | class MePort 83 | { 84 | public: 85 | MePort(); 86 | ///@brief initialize the Port 87 | ///@param port port number of device 88 | MePort(uint8_t port); 89 | MePort(uint8_t port,uint8_t slot); 90 | ///@return the level of pin 1 of port 91 | ///@retval true on HIGH. 92 | ///@retval false on LOW. 93 | uint8_t getPort(); 94 | uint8_t getSlot(); 95 | ///@return the level of pin 1 of port 96 | ///@retval true on HIGH. 97 | ///@retval false on LOW. 98 | bool dRead1(); 99 | ///@return the level of pin 2 of port 100 | ///@retval true on HIGH. 101 | ///@retval false on LOW. 102 | bool dRead2(); 103 | ///@brief set the analog value of pin 1 of port 104 | ///@param value is HIGH or LOW 105 | void dWrite1(bool value); 106 | ///@brief set the level of pin 1 of port 107 | ///@param value is HIGH or LOW 108 | void dWrite2(bool value); 109 | ///@return the analog signal of pin 1 of port between 0 to 1023 110 | int aRead1(); 111 | ///@return the analog signal of pin 2 of port between 0 to 1023 112 | int aRead2(); 113 | ///@brief set the PWM outpu value of pin 1 of port 114 | ///@param value between 0 to 255 115 | void aWrite1(int value); 116 | ///@brief set the PWM outpu value of pin 2 of port 117 | ///@param value between 0 to 255 118 | void aWrite2(int value); 119 | void reset(uint8_t port); 120 | void reset(uint8_t port,uint8_t slot); 121 | uint8_t pin1(); 122 | uint8_t pin2(); 123 | uint8_t pin(); 124 | uint8_t pin(uint8_t port,uint8_t slot); 125 | protected: 126 | uint8_t s1; 127 | uint8_t s2; 128 | uint8_t _port; 129 | uint8_t _slot; 130 | }; 131 | 132 | 133 | //TWI 134 | void i2c_init(void); 135 | void waitTransmissionI2C(); 136 | void i2c_rep_start(uint8_t address); 137 | void i2c_stop(void); 138 | void i2c_write(uint8_t data ); 139 | uint8_t i2c_read(uint8_t ack); 140 | uint8_t i2c_readAck(); 141 | uint8_t i2c_readNak(void); 142 | size_t i2c_read_to_buf(uint8_t add, void *buf, size_t size); 143 | size_t i2c_read_reg_to_buf(uint8_t add, uint8_t reg, void *buf, size_t size); 144 | void i2c_writeReg(uint8_t add, uint8_t reg, uint8_t val); 145 | uint8_t i2c_readReg(uint8_t add, uint8_t reg); 146 | int8_t i2c_readBit(uint8_t add, uint8_t reg, uint8_t bitNum); 147 | int8_t i2c_readBits(uint8_t dev, uint8_t reg, uint8_t bitStart, uint8_t length); 148 | void i2c_writeBits(uint8_t dev, uint8_t reg, uint8_t bitStart, uint8_t length,uint8_t data); 149 | 150 | ///@brief class of MeWire 151 | class MeWire: public MePort 152 | { 153 | public: 154 | MeWire(uint8_t address); 155 | ///@brief initialize 156 | ///@param port port number of device 157 | MeWire(MEPORT port, uint8_t address); 158 | ///@brief reset start index of i2c slave address. 159 | void setI2CBaseAddress(uint8_t baseAddress); 160 | bool isRunning(); 161 | ///@brief Initiate the Wire library and join the I2C bus as a master or slave. This should normally be called only once. 162 | ///@param address the 7-bit slave address (optional); if not specified, join the bus as a master. 163 | void begin(); 164 | ///@brief send one byte data request for read one byte from slave address. 165 | byte read(byte dataAddress); 166 | void read(byte dataAddress, uint8_t *buf, int len); 167 | ///@brief send one byte data request for write one byte to slave address. 168 | void write(byte dataAddress, byte data); 169 | void request(byte *writeData, byte *readData, int wlen, int rlen); 170 | protected: 171 | int _slaveAddress; 172 | }; 173 | 174 | ///@brief Class for Encoder Motor Driver 175 | class MeEncoderMotor: public MeWire{ 176 | public: 177 | MeEncoderMotor(uint8_t addr,uint8_t slot); 178 | void begin(); 179 | boolean Reset(); 180 | boolean Move(float angle, float speed); 181 | boolean MoveTo(float angle, float speed); 182 | boolean RunTurns(float turns, float speed); 183 | boolean RunSpeed(float speed); 184 | boolean RunSpeedAndTime(float speed, float time); 185 | float GetCurrentSpeed(); 186 | float GetCurrentPosition(); 187 | private: 188 | uint8_t _slot; 189 | }; 190 | #endif 191 | -------------------------------------------------------------------------------- /mBot-default-program/MeRGBLed.cpp: -------------------------------------------------------------------------------- 1 | #include "MeRGBLed.h" 2 | MeRGBLed::MeRGBLed() 3 | { 4 | pinMask = digitalPinToBitMask(13); 5 | ws2812_port = portOutputRegister(digitalPinToPort(13)); 6 | pinMode(13, OUTPUT); 7 | setNumber(4); 8 | } 9 | 10 | MeRGBLed::MeRGBLed(uint8_t pin) 11 | { 12 | s2 = pin; 13 | pinMask = digitalPinToBitMask(pin); 14 | ws2812_port = portOutputRegister(digitalPinToPort(pin)); 15 | pinMode(pin, OUTPUT); 16 | setNumber(4); 17 | } 18 | 19 | MeRGBLed::MeRGBLed(MEPORT port): MePort(port) 20 | { 21 | pinMask = digitalPinToBitMask(s2); 22 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 23 | pinMode(s2, OUTPUT); 24 | setNumber(4); 25 | } 26 | MeRGBLed::MeRGBLed(MEPORT port, uint8_t slot): MePort(port) 27 | { 28 | if(slot == SLOT2) 29 | { 30 | pinMask = digitalPinToBitMask(s2); 31 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 32 | pinMode(s2, OUTPUT); 33 | } 34 | else 35 | { 36 | pinMask = digitalPinToBitMask(s1); 37 | ws2812_port = portOutputRegister(digitalPinToPort(s1)); 38 | pinMode(s1, OUTPUT); 39 | } 40 | setNumber(4); 41 | } 42 | void MeRGBLed::reset(int pin){ 43 | pinMask = digitalPinToBitMask(pin); 44 | ws2812_port = portOutputRegister(digitalPinToPort(pin)); 45 | pinMode(pin, OUTPUT); 46 | } 47 | void MeRGBLed::reset(MEPORT port) 48 | { 49 | s2 = mePort[port].s2; 50 | s1 = mePort[port].s1; 51 | pinMask = digitalPinToBitMask(s2); 52 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 53 | pinMode(s2, OUTPUT); 54 | } 55 | 56 | void MeRGBLed::reset(MEPORT port, uint8_t slot) 57 | { 58 | s2 = mePort[port].s2; 59 | s1 = mePort[port].s1; 60 | if(slot == SLOT2) 61 | { 62 | pinMask = digitalPinToBitMask(s2); 63 | ws2812_port = portOutputRegister(digitalPinToPort(s2)); 64 | pinMode(s2, OUTPUT); 65 | } 66 | else 67 | { 68 | pinMask = digitalPinToBitMask(s1); 69 | ws2812_port = portOutputRegister(digitalPinToPort(s1)); 70 | pinMode(s1, OUTPUT); 71 | } 72 | setNumber(4); 73 | } 74 | 75 | void MeRGBLed::setNumber(uint8_t num_leds) 76 | { 77 | count_led = num_leds; 78 | pixels = (uint8_t *)malloc(count_led * 3); 79 | clear(); 80 | } 81 | cRGB MeRGBLed::getColorAt(uint8_t index) 82 | { 83 | 84 | cRGB px_value; 85 | 86 | if(index < count_led) 87 | { 88 | 89 | uint8_t tmp; 90 | tmp = index * 3; 91 | 92 | px_value.g = pixels[tmp]; 93 | px_value.r = pixels[tmp+1]; 94 | px_value.b = pixels[tmp+2]; 95 | } 96 | 97 | return px_value; 98 | } 99 | 100 | uint8_t MeRGBLed::getNumber() 101 | { 102 | return count_led; 103 | } 104 | bool MeRGBLed::setColorAt(uint8_t index, uint8_t red, uint8_t green, uint8_t blue) 105 | { 106 | if(index < count_led) 107 | { 108 | uint8_t tmp = index * 3; 109 | pixels[tmp] = green; 110 | pixels[tmp+1] = red; 111 | pixels[tmp+2] = blue; 112 | 113 | return true; 114 | } 115 | return false; 116 | } 117 | bool MeRGBLed::setColorAt(uint8_t index, long value) 118 | { 119 | if(index < count_led) 120 | { 121 | uint8_t tmp = index * 3; 122 | uint8_t red = (value & 0xff0000) >> 16; 123 | uint8_t green = (value & 0xff00) >> 8; 124 | uint8_t blue = value & 0xff; 125 | pixels[tmp] = green; 126 | pixels[tmp+1] = red; 127 | pixels[tmp+2] = blue; 128 | return true; 129 | } 130 | return false; 131 | } 132 | 133 | void MeRGBLed::setColor(uint8_t index,uint8_t red, uint8_t green, uint8_t blue){ 134 | if(index==0){ 135 | setColor(red,green,blue); 136 | }else{ 137 | setColorAt(index-1,red,green,blue); 138 | show(); 139 | } 140 | } 141 | void MeRGBLed::setColor(uint8_t red, uint8_t green, uint8_t blue) 142 | { 143 | for (int i = 0; i < count_led; ++i) 144 | { 145 | uint8_t tmp = i * 3; 146 | pixels[tmp] = green; 147 | pixels[tmp+1] = red; 148 | pixels[tmp+2] = blue; 149 | } 150 | show(); 151 | } 152 | 153 | void MeRGBLed::setColor(long value) 154 | { 155 | for (int i = 0; i < count_led; ++i) 156 | { 157 | uint8_t tmp = i * 3; 158 | uint8_t red = (value & 0xff0000) >> 16; 159 | uint8_t green = (value & 0xff00) >> 8; 160 | uint8_t blue = value & 0xff; 161 | pixels[tmp] = green; 162 | pixels[tmp+1] = red; 163 | pixels[tmp+2] = blue; 164 | } 165 | show(); 166 | } 167 | 168 | void MeRGBLed::clear() 169 | { 170 | // for(int i = 0; i < count_led; i++) 171 | // { 172 | // setColorAt(i, 0, 0, 0); 173 | // } 174 | memset(pixels,0,3*count_led); 175 | show(); 176 | } 177 | /* 178 | This routine writes an array of bytes with RGB values to the Dataout pin 179 | using the fast 800kHz clockless WS2811/2812 protocol. 180 | */ 181 | 182 | // Timing in ns 183 | #define w_zeropulse 350 184 | #define w_onepulse 900 185 | #define w_totalperiod 1250 186 | 187 | // Fixed cycles used by the inner loop 188 | #define w_fixedlow 3 189 | #define w_fixedhigh 6 190 | #define w_fixedtotal 10 191 | 192 | // Insert NOPs to match the timing, if possible 193 | #define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000) 194 | #define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000) 195 | #define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000) 196 | 197 | // w1 - nops between rising edge and falling edge - low 198 | #define w1 (w_zerocycles-w_fixedlow) 199 | // w2 nops between fe low and fe high 200 | #define w2 (w_onecycles-w_fixedhigh-w1) 201 | // w3 nops to complete loop 202 | #define w3 (w_totalcycles-w_fixedtotal-w1-w2) 203 | 204 | #if w1>0 205 | #define w1_nops w1 206 | #else 207 | #define w1_nops 0 208 | #endif 209 | 210 | // The only critical timing parameter is the minimum pulse length of the "0" 211 | // Warn or throw error if this timing can not be met with current F_CPU settings. 212 | #define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000) 213 | #if w_lowtime>550 214 | #error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?" 215 | #elif w_lowtime>450 216 | #warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)." 217 | #warning "Please consider a higher clockspeed, if possible" 218 | #endif 219 | 220 | #if w2>0 221 | #define w2_nops w2 222 | #else 223 | #define w2_nops 0 224 | #endif 225 | 226 | #if w3>0 227 | #define w3_nops w3 228 | #else 229 | #define w3_nops 0 230 | #endif 231 | 232 | #define w_nop1 "nop \n\t" 233 | #define w_nop2 "rjmp .+0 \n\t" 234 | #define w_nop4 w_nop2 w_nop2 235 | #define w_nop8 w_nop4 w_nop4 236 | #define w_nop16 w_nop8 w_nop8 237 | 238 | void MeRGBLed::rgbled_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t maskhi, uint8_t *port) 239 | { 240 | uint8_t curbyte, ctr, masklo; 241 | uint8_t oldSREG = SREG; 242 | cli(); //Disables all interrupts 243 | 244 | masklo = *port & ~maskhi; 245 | maskhi = *port | maskhi; 246 | 247 | while (datlen--) 248 | { 249 | curbyte = *data++; 250 | 251 | asm volatile( 252 | " ldi %0,8 \n\t" 253 | "loop%=: \n\t" 254 | " st X,%3 \n\t" // '1' [02] '0' [02] - re 255 | #if (w1_nops&1) 256 | w_nop1 257 | #endif 258 | #if (w1_nops&2) 259 | w_nop2 260 | #endif 261 | #if (w1_nops&4) 262 | w_nop4 263 | #endif 264 | #if (w1_nops&8) 265 | w_nop8 266 | #endif 267 | #if (w1_nops&16) 268 | w_nop16 269 | #endif 270 | " sbrs %1,7 \n\t" // '1' [04] '0' [03] 271 | " st X,%4 \n\t" // '1' [--] '0' [05] - fe-low 272 | " lsl %1 \n\t" // '1' [05] '0' [06] 273 | #if (w2_nops&1) 274 | w_nop1 275 | #endif 276 | #if (w2_nops&2) 277 | w_nop2 278 | #endif 279 | #if (w2_nops&4) 280 | w_nop4 281 | #endif 282 | #if (w2_nops&8) 283 | w_nop8 284 | #endif 285 | #if (w2_nops&16) 286 | w_nop16 287 | #endif 288 | " brcc skipone%= \n\t" // '1' [+1] '0' [+2] - 289 | " st X,%4 \n\t" // '1' [+3] '0' [--] - fe-high 290 | "skipone%=: " // '1' [+3] '0' [+2] - 291 | 292 | #if (w3_nops&1) 293 | w_nop1 294 | #endif 295 | #if (w3_nops&2) 296 | w_nop2 297 | #endif 298 | #if (w3_nops&4) 299 | w_nop4 300 | #endif 301 | #if (w3_nops&8) 302 | w_nop8 303 | #endif 304 | #if (w3_nops&16) 305 | w_nop16 306 | #endif 307 | 308 | " dec %0 \n\t" // '1' [+4] '0' [+3] 309 | " brne loop%=\n\t" // '1' [+5] '0' [+4] 310 | : "=&d" (ctr) 311 | // : "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo) 312 | : "r" (curbyte), "x" (port), "r" (maskhi), "r" (masklo) 313 | ); 314 | } 315 | 316 | SREG = oldSREG; 317 | } 318 | void MeRGBLed::show() 319 | { 320 | // *ws2812_port_reg |= pinMask; // Enable DDR 321 | rgbled_sendarray_mask(pixels, 3 * count_led, pinMask, (uint8_t *) ws2812_port); 322 | } 323 | 324 | MeRGBLed::~MeRGBLed() 325 | { 326 | 327 | 328 | } 329 | -------------------------------------------------------------------------------- /mBot-default-program/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-default-program/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-default-program/MeTemperature.h: -------------------------------------------------------------------------------- 1 | #ifndef MeTemperature_h 2 | #define MeTemperature_h 3 | #include "MePort.h" 4 | #include "Me1Wire.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 | Me1Wire _ts; 18 | }; 19 | #endif 20 | -------------------------------------------------------------------------------- /mBot-default-program/MeUltrasonic.cpp: -------------------------------------------------------------------------------- 1 | #include "MeUltrasonic.h" 2 | /* UltrasonicSenser */ 3 | // MeUltrasonic::MeUltrasonic(): MePort(0) 4 | // { 5 | // } 6 | MeUltrasonic::MeUltrasonic(MEPORT port): MePort(port) 7 | { 8 | 9 | } 10 | 11 | double MeUltrasonic::distanceCm(uint16_t maxCm) 12 | { 13 | long distance = measure(maxCm * 55 + 200); 14 | return (double)distance / 58.0; 15 | } 16 | 17 | double MeUltrasonic::distanceInch(uint16_t maxInch) 18 | { 19 | long distance = measure(maxInch * 145 + 200); 20 | return (double)(distance / 148.0); 21 | } 22 | 23 | double MeUltrasonic::distanceCm(){ 24 | return distanceCm(400); 25 | } 26 | double MeUltrasonic::distanceInch(){ 27 | return distanceInch(5); 28 | } 29 | long MeUltrasonic::measure(unsigned long timeout) 30 | { 31 | long duration; 32 | // MePort::dWrite2(LOW); 33 | // delayMicroseconds(2); 34 | // MePort::dWrite2(HIGH); 35 | // delayMicroseconds(10); 36 | // MePort::dWrite2(LOW); 37 | // pinMode(s2, INPUT); 38 | // duration = pulseIn(s2, HIGH, timeout); 39 | digitalWrite(s2,LOW); 40 | delayMicroseconds(2); 41 | digitalWrite(s2,HIGH); 42 | delayMicroseconds(10); 43 | digitalWrite(s2,LOW); 44 | pinMode(s2,INPUT); 45 | duration = pulseIn(s2,HIGH,timeout); 46 | return duration; 47 | } 48 | -------------------------------------------------------------------------------- /mBot-default-program/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(MEPORT 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 | private: 17 | uint8_t _pin; 18 | }; 19 | #endif 20 | -------------------------------------------------------------------------------- /mBot-default-program/mBot-default-program.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "mCore.h" 5 | MeRGBLed rgb; 6 | MeUltrasonic ultr(PORT_3); 7 | MeLineFollower line(PORT_2); 8 | MeLEDMatrix ledMx; 9 | MeIR ir; 10 | MeBuzzer buzzer; 11 | MeTemperature ts; 12 | Me7SegmentDisplay seg; 13 | 14 | MeDCMotor MotorL(M1); 15 | MeDCMotor MotorR(M2); 16 | MePort generalDevice; 17 | Servo servo; 18 | 19 | int moveSpeed = 200; 20 | int minSpeed = 48; 21 | int factor = 23; 22 | 23 | #define NTD1 294 24 | #define NTD2 330 25 | #define NTD3 350 26 | #define NTD4 393 27 | #define NTD5 441 28 | #define NTD6 495 29 | #define NTD7 556 30 | #define NTDL1 147 31 | #define NTDL2 165 32 | #define NTDL3 175 33 | #define NTDL4 196 34 | #define NTDL5 221 35 | #define NTDL6 248 36 | #define NTDL7 278 37 | #define NTDH1 589 38 | #define NTDH2 661 39 | #define NTDH3 700 40 | #define NTDH4 786 41 | #define NTDH5 882 42 | #define NTDH6 990 43 | #define NTDH7 112 44 | 45 | 46 | #define RUN_F 0x01 47 | #define RUN_B 0x01<<1 48 | #define RUN_L 0x01<<2 49 | #define RUN_R 0x01<<3 50 | #define STOP 0 51 | uint8_t motor_sta = STOP; 52 | enum 53 | { 54 | MODE_A, 55 | MODE_B, 56 | MODE_C 57 | }; 58 | 59 | typedef struct MeModule 60 | { 61 | int device; 62 | int port; 63 | int slot; 64 | int pin; 65 | int index; 66 | float values[3]; 67 | } MeModule; 68 | 69 | union{ 70 | byte byteVal[4]; 71 | float floatVal; 72 | long longVal; 73 | }val; 74 | 75 | union{ 76 | byte byteVal[8]; 77 | double doubleVal; 78 | }valDouble; 79 | 80 | union{ 81 | byte byteVal[2]; 82 | short shortVal; 83 | }valShort; 84 | 85 | MeModule modules[12]; 86 | int analogs[8]={A0,A1,A2,A3,A4,A5,A6,A7}; 87 | uint8_t mode = MODE_A; 88 | 89 | boolean isAvailable = false; 90 | int len = 52; 91 | char buffer[52]; 92 | char bufferBt[52]; 93 | byte index = 0; 94 | byte dataLen; 95 | byte modulesLen=0; 96 | boolean isStart = false; 97 | char serialRead; 98 | String mVersion = "1.2.103"; 99 | float angleServo = 90.0; 100 | unsigned char prevc=0; 101 | boolean buttonPressed = false; 102 | double lastTime = 0.0; 103 | double currentTime = 0.0; 104 | int LineFollowFlag=0; 105 | 106 | #define VERSION 0 107 | #define ULTRASONIC_SENSOR 1 108 | #define TEMPERATURE_SENSOR 2 109 | #define LIGHT_SENSOR 3 110 | #define POTENTIONMETER 4 111 | #define JOYSTICK 5 112 | #define GYRO 6 113 | #define SOUND_SENSOR 7 114 | #define RGBLED 8 115 | #define SEVSEG 9 116 | #define MOTOR 10 117 | #define SERVO 11 118 | #define ENCODER 12 119 | #define IR 13 120 | #define IRREMOTE 14 121 | #define PIRMOTION 15 122 | #define INFRARED 16 123 | #define LINEFOLLOWER 17 124 | #define IRREMOTECODE 18 125 | #define SHUTTER 20 126 | #define LIMITSWITCH 21 127 | #define BUTTON 22 128 | #define DIGITAL 30 129 | #define ANALOG 31 130 | #define PWM 32 131 | #define SERVO_PIN 33 132 | #define TONE 34 133 | #define BUTTON_INNER 35 134 | #define LEDMATRIX 41 135 | #define TIMER 50 136 | 137 | #define GET 1 138 | #define RUN 2 139 | #define RESET 4 140 | #define START 5 141 | 142 | 143 | void setup() 144 | { 145 | Stop(); 146 | rgb.setNumber(16); 147 | rgb.clear(); 148 | rgb.setColor(10, 0, 0); 149 | buzzer.tone(NTD1, 300); 150 | delay(300); 151 | rgb.setColor(0, 10, 0); 152 | buzzer.tone(NTD2, 300); 153 | delay(300); 154 | rgb.setColor(0, 0, 10); 155 | buzzer.tone(NTD3, 300); 156 | delay(300); 157 | rgb.clear(); 158 | Serial.begin(115200); 159 | buzzer.noTone(); 160 | ir.begin(); 161 | } 162 | unsigned char readBuffer(int index){ 163 | return buffer[index]; 164 | } 165 | void writeBuffer(int index,unsigned char c){ 166 | buffer[index]=c; 167 | } 168 | void writeHead(){ 169 | writeSerial(0xff); 170 | writeSerial(0x55); 171 | } 172 | void writeEnd(){ 173 | Serial.println(); 174 | } 175 | void writeSerial(unsigned char c){ 176 | Serial.write(c); 177 | } 178 | void readSerial(){ 179 | isAvailable = false; 180 | if(Serial.available()>0){ 181 | isAvailable = true; 182 | serialRead = Serial.read(); 183 | } 184 | } 185 | void serialHandle(){ 186 | readSerial(); 187 | if(isAvailable){ 188 | unsigned char c = serialRead&0xff; 189 | if(c==0x55&&isStart==false){ 190 | if(prevc==0xff){ 191 | index=1; 192 | isStart = true; 193 | } 194 | }else{ 195 | prevc = c; 196 | if(isStart){ 197 | if(index==2){ 198 | dataLen = c; 199 | }else if(index>2){ 200 | dataLen--; 201 | } 202 | writeBuffer(index,c); 203 | } 204 | } 205 | index++; 206 | if(index>51){ 207 | index=0; 208 | isStart=false; 209 | } 210 | if(isStart&&dataLen==0&&index>3){ 211 | isStart = false; 212 | parseData(); 213 | index=0; 214 | } 215 | } 216 | } 217 | int px = 0; 218 | void loop() 219 | { 220 | while(1) 221 | { 222 | get_ir_command(); 223 | serialHandle(); 224 | switch (mode) 225 | { 226 | case MODE_A: 227 | modeA(); 228 | break; 229 | case MODE_B: 230 | modeB(); 231 | break; 232 | case MODE_C: 233 | modeC(); 234 | break; 235 | } 236 | } 237 | } 238 | 239 | void get_ir_command() 240 | { 241 | static long time = millis(); 242 | if (ir.decode()) 243 | { 244 | uint32_t value = ir.value; 245 | time = millis(); 246 | switch (value >> 16 & 0xff) 247 | { 248 | case IR_BUTTON_A: 249 | moveSpeed = 220; 250 | mode = MODE_A; 251 | Stop(); 252 | buzzer.tone(NTD1, 300); 253 | rgb.clear(); 254 | rgb.setColor(10, 10, 10); 255 | break; 256 | case IR_BUTTON_B: 257 | moveSpeed = 200; 258 | mode = MODE_B; 259 | Stop(); 260 | buzzer.tone(NTD2, 300); 261 | rgb.clear(); 262 | rgb.setColor(0, 10, 0); 263 | break; 264 | case IR_BUTTON_C: 265 | mode = MODE_C; 266 | moveSpeed = 120; 267 | Stop(); 268 | buzzer.tone(NTD3, 300); 269 | rgb.clear(); 270 | rgb.setColor(0, 0, 10); 271 | break; 272 | case IR_BUTTON_PLUS: 273 | motor_sta = RUN_F; 274 | //buzzer.tone(NTD4, 300); 275 | rgb.clear(); 276 | rgb.setColor(10, 10, 0); 277 | // Forward(); 278 | break; 279 | case IR_BUTTON_MINUS: 280 | motor_sta = RUN_B; 281 | rgb.clear(); 282 | rgb.setColor(10, 0, 0); 283 | //buzzer.tone(NTD4, 300); 284 | // Backward(); 285 | break; 286 | case IR_BUTTON_NEXT: 287 | motor_sta = RUN_R; 288 | //buzzer.tone(NTD4, 300); 289 | rgb.clear(); 290 | rgb.setColor(1,10, 10, 0); 291 | // TurnRight(); 292 | break; 293 | case IR_BUTTON_PREVIOUS: 294 | motor_sta = RUN_L; 295 | //buzzer.tone(NTD4, 300); 296 | rgb.clear(); 297 | rgb.setColor(2,10, 10, 0); 298 | // TurnLeft(); 299 | break; 300 | case IR_BUTTON_9: 301 | buzzer.tone(NTDH2, 300); 302 | delay(300); 303 | ChangeSpeed(factor * 9 + minSpeed); 304 | break; 305 | case IR_BUTTON_8: 306 | buzzer.tone(NTDH1, 300); 307 | delay(300); 308 | ChangeSpeed(factor * 8 + minSpeed); 309 | break; 310 | case IR_BUTTON_7: 311 | buzzer.tone(NTD7, 300); 312 | delay(300); 313 | ChangeSpeed(factor * 7 + minSpeed); 314 | break; 315 | case IR_BUTTON_6: 316 | buzzer.tone(NTD6, 300); 317 | delay(300); 318 | ChangeSpeed(factor * 6 + minSpeed); 319 | break; 320 | case IR_BUTTON_5: 321 | buzzer.tone(NTD5, 300); 322 | delay(300); 323 | ChangeSpeed(factor * 5 + minSpeed); 324 | break; 325 | case IR_BUTTON_4: 326 | buzzer.tone(NTD4, 300); 327 | delay(300); 328 | ChangeSpeed(factor * 4 + minSpeed); 329 | break; 330 | case IR_BUTTON_3: 331 | buzzer.tone(NTD3, 300); 332 | delay(300); 333 | ChangeSpeed(factor * 3 + minSpeed); 334 | break; 335 | case IR_BUTTON_2: 336 | buzzer.tone(NTD2, 300); 337 | delay(300); 338 | ChangeSpeed(factor * 2 + minSpeed); 339 | break; 340 | case IR_BUTTON_1: 341 | buzzer.tone(NTD1, 300); 342 | delay(300); 343 | ChangeSpeed(factor * 1 + minSpeed); 344 | break; 345 | } 346 | } 347 | else if (millis() - time > 120) 348 | { 349 | motor_sta = STOP; 350 | time = millis(); 351 | } 352 | } 353 | void Forward() 354 | { 355 | MotorL.run(-moveSpeed); 356 | MotorR.run(moveSpeed); 357 | } 358 | void Backward() 359 | { 360 | MotorL.run(moveSpeed); 361 | MotorR.run(-moveSpeed); 362 | } 363 | void TurnLeft() 364 | { 365 | MotorL.run(-moveSpeed/10); 366 | MotorR.run(moveSpeed); 367 | } 368 | void TurnRight() 369 | { 370 | MotorL.run(-moveSpeed); 371 | MotorR.run(moveSpeed/10); 372 | } 373 | void Stop() 374 | { 375 | rgb.clear(); 376 | MotorL.run(0); 377 | MotorR.run(0); 378 | } 379 | uint8_t prevState = 0; 380 | void ChangeSpeed(int spd) 381 | { 382 | buzzer.tone(NTD5, 300); 383 | moveSpeed = spd; 384 | } 385 | 386 | void modeA() 387 | { 388 | switch (motor_sta) 389 | { 390 | case RUN_F: 391 | Forward(); 392 | prevState = motor_sta; 393 | break; 394 | case RUN_B: 395 | Backward(); 396 | prevState = motor_sta; 397 | break; 398 | case RUN_L: 399 | TurnLeft(); 400 | prevState = motor_sta; 401 | break; 402 | case RUN_R: 403 | TurnRight(); 404 | prevState = motor_sta; 405 | break; 406 | case STOP: 407 | if(prevState!=motor_sta){ 408 | prevState = motor_sta; 409 | Stop(); 410 | } 411 | break; 412 | } 413 | 414 | } 415 | 416 | void modeB() 417 | { 418 | uint8_t d = ultr.distanceCm(50); 419 | static long time = millis(); 420 | randomSeed(analogRead(6)); 421 | uint8_t randNumber = random(2); 422 | if (d > 15 || d == 0)Forward(); 423 | else if (d > 10) { 424 | switch (randNumber) 425 | { 426 | case 0: 427 | TurnLeft(); 428 | delay(200); 429 | break; 430 | case 1: 431 | TurnRight(); 432 | delay(200); 433 | break; 434 | } 435 | } 436 | else 437 | { 438 | Backward(); 439 | delay(400); 440 | } 441 | delay(100); 442 | } 443 | 444 | void modeC() 445 | { 446 | uint8_t val; 447 | val = line.readSensors(); 448 | if(moveSpeed >230)moveSpeed=230; 449 | switch (val) 450 | { 451 | case S1_IN_S2_IN: 452 | Forward(); 453 | LineFollowFlag=10; 454 | break; 455 | 456 | case S1_IN_S2_OUT: 457 | Forward(); 458 | if (LineFollowFlag>1) LineFollowFlag--; 459 | break; 460 | 461 | case S1_OUT_S2_IN: 462 | Forward(); 463 | if (LineFollowFlag<20) LineFollowFlag++; 464 | break; 465 | 466 | case S1_OUT_S2_OUT: 467 | if(LineFollowFlag==10) Backward(); 468 | if(LineFollowFlag<10) TurnLeft(); 469 | if(LineFollowFlag>10) TurnRight(); 470 | break; 471 | } 472 | // delay(50); 473 | } 474 | void parseData(){ 475 | isStart = false; 476 | int idx = readBuffer(3); 477 | int action = readBuffer(4); 478 | int device = readBuffer(5); 479 | switch(action){ 480 | case GET:{ 481 | writeHead(); 482 | writeSerial(idx); 483 | readSensor(device); 484 | writeEnd(); 485 | } 486 | break; 487 | case RUN:{ 488 | runModule(device); 489 | callOK(); 490 | } 491 | break; 492 | case RESET:{ 493 | //reset 494 | callOK(); 495 | } 496 | break; 497 | case START:{ 498 | //start 499 | callOK(); 500 | } 501 | break; 502 | } 503 | } 504 | void callOK(){ 505 | writeSerial(0xff); 506 | writeSerial(0x55); 507 | writeEnd(); 508 | } 509 | void sendByte(char c){ 510 | writeSerial(1); 511 | writeSerial(c); 512 | } 513 | void sendString(String s){ 514 | int l = s.length(); 515 | writeSerial(4); 516 | writeSerial(l); 517 | for(int i=0;i15){ 574 | break; 575 | } 576 | _receiveUint8[i] = readBuffer(idx+i); 577 | } 578 | return _receiveUint8; 579 | } 580 | void runModule(int device){ 581 | //0xff 0x55 0x6 0x0 0x2 0x22 0x9 0x0 0x0 0xa 582 | int port = readBuffer(6); 583 | int pin = port; 584 | switch(device){ 585 | case MOTOR:{ 586 | int speed = readShort(7); 587 | port==M1?MotorL.run(speed):MotorR.run(speed); 588 | } 589 | break; 590 | case JOYSTICK:{ 591 | int leftSpeed = readShort(6); 592 | MotorL.run(leftSpeed); 593 | int rightSpeed = readShort(8); 594 | MotorR.run(rightSpeed); 595 | } 596 | break; 597 | case RGBLED:{ 598 | int idx = readBuffer(7); 599 | int r = readBuffer(8); 600 | int g = readBuffer(9); 601 | int b = readBuffer(10); 602 | rgb.setColor(idx,r, g, b); 603 | rgb.show(); 604 | } 605 | break; 606 | case SERVO:{ 607 | int slot = readBuffer(7); 608 | pin = slot==1?mePort[port].s1:mePort[port].s2; 609 | int v = readBuffer(8); 610 | if(v>=0&&v<=180){ 611 | servo.attach(pin); 612 | servo.write(v); 613 | } 614 | } 615 | break; 616 | case SEVSEG:{ 617 | if(seg.getPort()!=port){ 618 | seg.reset(port); 619 | } 620 | float v = readFloat(7); 621 | seg.display(v); 622 | } 623 | break; 624 | case LEDMATRIX:{ 625 | if(ledMx.getPort()!=port){ 626 | ledMx.reset(port); 627 | } 628 | int action = readBuffer(7); 629 | if(action==1){ 630 | int brightness = readBuffer(8); 631 | int color = readBuffer(9); 632 | int px = readShort(10); 633 | int py = readShort(12); 634 | int len = readBuffer(14); 635 | char *s = readString(15,len); 636 | ledMx.clearScreen(); 637 | ledMx.setColorIndex(color); 638 | ledMx.setBrightness(brightness); 639 | ledMx.drawStr(px,py,s); 640 | }else if(action==2){ 641 | int brightness = readBuffer(8); 642 | int dw = readBuffer(9); 643 | int px = readShort(10); 644 | int py = readShort(12); 645 | int len = readBuffer(14); 646 | uint8_t *ss = readUint8(15,len); 647 | ledMx.clearScreen(); 648 | ledMx.setColorIndex(1); 649 | ledMx.setBrightness(brightness); 650 | ledMx.drawBitmap(px,py,dw,ss); 651 | }else if(action==3){ 652 | int brightness = readBuffer(8); 653 | int point = readBuffer(9); 654 | int hours = readShort(10); 655 | int minutes = readShort(12); 656 | ledMx.clearScreen(); 657 | ledMx.setColorIndex(1); 658 | ledMx.setBrightness(brightness); 659 | ledMx.showClock(hours,minutes,point); 660 | } 661 | } 662 | break; 663 | case LIGHT_SENSOR:{ 664 | if(generalDevice.getPort()!=port){ 665 | generalDevice.reset(port); 666 | } 667 | int v = readBuffer(7); 668 | generalDevice.dWrite1(v); 669 | } 670 | break; 671 | case IR:{ 672 | int len = readBuffer(2)-3; 673 | String s =""; 674 | for(int i=0;i0){ 708 | buzzer.tone(hz); 709 | }else{ 710 | buzzer.noTone(); 711 | } 712 | } 713 | break; 714 | case SERVO_PIN:{ 715 | int v = readBuffer(7); 716 | if(v>=0&&v<=180){ 717 | servo.attach(pin); 718 | servo.write(v); 719 | } 720 | } 721 | break; 722 | case TIMER:{ 723 | lastTime = millis()/1000.0; 724 | } 725 | break; 726 | } 727 | } 728 | void readSensor(int device){ 729 | /************************************************** 730 | ff 55 len idx action device port slot data a 731 | 0 1 2 3 4 5 6 7 8 732 | 0xff 0x55 0x4 0x3 0x1 0x1 0x1 0xa 733 | ***************************************************/ 734 | float value=0.0; 735 | int port,slot,pin; 736 | port = readBuffer(6); 737 | pin = port; 738 | switch(device){ 739 | case ULTRASONIC_SENSOR:{ 740 | if(ultr.getPort()!=port){ 741 | ultr.reset(port); 742 | } 743 | value = (float)ultr.distanceCm(50000); 744 | sendFloat(value); 745 | } 746 | break; 747 | case TEMPERATURE_SENSOR:{ 748 | slot = readBuffer(7); 749 | if(ts.getPort()!=port||ts.getSlot()!=slot){ 750 | ts.reset(port,slot); 751 | } 752 | value = ts.temperature(); 753 | sendFloat(value); 754 | } 755 | break; 756 | case LIGHT_SENSOR: 757 | case SOUND_SENSOR: 758 | case POTENTIONMETER:{ 759 | if(generalDevice.getPort()!=port){ 760 | generalDevice.reset(port); 761 | pinMode(generalDevice.pin2(),INPUT); 762 | } 763 | value = generalDevice.aRead2(); 764 | sendFloat(value); 765 | } 766 | break; 767 | case JOYSTICK:{ 768 | slot = readBuffer(7); 769 | if(generalDevice.getPort()!=port){ 770 | generalDevice.reset(port); 771 | pinMode(generalDevice.pin1(),INPUT); 772 | pinMode(generalDevice.pin2(),INPUT); 773 | } 774 | if(slot==1){ 775 | value = generalDevice.aRead1(); 776 | sendFloat(value); 777 | }else if(slot==2){ 778 | value = generalDevice.aRead2(); 779 | sendFloat(value); 780 | } 781 | } 782 | break; 783 | case IR:{ 784 | // if(ir.getPort()!=port){ 785 | // ir.reset(port); 786 | // } 787 | // if(irReady){ 788 | // sendString(irBuffer); 789 | // irReady = false; 790 | // irBuffer = ""; 791 | // } 792 | } 793 | break; 794 | case IRREMOTE:{ 795 | // unsigned char r = readBuffer(7); 796 | // if(millis()/1000.0-lastIRTime>0.2){ 797 | // sendByte(0); 798 | // }else{ 799 | // sendByte(irRead==r); 800 | // } 801 | // //irRead = 0; 802 | // irIndex = 0; 803 | } 804 | break; 805 | case IRREMOTECODE:{ 806 | // sendByte(irRead); 807 | // irRead = 0; 808 | // irIndex = 0; 809 | } 810 | break; 811 | case PIRMOTION:{ 812 | if(generalDevice.getPort()!=port){ 813 | generalDevice.reset(port); 814 | pinMode(generalDevice.pin2(),INPUT); 815 | } 816 | value = generalDevice.dRead2(); 817 | sendFloat(value); 818 | } 819 | break; 820 | case LINEFOLLOWER:{ 821 | if(generalDevice.getPort()!=port){ 822 | generalDevice.reset(port); 823 | pinMode(generalDevice.pin1(),INPUT); 824 | pinMode(generalDevice.pin2(),INPUT); 825 | } 826 | value = generalDevice.dRead1()*2+generalDevice.dRead2(); 827 | sendFloat(value); 828 | } 829 | break; 830 | case LIMITSWITCH:{ 831 | slot = readBuffer(7); 832 | if(generalDevice.getPort()!=port||generalDevice.getSlot()!=slot){ 833 | generalDevice.reset(port,slot); 834 | } 835 | if(slot==1){ 836 | pinMode(generalDevice.pin1(),INPUT_PULLUP); 837 | value = generalDevice.dRead1(); 838 | }else{ 839 | pinMode(generalDevice.pin2(),INPUT_PULLUP); 840 | value = generalDevice.dRead2(); 841 | } 842 | sendFloat(value); 843 | } 844 | break; 845 | case BUTTON_INNER:{ 846 | pin = analogs[pin]; 847 | char s = readBuffer(7); 848 | pinMode(pin,INPUT); 849 | boolean currentPressed = !(analogRead(pin)>10); 850 | sendByte(s^(currentPressed?1:0)); 851 | buttonPressed = currentPressed; 852 | } 853 | break; 854 | case GYRO:{ 855 | // int axis = readBuffer(7); 856 | // gyro.update(); 857 | // if(axis==1){ 858 | // value = gyro.getAngleX(); 859 | // sendFloat(value); 860 | // }else if(axis==2){ 861 | // value = gyro.getAngleY(); 862 | // sendFloat(value); 863 | // }else if(axis==3){ 864 | // value = gyro.getAngleZ(); 865 | // sendFloat(value); 866 | // } 867 | } 868 | break; 869 | case VERSION:{ 870 | sendString(mVersion); 871 | } 872 | break; 873 | case DIGITAL:{ 874 | pinMode(pin,INPUT); 875 | sendFloat(digitalRead(pin)); 876 | } 877 | break; 878 | case ANALOG:{ 879 | pin = analogs[pin]; 880 | pinMode(pin,INPUT); 881 | sendFloat(analogRead(pin)); 882 | } 883 | break; 884 | case TIMER:{ 885 | sendFloat(currentTime); 886 | } 887 | break; 888 | } 889 | } 890 | -------------------------------------------------------------------------------- /mBot-default-program/mCore.h: -------------------------------------------------------------------------------- 1 | ///@file Makeblock.h head file of Makeblock Library V2.1.0625 2 | ///Define the interface of Makeblock Library 3 | 4 | #ifndef mCore_h 5 | #define mCore_h 6 | 7 | #include "MePort.h" 8 | #include "MeDCMotor.h" 9 | #include "MeBuzzer.h" 10 | #include "MeTemperature.h" 11 | #include "Me7SegmentDisplay.h" 12 | #include "MeRGBLed.h" 13 | #include "MeUltrasonic.h" 14 | #include "MeInfraredReceiver.h" 15 | #include "MeIR.h" 16 | #include "MeLineFollower.h" 17 | #include "MeLEDMatrix.h" 18 | Board_type MakeblockBoard = mCore; 19 | 20 | MePort_Sig mePort[11]={{NC, NC}, {11, 12}, {9, 10}, {A2, A3}, {A0, A1}, 21 | {6, 7}, {5, 4}, {A7, 13}, {8, A6}, {6, 7}, {5, 4}}; 22 | 23 | ///@brief Class for MeBoard 24 | // class MeBoard 25 | // { 26 | // public: 27 | // MeBoard(uint8_t boards); 28 | // }; 29 | 30 | 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /pcb/mCore.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Makeblock-official/mBot/f35251ac89f046214e1f3a5be582abccd32f04a0/pcb/mCore.pdf --------------------------------------------------------------------------------