├── GoKit.cpp ├── GoKit.h ├── doc ├── arduino串口下载方法.doc └── 串口烧写工具 │ └── Arduino.zip ├── gokit_2.ino ├── image ├── Thumbs.db └── gokit.jpg ├── lib └── lib │ ├── ChainableLED │ ├── ChainableLED.cpp │ ├── ChainableLED.h │ ├── LICENSE │ ├── README.md │ ├── examples │ │ ├── CycleThroughColors │ │ │ └── CycleThroughColors.ino │ │ ├── FadeInOut │ │ │ └── FadeInOut.ino │ │ └── SimpleCycle │ │ │ └── SimpleCycle.ino │ └── keywords.txt │ ├── DHT │ ├── DHT.cpp │ ├── DHT.h │ ├── README.txt │ └── examples │ │ └── DHTtester │ │ └── DHTtester.ino │ ├── I2Cdev │ ├── I2Cdev.cpp │ ├── I2Cdev.h │ ├── _Stub │ │ ├── _Stub.cpp │ │ └── _Stub.h │ └── keywords.txt │ ├── MemoryFree │ ├── .gitignore │ ├── MemoryFree.cpp │ ├── MemoryFree.h │ ├── README │ └── examples │ │ └── FreeMemory │ │ └── FreeMemory.pde │ ├── MsTimer2 │ ├── MsTimer2.cpp │ ├── MsTimer2.h │ ├── examples │ │ └── FlashLed │ │ │ └── FlashLed.pde │ └── keywords.txt │ └── SSD1306 │ ├── SSD1306.cpp │ ├── SSD1306.h │ └── glcdfont.c ├── protocol.cpp ├── protocol.h └── readme.txt /GoKit.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "GoKit.h" 8 | 9 | DHT dht(DHTPIN, DHTTYPE); 10 | ChainableLED leds(A5, A4, 1); 11 | #if(DEBUG==1) 12 | SoftwareSerial mySerial(8, 9); 13 | #endif 14 | void motortime(); 15 | unsigned char uart_buf[MAX_UART_LEN]={0}; 16 | m2w_returnMcuInfo m_m2w_returnMcuInfo; 17 | pro_commonCmd m_pro_commonCmd; //通用命令 心跳 ack等待复用 18 | m2w_setModule m_m2w_setModule; //配置模块 19 | w2m_controlMcu m_w2m_controlMcu; //控制MCU 20 | m2w_mcuStatus m_m2w_mcuStatus; //MCU当前状态 21 | m2w_mcuStatus m_m2w_mcuStatus_reported; //上次MCU的状态 22 | w2m_reportModuleStatus m_w2m_reportModuleStatus; //WIFI模组状态 23 | pro_errorCmd m_pro_errorCmd; //错误命令帧 24 | unsigned char SN = 0; 25 | unsigned long last_time=0; 26 | unsigned char hal_UartRxBuffer[UART_RX_BUF_SIZE]; 27 | 28 | int hal_UartRxLen; 29 | int hal_dmatxhead, hal_dmatxtail; 30 | int hal_UartRxTail; 31 | int hal_UartRxHead; 32 | void GoKit_Init() 33 | { 34 | Serial.begin(9600); 35 | #if(DEBUG==1) 36 | mySerial.begin(9600); 37 | #endif 38 | dht.begin(); 39 | leds.init(); 40 | 41 | pinMode(KEY1,INPUT_PULLUP); //KEY1 上拉输入 42 | pinMode(KEY2,INPUT_PULLUP); //KEY2 上拉输入 43 | attachInterrupt(0, gokit_IR_event, CHANGE);//当引脚电平发生变化,触发中断函数gokit_IR_event pin 2 44 | MsTimer2::set(1000, gokit_timer); // 1s period 45 | MsTimer2::start(); 46 | gokit_motor_init(); 47 | gokit_setColorRGB(0,0,0); 48 | McuStatusInit(); 49 | } 50 | /******************************************************************************* 51 | * Function Name : exchangeBytes 52 | * Description : like htonl 53 | * Input : value 54 | * Output : None 55 | * Return : 转换之后的数据 56 | * Attention : None 57 | *******************************************************************************/ 58 | unsigned short exchangeBytes(unsigned short value) 59 | { 60 | short tmp_value; 61 | unsigned char *index_1, *index_2; 62 | 63 | index_1 = (unsigned char *)&tmp_value; 64 | index_2 = (unsigned char *)&value; 65 | 66 | *index_1 = *(index_2+1); 67 | *(index_1+1) = *index_2; 68 | 69 | return tmp_value; 70 | } 71 | /******************************************************************************* 72 | * Function Name : SendToUart 73 | * Description : send data to uart 74 | * *buf : the pointer of data to uart 75 | * packLen : the data length 76 | * Return : None 77 | *******************************************************************************/ 78 | void SendToUart(unsigned char *buf, unsigned short packLen, unsigned char tag) 79 | { 80 | unsigned short i=0; 81 | int Send_num; 82 | pro_headPart send_headPart; 83 | pro_commonCmd recv_commonCmd; 84 | unsigned char m_55 = 0x55; 85 | unsigned long last_time=0; 86 | for(i=0;i=2 && buf[i] == 0xFF) Serial.write(m_55); // add 0x55 while across 0xff except head. 90 | } 91 | if( tag == 0 ) return ; 92 | 93 | memcpy(&send_headPart, buf, sizeof(pro_headPart)); 94 | memset(&recv_commonCmd, 0, sizeof(pro_commonCmd)); 95 | last_time = gokit_time_ms(); 96 | Send_num = 1; 97 | #if(DEBUG==1) 98 | Serial.print("restart send timems"); 99 | Serial.println(gokit_time_ms()); 100 | #endif 101 | while(Send_num 0) 106 | { 107 | memcpy(&recv_commonCmd, uart_buf, sizeof(pro_commonCmd)); 108 | if((send_headPart.cmd == CMD_SEND_MODULE_P0 && recv_commonCmd.head_part.cmd == CMD_SEND_MODULE_P0_ACK) && 109 | (send_headPart.sn == recv_commonCmd.head_part.sn)) break; 110 | 111 | if((send_headPart.cmd == CMD_SET_MODULE_WORKMODE && recv_commonCmd.head_part.cmd == CMD_SET_MODULE_WORKMODE_ACK) && 112 | (send_headPart.sn == recv_commonCmd.head_part.sn)) break; 113 | 114 | if((send_headPart.cmd == CMD_RESET_MODULE && recv_commonCmd.head_part.cmd == CMD_RESET_MODULE_ACK) && 115 | (send_headPart.sn == recv_commonCmd.head_part.sn)) break; 116 | } 117 | } 118 | else 119 | { 120 | last_time = gokit_time_ms(); 121 | Send_num++; 122 | for(i=0;i=2 && buf[i] == 0xFF) Serial.write(m_55); // add 0x55 while across 0xff except head. 126 | } 127 | #if(DEBUG==1) 128 | Serial.print("restart send timems"); 129 | Serial.println(gokit_time_ms()); 130 | #endif 131 | } 132 | } 133 | } 134 | /******************************************************************************* 135 | * Function Name : SendCommonCmd 136 | * Description : send common cmd to WiFi 137 | * cmd : CMD_SEND_MCU_P0_ACK CMD_REPORT_MODULE_STATUS_ACK CMD_SEND_HEARTBEAT_ACK 138 | * or CMD_REBOOT_MCU_ACK 139 | * packLen : sn 140 | * Return : None 141 | *******************************************************************************/ 142 | void SendCommonCmd(uint8_t cmd, uint8_t sn) 143 | { 144 | memset(&m_pro_commonCmd, 0, sizeof(pro_commonCmd)); 145 | 146 | m_pro_commonCmd.head_part.head[0] = 0xFF; 147 | m_pro_commonCmd.head_part.head[1] = 0xFF; 148 | m_pro_commonCmd.head_part.len = exchangeBytes(5); 149 | m_pro_commonCmd.head_part.cmd = cmd; 150 | m_pro_commonCmd.head_part.sn = sn; 151 | m_pro_commonCmd.sum = CheckSum((uint8_t *)&m_pro_commonCmd, sizeof(pro_commonCmd)); 152 | 153 | SendToUart((uint8_t *)&m_pro_commonCmd, sizeof(pro_commonCmd), 0); 154 | } 155 | 156 | void SendErrorCmd(uint8_t error_no, uint8_t sn) 157 | { 158 | m_pro_errorCmd.head_part.sn = sn; 159 | m_pro_errorCmd.error = error_no; 160 | m_pro_errorCmd.sum = CheckSum((uint8_t *)&m_pro_errorCmd, sizeof(pro_errorCmd)); 161 | 162 | SendToUart((uint8_t *)&m_pro_errorCmd, sizeof(pro_errorCmd), 0); 163 | } 164 | 165 | int McuStatusInit() 166 | { 167 | //common package init 168 | memset(&m_pro_commonCmd, 0, sizeof(pro_commonCmd)); 169 | m_pro_commonCmd.head_part.head[0] = 0xFF; 170 | m_pro_commonCmd.head_part.head[1] = 0xFF; 171 | m_pro_commonCmd.head_part.len = exchangeBytes(sizeof(pro_commonCmd) - 4); 172 | 173 | // mcu info package init 174 | memset(&m_m2w_returnMcuInfo, 0, sizeof(m2w_returnMcuInfo)); 175 | m_m2w_returnMcuInfo.head_part.head[0] = 0xFF; 176 | m_m2w_returnMcuInfo.head_part.head[1] = 0xFF; 177 | m_m2w_returnMcuInfo.head_part.len = exchangeBytes(sizeof(m2w_returnMcuInfo) - 4); //except FF FF XX XX(XX XX is the len) 178 | m_m2w_returnMcuInfo.head_part.cmd = CMD_GET_MCU_INFO_ACK; 179 | memcpy(m_m2w_returnMcuInfo.pro_ver, PRO_VER, 8); 180 | memcpy(m_m2w_returnMcuInfo.p0_ver, P0_VER, 8); 181 | memcpy(m_m2w_returnMcuInfo.hard_ver, HARD_VER, 8); 182 | memcpy(m_m2w_returnMcuInfo.soft_ver, SOFT_VER, 8); 183 | memcpy(m_m2w_returnMcuInfo.product_key, PRODUCT_KEY, 32); 184 | m_m2w_returnMcuInfo.binable_time = exchangeBytes(PASSCODE_TIME); //can be binded any time 185 | 186 | // 187 | memset(&m_m2w_mcuStatus, 0, sizeof(m2w_mcuStatus)); 188 | m_m2w_mcuStatus.head_part.head[0] = 0xFF; 189 | m_m2w_mcuStatus.head_part.head[1] = 0xFF; 190 | m_m2w_mcuStatus.head_part.len = exchangeBytes(sizeof(m2w_mcuStatus) - 4); 191 | gokit_DHT11_Read_Data((uint8_t *)&(m_m2w_mcuStatus.status_r.temputure), (uint8_t *)&(m_m2w_mcuStatus.status_r.humidity)); 192 | m_m2w_mcuStatus.status_w.motor_speed = 5; 193 | 194 | // 195 | memset(&m_m2w_setModule, 0, sizeof(m2w_setModule)); 196 | m_m2w_setModule.head_part.head[0] = 0xFF; 197 | m_m2w_setModule.head_part.head[1] = 0xFF; 198 | m_m2w_setModule.head_part.cmd = CMD_SET_MODULE_WORKMODE; 199 | m_m2w_setModule.head_part.len = exchangeBytes(sizeof(m2w_setModule) - 4); 200 | 201 | // 202 | memset(&m_pro_errorCmd, 0, sizeof(pro_errorCmd)); 203 | m_pro_errorCmd.head_part.head[0] = 0xFF; 204 | m_pro_errorCmd.head_part.head[1] = 0xFF; 205 | m_pro_errorCmd.head_part.cmd = CMD_MODULE_CMD_ERROR_ACK; 206 | m_pro_errorCmd.head_part.len = exchangeBytes(sizeof(pro_errorCmd) - 4); 207 | 208 | } 209 | void CmdGetMcuInfo(uint8_t sn) 210 | { 211 | m_m2w_returnMcuInfo.head_part.sn = sn; 212 | m_m2w_returnMcuInfo.sum = CheckSum((uint8_t *)&m_m2w_returnMcuInfo, sizeof(m2w_returnMcuInfo)); 213 | SendToUart((uint8_t *)&m_m2w_returnMcuInfo, sizeof(m2w_returnMcuInfo), 0); 214 | } 215 | /****************************************************** 216 | * function : serialEvent 217 | * Description : arduino serial uart receive interrupt 218 | * function 219 | * 220 | * return : none. 221 | * Add by Alex.lin --2014-12-24 222 | ******************************************************/ 223 | void serialEvent() 224 | { 225 | hal_UartRxBuffer[hal_UartRxTail] = (unsigned char)Serial.read(); 226 | hal_UartRxTail++; 227 | if (hal_UartRxTail == UART_RX_BUF_SIZE) 228 | { 229 | hal_UartRxTail = 0; 230 | } 231 | hal_UartRxLen++; 232 | #if(DEBUG==1) 233 | Serial.println(hal_UartRxBuffer[hal_UartRxTail-1],HEX); 234 | #endif 235 | } 236 | /****************************************************** 237 | * function : get one gagetn uart package 238 | * buf : uart receive buf. 239 | * return : uart data length. 240 | * Add by Alex.lin --2014-12-24 241 | ******************************************************/ 242 | int get_onepackage(unsigned char *buf) 243 | { 244 | int ret = 0; 245 | int len = 0; 246 | int i, head=0; 247 | unsigned long receive_time=0; 248 | if (hal_UartRxLen<4) // not have enough data yet. 249 | goto done; 250 | 251 | for (i=0, head=hal_UartRxHead; i+1<(int)hal_UartRxLen; i++) 252 | { 253 | 254 | if ((hal_UartRxBuffer[head] != 0xFF) || (hal_UartRxBuffer[(head+1)%UART_RX_BUF_SIZE] != 0xFF) ) 255 | { 256 | head++; 257 | if (head == UART_RX_BUF_SIZE) { 258 | head = 0; 259 | } 260 | } else { 261 | break; 262 | } 263 | } 264 | hal_UartRxLen -= i; 265 | hal_UartRxHead = head; // remove invalid data. 266 | 267 | if (hal_UartRxLen<4) // not have enough data yet. 268 | goto done; 269 | 270 | // copy first 4 bytes to buf 271 | head = hal_UartRxHead; 272 | for (i = 0; i < 4; i++) 273 | { 274 | buf[i] = hal_UartRxBuffer[head++]; 275 | if (head == UART_RX_BUF_SIZE) { 276 | head = 0; 277 | } 278 | } 279 | 280 | // total data length 281 | len = (buf[2]<<8 )+ buf[3] + 4; 282 | 283 | if (len > UART_RX_BUF_SIZE) { // length to long, must wrong format 284 | goto WRONG; 285 | } 286 | 287 | if (len > (int)hal_UartRxLen)// 288 | goto done; // not have enough data yet. 289 | 290 | receive_time = gokit_time_s(); 291 | // copy data & checksum to buf 292 | for (; i1) 295 | { 296 | goto WRONG;//1S内没接收到全数据,跳出。 297 | } 298 | buf[i] = hal_UartRxBuffer[head]; 299 | head++; 300 | if (head == UART_RX_BUF_SIZE) { 301 | head = 0; 302 | } 303 | } 304 | 305 | ret = len; 306 | hal_UartRxLen -= len; 307 | hal_UartRxHead = head; 308 | goto done; 309 | 310 | WRONG: // wrong format, remove one byte 311 | hal_UartRxLen--; 312 | hal_UartRxHead++; 313 | if (hal_UartRxHead == UART_RX_BUF_SIZE) { 314 | hal_UartRxHead = 0; 315 | } 316 | done: 317 | return ret; 318 | } 319 | 320 | /******************************************************* 321 | * function : gokit_time_ms 322 | * Description : gokit running time form power on 323 | * return : gokit running time(ms). 324 | * Add by Alex.lin --2014-12-25 325 | ******************************************************/ 326 | unsigned long gokit_time_ms() 327 | { 328 | return millis(); 329 | } 330 | /******************************************************* 331 | * function : gokit_time_m 332 | * Description : gokit running time form power on 333 | * return : gokit running time(m). 334 | * Add by Alex.lin --2014-12-25 335 | ******************************************************/ 336 | unsigned long gokit_time_s() 337 | { 338 | return millis()/1000; 339 | } 340 | 341 | /******************************************************* 342 | * function : gokit_DHT11_Read_Data 343 | * Description : gokit read temperature and hum 344 | * return : none 345 | * Add by Alex.lin --2014-12-25 346 | ******************************************************/ 347 | 348 | void gokit_DHT11_Read_Data( unsigned char *temperature,unsigned char *humidity) 349 | { 350 | *temperature = (unsigned char)dht.readTemperature(); 351 | *humidity = (unsigned char)dht.readHumidity(); 352 | return ; 353 | } 354 | /******************************************************* 355 | * function : gokit_key1down 356 | * Description : check the gokit key1 event 357 | * return : KEY1_LONG_PRESS KEY1_SHORT_PRESS 358 | * 0-no keydown event. 359 | * Add by Alex.lin --2014-12-25 360 | ******************************************************/ 361 | char gokit_key1down() 362 | { 363 | int unsigned long keep_time=0; 364 | if( digitalRead(KEY1)==LOW) 365 | { 366 | delay(100); 367 | if(digitalRead(KEY1)==LOW) 368 | { 369 | keep_time = gokit_time_s(); 370 | while(digitalRead(KEY1)==LOW) 371 | { 372 | if( (gokit_time_s()-keep_time)> KEY_LONG_TIMER) 373 | { 374 | return KEY1_LONG_PRESS; 375 | } 376 | }//until open the key 377 | return KEY1_SHORT_PRESS ; 378 | } 379 | return 0; 380 | } 381 | return 0; 382 | } 383 | /******************************************************* 384 | * function : gokit_key2down 385 | * Description : check the gokit key2 event 386 | * return : KEY2_LONG_PRESS KEY2_SHORT_PRESS 387 | * 0-no keydown event. 388 | * Add by Alex.lin --2014-12-25 389 | ******************************************************/ 390 | char gokit_key2down() 391 | { 392 | int unsigned long keep_time=0; 393 | if( digitalRead(KEY2)==LOW) 394 | { 395 | delay(100); 396 | if(digitalRead(KEY2)==LOW) 397 | { 398 | keep_time = gokit_time_s(); 399 | while(digitalRead(KEY2)==LOW)//until open the key 400 | { 401 | 402 | if( (gokit_time_s()-keep_time)> KEY_LONG_TIMER) 403 | { 404 | return KEY2_LONG_PRESS; 405 | } 406 | } 407 | 408 | return KEY2_SHORT_PRESS; 409 | } 410 | return 0; 411 | } 412 | return 0; 413 | } 414 | /******************************************************* 415 | * function : gokit_keydown 416 | * Description : check the gokit key1 or key2 event 417 | * return : KEY1_LONG_PRESS KEY1_SHORT_PRESS 418 | * KEY2_LONG_PRESS KEY2_SHORT_PRESS 419 | * 0-no keydown event. 420 | * Add by Alex.lin --2014-12-25 421 | ******************************************************/ 422 | char gokit_keydown() 423 | { 424 | char ret=0; 425 | ret |= gokit_key2down(); 426 | ret |= gokit_key1down(); 427 | return ret; 428 | 429 | } 430 | /******************************************************* 431 | * function : gokit_IR_event 432 | * Description : check the gokit infrared event 433 | * return : none 434 | * 435 | * Add by Alex.lin --2014-12-25 436 | ******************************************************/ 437 | void gokit_IR_event() 438 | { 439 | noInterrupts(); 440 | if(digitalRead(2)) 441 | { 442 | #if (DEBUG==1) 443 | Serial.println("gokit_IR_event! no happen. "); 444 | #endif 445 | m_m2w_mcuStatus.status_r.ir_status &= ~(1<<0); 446 | } 447 | else 448 | { 449 | #if (DEBUG==1) 450 | Serial.println("gokit_IR_event! happen. "); 451 | #endif 452 | m_m2w_mcuStatus.status_r.ir_status |= (1<<0); 453 | } 454 | interrupts(); 455 | } 456 | /******************************************************* 457 | * function : gokit_setColorRGB 458 | * Description : set gokit colorrgb led 459 | * return : none 460 | * 461 | * Add by Alex.lin --2014-12-25 462 | ******************************************************/ 463 | void gokit_setColorRGB(byte red, byte green, byte blue) 464 | { 465 | leds.setColorRGB(0, red, green, blue); 466 | } 467 | /******************************************************* 468 | * function : gokit_motor_init 469 | * Description : init gokit motor. 470 | * return : none 471 | * 472 | * Add by Alex.lin --2014-12-25 473 | ******************************************************/ 474 | void gokit_motor_init() 475 | { 476 | pinMode(MOTOR_PINA,OUTPUT); 477 | pinMode(MOTOR_PINB,OUTPUT); 478 | digitalWrite(MOTOR_PINB,LOW); 479 | digitalWrite(MOTOR_PINA,LOW); 480 | gokit_motorstatus(5); 481 | } 482 | /******************************************************* 483 | * function : gokit_motorstatus 484 | * Description : set gokit motor speed. 485 | * return : none 486 | * 487 | * Add by Alex.lin --2014-12-25 488 | ******************************************************/ 489 | void gokit_motorstatus( char motor_speed ) 490 | { 491 | 492 | unsigned char Temp_motor_speed=0; 493 | if(motor_speed==5) //停止 494 | { 495 | digitalWrite(MOTOR_PINA,LOW); 496 | digitalWrite(MOTOR_PINB,LOW); 497 | } 498 | if(motor_speed>5)//正转 499 | { 500 | Temp_motor_speed = (motor_speed-5)*51; 501 | if(Temp_motor_speed>255) Temp_motor_speed=255; 502 | digitalWrite(MOTOR_PINA,LOW); 503 | analogWrite( MOTOR_PINB, Temp_motor_speed); 504 | } 505 | if(motor_speed<5)//反转 506 | { 507 | Temp_motor_speed = (255-(5+motor_speed))*51; 508 | if(Temp_motor_speed>255) Temp_motor_speed =255; 509 | digitalWrite(MOTOR_PINA,HIGH); 510 | analogWrite( MOTOR_PINB,Temp_motor_speed ); 511 | } 512 | } 513 | 514 | void gokit_timer() 515 | { 516 | } 517 | /******************************************************* 518 | * function : gokit_ResetWiFi 519 | * Description : gokit reset the wifi. 520 | * return : None. 521 | * Add by Alex.lin --2014-12-25 522 | ******************************************************/ 523 | void gokit_ResetWiFi() 524 | { 525 | gokit_setColorRGB(0,0,50); 526 | delay(500); 527 | gokit_setColorRGB(0,0,0); 528 | 529 | m_pro_commonCmd.head_part.cmd = CMD_RESET_MODULE; 530 | m_pro_commonCmd.head_part.sn = ++SN; 531 | m_pro_commonCmd.sum = CheckSum((uint8_t *)&m_pro_commonCmd, sizeof(pro_commonCmd)); 532 | SendToUart((uint8_t *)&m_pro_commonCmd, sizeof(pro_commonCmd), 1); 533 | } 534 | /******************************************************* 535 | * function : WiFi_Config 536 | * Description : Gonfig wifi into airlink 537 | * return : None. 538 | * Add by Alex.lin --2014-12-25 539 | ******************************************************/ 540 | void gokit_sendAirlink() 541 | { 542 | gokit_setColorRGB(0,50,0); 543 | m_m2w_setModule.config_info = 0x02; //air link 544 | m_m2w_setModule.head_part.sn = ++SN; 545 | m_m2w_setModule.sum = CheckSum((uint8_t *)&m_m2w_setModule, sizeof(m2w_setModule)); 546 | SendToUart((uint8_t *)&m_m2w_setModule, sizeof(m2w_setModule), 1); 547 | } 548 | void gokit_sendApCmd() 549 | { 550 | gokit_setColorRGB(50,0,0); 551 | delay(500); 552 | gokit_setColorRGB(0,0,0); 553 | 554 | m_m2w_setModule.config_info = 0x01; //air link 555 | m_m2w_setModule.head_part.sn = ++SN; 556 | m_m2w_setModule.sum = CheckSum((uint8_t *)&m_m2w_setModule, sizeof(m2w_setModule)); 557 | SendToUart((uint8_t *)&m_m2w_setModule, sizeof(m2w_setModule), 1); 558 | 559 | } 560 | void gokit_ReportStatus(uint8_t tag) 561 | { 562 | if(tag == REPORT_STATUS) 563 | { 564 | m_m2w_mcuStatus.head_part.cmd = CMD_SEND_MODULE_P0; 565 | m_m2w_mcuStatus.head_part.sn = ++SN; 566 | m_m2w_mcuStatus.sub_cmd = SUB_CMD_REPORT_MCU_STATUS; 567 | m_m2w_mcuStatus.status_w.motor_speed = exchangeBytes(m_m2w_mcuStatus.status_w.motor_speed); 568 | m_m2w_mcuStatus.sum = CheckSum((uint8_t *)&m_m2w_mcuStatus, sizeof(m2w_mcuStatus)); 569 | SendToUart((uint8_t *)&m_m2w_mcuStatus, sizeof(m2w_mcuStatus), 0); 570 | } 571 | else if(tag == REQUEST_STATUS) 572 | { 573 | m_m2w_mcuStatus.head_part.cmd = CMD_SEND_MCU_P0_ACK; 574 | m_m2w_mcuStatus.head_part.sn = m_w2m_controlMcu.head_part.sn; 575 | m_m2w_mcuStatus.sub_cmd = SUB_CMD_REQUIRE_STATUS_ACK; 576 | m_m2w_mcuStatus.status_w.motor_speed = exchangeBytes(m_m2w_mcuStatus.status_w.motor_speed); 577 | m_m2w_mcuStatus.sum = CheckSum((uint8_t *)&m_m2w_mcuStatus, sizeof(m2w_mcuStatus)); 578 | SendToUart((uint8_t *)&m_m2w_mcuStatus, sizeof(m2w_mcuStatus), 0); 579 | } 580 | 581 | 582 | m_m2w_mcuStatus.status_w.motor_speed = exchangeBytes(m_m2w_mcuStatus.status_w.motor_speed); 583 | memcpy(&m_m2w_mcuStatus_reported, &m_m2w_mcuStatus, sizeof(m2w_mcuStatus)); 584 | } 585 | -------------------------------------------------------------------------------- /GoKit.h: -------------------------------------------------------------------------------- 1 | #ifndef _GOKIT_H_ 2 | #define _GOKIT_H_ 3 | #include 4 | #include "protocol.h" 5 | 6 | #define DEBUG 0 7 | /*************************** HAL define ***************************/ 8 | #define DHTPIN 3 9 | #define DHTTYPE DHT11 10 | #define KEY1 6 11 | #define KEY2 7 12 | #define KEY1_SHORT_PRESS 1 13 | #define KEY1_LONG_PRESS 2 14 | #define KEY2_SHORT_PRESS 4 15 | #define KEY2_LONG_PRESS 8 16 | #define NO_KEY 0 17 | 18 | #define KEY_LONG_TIMER 3 //( 3s ) 19 | 20 | #define MOTOR_PINA 4 21 | #define MOTOR_PINB 5 22 | #define MOTOR_MAX 100 23 | #define MOTOR_MAX1 -100 24 | #define MOTOR_MIN 0 25 | /******************************************************************/ 26 | 27 | #define MAX_SEND_NUM 3 28 | #define MAX_SEND_TIME 200 29 | #define MAX_UART_LEN 100 30 | #define UART_RX_BUF_SIZE 100 31 | 32 | extern unsigned char uart_buf[MAX_UART_LEN]; 33 | extern SoftwareSerial mySerial; 34 | extern DHT dht; 35 | extern unsigned long last_time; 36 | extern m2w_returnMcuInfo m_m2w_returnMcuInfo; 37 | extern w2m_controlMcu m_w2m_controlMcu; //控制MCU 38 | extern m2w_mcuStatus m_m2w_mcuStatus; //MCU当前状态 39 | extern m2w_mcuStatus m_m2w_mcuStatus_reported; //上次MCU的状态 40 | extern w2m_reportModuleStatus m_w2m_reportModuleStatus; //WIFI模组状态 41 | 42 | void GoKit_Init(); 43 | int McuStatusInit(); 44 | void WiFi_Reset(); 45 | void WiFi_Config(); 46 | void gokit_motor_init(); 47 | void gokit_motorstatus( char motor_speed ); 48 | void gokit_timer(); 49 | unsigned long gokit_time_ms(); 50 | unsigned long gokit_time_s(); 51 | void gokit_DHT11_Read_Data( unsigned char *temperature,unsigned char *humidity); 52 | 53 | char gokit_key1down(); 54 | char gokit_key2down(); 55 | char gokit_keydown(); 56 | 57 | void gokit_IR_event(); 58 | void gokit_setColorRGB(byte red, byte green, byte blue); 59 | 60 | void gokit_ResetWiFi(); 61 | void gokit_sendAirlink(); 62 | void gokit_sendApCmd(); 63 | void gokit_ReportStatus(uint8_t tag); 64 | void SendToUart(unsigned char *buf, unsigned short packLen, unsigned char tag); 65 | unsigned short exchangeBytes(unsigned short value); 66 | int get_onepackage(unsigned char *buf); 67 | int send_onepackage( unsigned char *buf,int len ); 68 | void CmdGetMcuInfo(uint8_t sn); 69 | void SendCommonCmd(uint8_t cmd, uint8_t sn); 70 | void SendErrorCmd(uint8_t error_no, uint8_t sn); 71 | #endif 72 | -------------------------------------------------------------------------------- /doc/arduino串口下载方法.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gizwits/GoKit-Arduino-MCU/148d1a365c1dffd1e077d8fdd995aef7fd7011b3/doc/arduino串口下载方法.doc -------------------------------------------------------------------------------- /doc/串口烧写工具/Arduino.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gizwits/GoKit-Arduino-MCU/148d1a365c1dffd1e077d8fdd995aef7fd7011b3/doc/串口烧写工具/Arduino.zip -------------------------------------------------------------------------------- /gokit_2.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "Wire.h" 10 | #include "GoKit.h" 11 | 12 | 13 | #define OLED_DC 9 14 | #define OLED_CS 10 15 | #define OLED_CLK 13 16 | #define OLED_MOSI 11 17 | #define OLED_RESET 8 18 | 19 | SSD1306 oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); 20 | 21 | void setup() 22 | { 23 | 24 | GoKit_Init(); 25 | oled.ssd1306_init(SSD1306_SWITCHCAPVCC); 26 | oled.drawstring(0,3," Hello World! "); 27 | oled.display(); 28 | #if (DEBUG==1) 29 | Serial.println("GoKit init OK!"); 30 | Serial.print("freeMemory()="); 31 | Serial.println(freeMemory()); 32 | #endif 33 | } 34 | void loop() 35 | { 36 | GoKit_Handle(); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /image/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gizwits/GoKit-Arduino-MCU/148d1a365c1dffd1e077d8fdd995aef7fd7011b3/image/Thumbs.db -------------------------------------------------------------------------------- /image/gokit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gizwits/GoKit-Arduino-MCU/148d1a365c1dffd1e077d8fdd995aef7fd7011b3/image/gokit.jpg -------------------------------------------------------------------------------- /lib/lib/ChainableLED/ChainableLED.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Paulo Marques (pjp.marques@gmail.com) 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | * this software and associated documentation files (the "Software"), to deal in 6 | * the Software without restriction, including without limitation the rights to 7 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | * the Software, and to permit persons to whom the Software is furnished to do so, 9 | * subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | */ 21 | 22 | /* Information about the P9813 protocol obtained from: 23 | * http://www.seeedstudio.com/wiki/index.php?title=Twig_-_Chainable_RGB_LED 24 | * 25 | * HSB to RGB routine adapted from: 26 | * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript 27 | */ 28 | 29 | 30 | // -------------------------------------------------------------------------------------- 31 | 32 | #include "ChainableLED.h" 33 | 34 | // Forward declaration 35 | float hue2rgb(float p, float q, float t); 36 | 37 | // -------------------------------------------------------------------------------------- 38 | 39 | ChainableLED::ChainableLED(byte clk_pin, byte data_pin, byte number_of_leds) : 40 | _clk_pin(clk_pin), _data_pin(data_pin), _num_leds(number_of_leds) 41 | { 42 | _led_state = (byte*) calloc(_num_leds*3, sizeof(byte)); 43 | } 44 | 45 | ChainableLED::~ChainableLED() 46 | { 47 | free(_led_state); 48 | } 49 | 50 | // -------------------------------------------------------------------------------------- 51 | 52 | void ChainableLED::init() 53 | { 54 | pinMode(_clk_pin, OUTPUT); 55 | pinMode(_data_pin, OUTPUT); 56 | 57 | for (byte i=0; i<_num_leds; i++) 58 | setColorRGB(i, 0, 0, 0); 59 | } 60 | 61 | void ChainableLED::clk(void) 62 | { 63 | digitalWrite(_clk_pin, LOW); 64 | delayMicroseconds(_CLK_PULSE_DELAY); 65 | digitalWrite(_clk_pin, HIGH); 66 | delayMicroseconds(_CLK_PULSE_DELAY); 67 | } 68 | 69 | void ChainableLED::sendByte(byte b) 70 | { 71 | // Send one bit at a time, starting with the MSB 72 | for (byte i=0; i<8; i++) 73 | { 74 | // If MSB is 1, write one and clock it, else write 0 and clock 75 | if ((b & 0x80) != 0) 76 | digitalWrite(_data_pin, HIGH); 77 | else 78 | digitalWrite(_data_pin, LOW); 79 | clk(); 80 | 81 | // Advance to the next bit to send 82 | b <<= 1; 83 | } 84 | } 85 | 86 | void ChainableLED::sendColor(byte red, byte green, byte blue) 87 | { 88 | // Start by sending a byte with the format "1 1 /B7 /B6 /G7 /G6 /R7 /R6" 89 | byte prefix = B11000000; 90 | if ((blue & 0x80) == 0) prefix|= B00100000; 91 | if ((blue & 0x40) == 0) prefix|= B00010000; 92 | if ((green & 0x80) == 0) prefix|= B00001000; 93 | if ((green & 0x40) == 0) prefix|= B00000100; 94 | if ((red & 0x80) == 0) prefix|= B00000010; 95 | if ((red & 0x40) == 0) prefix|= B00000001; 96 | sendByte(prefix); 97 | 98 | // Now must send the 3 colors 99 | sendByte(blue); 100 | sendByte(green); 101 | sendByte(red); 102 | } 103 | 104 | void ChainableLED::setColorRGB(byte led, byte red, byte green, byte blue) 105 | { 106 | // Send data frame prefix (32x "0") 107 | sendByte(0x00); 108 | sendByte(0x00); 109 | sendByte(0x00); 110 | sendByte(0x00); 111 | 112 | // Send color data for each one of the leds 113 | for (byte i=0; i<_num_leds; i++) 114 | { 115 | if (i == led) 116 | { 117 | _led_state[i*3 + _CL_RED] = red; 118 | _led_state[i*3 + _CL_GREEN] = green; 119 | _led_state[i*3 + _CL_BLUE] = blue; 120 | } 121 | 122 | sendColor(_led_state[i*3 + _CL_RED], 123 | _led_state[i*3 + _CL_GREEN], 124 | _led_state[i*3 + _CL_BLUE]); 125 | } 126 | 127 | // Terminate data frame (32x "0") 128 | sendByte(0x00); 129 | sendByte(0x00); 130 | sendByte(0x00); 131 | sendByte(0x00); 132 | } 133 | 134 | void ChainableLED::setColorHSB(byte led, float hue, float saturation, float brightness) 135 | { 136 | float r, g, b; 137 | 138 | constrain(hue, 0.0, 1.0); 139 | constrain(saturation, 0.0, 1.0); 140 | constrain(brightness, 0.0, 1.0); 141 | 142 | if(saturation == 0.0) 143 | { 144 | r = g = b = brightness; 145 | } 146 | else 147 | { 148 | float q = brightness < 0.5 ? 149 | brightness * (1.0 + saturation) : brightness + saturation - brightness * saturation; 150 | float p = 2.0 * brightness - q; 151 | r = hue2rgb(p, q, hue + 1.0/3.0); 152 | g = hue2rgb(p, q, hue); 153 | b = hue2rgb(p, q, hue - 1.0/3.0); 154 | } 155 | 156 | setColorRGB(led, (byte)(255.0*r), (byte)(255.0*g), (byte)(255.0*b)); 157 | } 158 | 159 | // -------------------------------------------------------------------------------------- 160 | 161 | float hue2rgb(float p, float q, float t) 162 | { 163 | if (t < 0.0) 164 | t += 1.0; 165 | if(t > 1.0) 166 | t -= 1.0; 167 | if(t < 1.0/6.0) 168 | return p + (q - p) * 6.0 * t; 169 | if(t < 1.0/2.0) 170 | return q; 171 | if(t < 2.0/3.0) 172 | return p + (q - p) * (2.0/3.0 - t) * 6.0; 173 | 174 | return p; 175 | } 176 | -------------------------------------------------------------------------------- /lib/lib/ChainableLED/ChainableLED.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2012 Paulo Marques (pjp.marques@gmail.com) 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | the Software, and to permit persons to whom the Software is furnished to do so, 9 | subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | */ 21 | 22 | /* 23 | * Library for controlling a chain of RGB LEDs based on the P9813 protocol. 24 | * E.g., supports the Grove Chainable RGB LED product. 25 | * 26 | * Information about the P9813 protocol obtained from: 27 | * http://www.seeedstudio.com/wiki/index.php?title=Twig_-_Chainable_RGB_LED 28 | */ 29 | 30 | 31 | 32 | #ifndef __ChainableLED_h__ 33 | #define __ChainableLED_h__ 34 | 35 | #include "Arduino.h" 36 | 37 | #define _CL_RED 0 38 | #define _CL_GREEN 1 39 | #define _CL_BLUE 2 40 | #define _CLK_PULSE_DELAY 20 41 | 42 | class ChainableLED 43 | { 44 | public: 45 | ChainableLED(byte clk_pin, byte data_pin, byte number_of_leds); 46 | ~ChainableLED(); 47 | 48 | void init(); 49 | void setColorRGB(byte led, byte red, byte green, byte blue); 50 | void setColorHSB(byte led, float hue, float saturation, float brightness); 51 | 52 | private: 53 | byte _clk_pin; 54 | byte _data_pin; 55 | byte _num_leds; 56 | 57 | byte* _led_state; 58 | 59 | void clk(void); 60 | void sendByte(byte b); 61 | void sendColor(byte red, byte green, byte blue); 62 | }; 63 | 64 | #endif 65 | 66 | -------------------------------------------------------------------------------- /lib/lib/ChainableLED/LICENSE: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Paulo Marques (pjp.marques@gmail.com) 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | * this software and associated documentation files (the "Software"), to deal in 6 | * the Software without restriction, including without limitation the rights to 7 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | * the Software, and to permit persons to whom the Software is furnished to do so, 9 | * subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | */ 21 | -------------------------------------------------------------------------------- /lib/lib/ChainableLED/README.md: -------------------------------------------------------------------------------- 1 | ChainableLED 2 | ============ 3 | 4 | Arduino library compatible with Grove Chainable LED and the P9813 chip. It allows controlling a chain of LEDS individually. 5 | Supports both RGB and HSB color spaces for setting the color of each individual LED. 6 | 7 | [More information on the wiki](https://github.com/pjpmarques/ChainableLED/wiki) 8 | 9 | 10 | Installation 11 | ============ 12 | 1. Grab the latest version from the release section of GitHub. 13 | (https://github.com/pjpmarques/ChainableLED/releases) 14 | 15 | 2. Unzip it to your Arduino "libraries" directory. 16 | 17 | 3. It should be ready to use. Examples are included. 18 | 19 | 20 | Library Interface 21 | ================= 22 | ```c++ 23 | class ChainableLED { 24 | public: 25 | ChainableLED(byte clk_pin, byte data_pin, byte number_of_leds); 26 | 27 | void init(); 28 | void setColorRGB(byte led, byte red, byte green, byte blue); 29 | void setColorHSB(byte led, float hue, float saturation, float brightness); 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /lib/lib/ChainableLED/examples/CycleThroughColors/CycleThroughColors.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Example of using the ChainableRGB library for controlling a Grove RGB. 4 | * This code cycles through all the colors in an uniform way. This is accomplished using a HSB color space. 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define NUM_LEDS 5 11 | 12 | ChainableLED leds(7, 8, NUM_LEDS); 13 | 14 | void setup() 15 | { 16 | leds.init(); 17 | } 18 | 19 | float hue = 0.0; 20 | boolean up = true; 21 | 22 | void loop() 23 | { 24 | for (byte i=0; i=1.0 && up) 35 | up = false; 36 | else if (hue<=0.0 && !up) 37 | up = true; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /lib/lib/ChainableLED/examples/FadeInOut/FadeInOut.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Example of using the ChainableRGB library for controlling a Grove RGB. 4 | * This code fades in an out colors in a strip of leds. 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define NUM_LEDS 5 11 | 12 | ChainableLED leds(7, 8, NUM_LEDS); 13 | 14 | void setup() 15 | { 16 | leds.init(); 17 | } 18 | 19 | byte power = 0; 20 | 21 | void loop() 22 | { 23 | for (byte i=0; i 8 | 9 | #define NUM_LEDS 5 10 | 11 | ChainableLED leds(7, 8, NUM_LEDS); 12 | 13 | void setup() 14 | { 15 | leds.init(); 16 | } 17 | 18 | byte pos = 0; 19 | 20 | void loop() 21 | { 22 | for (byte i=0; i= 4) && (i%2 == 0)) { 149 | // shove each bit into the storage bytes 150 | data[j/8] <<= 1; 151 | if (counter > _count) 152 | data[j/8] |= 1; 153 | j++; 154 | } 155 | 156 | } 157 | 158 | interrupts(); 159 | 160 | /* 161 | Serial.println(j, DEC); 162 | Serial.print(data[0], HEX); Serial.print(", "); 163 | Serial.print(data[1], HEX); Serial.print(", "); 164 | Serial.print(data[2], HEX); Serial.print(", "); 165 | Serial.print(data[3], HEX); Serial.print(", "); 166 | Serial.print(data[4], HEX); Serial.print(" =? "); 167 | Serial.println(data[0] + data[1] + data[2] + data[3], HEX); 168 | */ 169 | 170 | // check we read 40 bits and that the checksum matches 171 | if ((j >= 40) && 172 | (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) { 173 | return true; 174 | } 175 | 176 | 177 | return false; 178 | 179 | } 180 | -------------------------------------------------------------------------------- /lib/lib/DHT/DHT.h: -------------------------------------------------------------------------------- 1 | #ifndef DHT_H 2 | #define DHT_H 3 | #if ARDUINO >= 100 4 | #include "Arduino.h" 5 | #else 6 | #include "WProgram.h" 7 | #endif 8 | 9 | /* DHT library 10 | 11 | MIT license 12 | written by Adafruit Industries 13 | */ 14 | 15 | // how many timing transitions we need to keep track of. 2 * number bits + extra 16 | #define MAXTIMINGS 85 17 | 18 | #define DHT11 11 19 | #define DHT22 22 20 | #define DHT21 21 21 | #define AM2301 21 22 | 23 | class DHT { 24 | private: 25 | uint8_t data[6]; 26 | uint8_t _pin, _type, _count; 27 | unsigned long _lastreadtime; 28 | boolean firstreading; 29 | 30 | public: 31 | DHT(uint8_t pin, uint8_t type, uint8_t count=6); 32 | void begin(void); 33 | float readTemperature(bool S=false); 34 | float convertCtoF(float); 35 | float convertFtoC(float); 36 | float computeHeatIndex(float tempFahrenheit, float percentHumidity); 37 | float readHumidity(void); 38 | boolean read(void); 39 | 40 | }; 41 | #endif 42 | -------------------------------------------------------------------------------- /lib/lib/DHT/README.txt: -------------------------------------------------------------------------------- 1 | This is an Arduino library for the DHT series of low cost temperature/humidity sensors. 2 | 3 | To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder DHT. Check that the DHT folder contains DHT.cpp and DHT.h. Place the DHT library folder your /libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE. -------------------------------------------------------------------------------- /lib/lib/DHT/examples/DHTtester/DHTtester.ino: -------------------------------------------------------------------------------- 1 | // Example testing sketch for various DHT humidity/temperature sensors 2 | // Written by ladyada, public domain 3 | 4 | #include "DHT.h" 5 | 6 | #define DHTPIN 2 // what pin we're connected to 7 | 8 | // Uncomment whatever type you're using! 9 | //#define DHTTYPE DHT11 // DHT 11 10 | #define DHTTYPE DHT22 // DHT 22 (AM2302) 11 | //#define DHTTYPE DHT21 // DHT 21 (AM2301) 12 | 13 | // Connect pin 1 (on the left) of the sensor to +5V 14 | // NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1 15 | // to 3.3V instead of 5V! 16 | // Connect pin 2 of the sensor to whatever your DHTPIN is 17 | // Connect pin 4 (on the right) of the sensor to GROUND 18 | // Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor 19 | 20 | // Initialize DHT sensor for normal 16mhz Arduino 21 | DHT dht(DHTPIN, DHTTYPE); 22 | // NOTE: For working with a faster chip, like an Arduino Due or Teensy, you 23 | // might need to increase the threshold for cycle counts considered a 1 or 0. 24 | // You can do this by passing a 3rd parameter for this threshold. It's a bit 25 | // of fiddling to find the right value, but in general the faster the CPU the 26 | // higher the value. The default for a 16mhz AVR is a value of 6. For an 27 | // Arduino Due that runs at 84mhz a value of 30 works. 28 | // Example to initialize DHT sensor for Arduino Due: 29 | //DHT dht(DHTPIN, DHTTYPE, 30); 30 | 31 | void setup() { 32 | Serial.begin(9600); 33 | Serial.println("DHTxx test!"); 34 | 35 | dht.begin(); 36 | } 37 | 38 | void loop() { 39 | // Wait a few seconds between measurements. 40 | delay(2000); 41 | 42 | // Reading temperature or humidity takes about 250 milliseconds! 43 | // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 44 | float h = dht.readHumidity(); 45 | // Read temperature as Celsius 46 | float t = dht.readTemperature(); 47 | // Read temperature as Fahrenheit 48 | float f = dht.readTemperature(true); 49 | 50 | // Check if any reads failed and exit early (to try again). 51 | if (isnan(h) || isnan(t) || isnan(f)) { 52 | Serial.println("Failed to read from DHT sensor!"); 53 | return; 54 | } 55 | 56 | // Compute heat index 57 | // Must send in temp in Fahrenheit! 58 | float hi = dht.computeHeatIndex(f, h); 59 | 60 | Serial.print("Humidity: "); 61 | Serial.print(h); 62 | Serial.print(" %\t"); 63 | Serial.print("Temperature: "); 64 | Serial.print(t); 65 | Serial.print(" *C "); 66 | Serial.print(f); 67 | Serial.print(" *F\t"); 68 | Serial.print("Heat index: "); 69 | Serial.print(hi); 70 | Serial.println(" *F"); 71 | } 72 | -------------------------------------------------------------------------------- /lib/lib/I2Cdev/I2Cdev.cpp: -------------------------------------------------------------------------------- 1 | // I2Cdev library collection - Main I2C device class 2 | // Abstracts bit and byte I2C R/W functions into a convenient class 3 | // 6/9/2012 by Jeff Rowberg 4 | // 5 | // Changelog: 6 | // 2013-05-06 - add Francesco Ferrara's Fastwire v0.24 implementation with small modifications 7 | // 2013-05-05 - fix issue with writing bit values to words (Sasquatch/Farzanegan) 8 | // 2012-06-09 - fix major issue with reading > 32 bytes at a time with Arduino Wire 9 | // - add compiler warnings when using outdated or IDE or limited I2Cdev implementation 10 | // 2011-11-01 - fix write*Bits mask calculation (thanks sasquatch @ Arduino forums) 11 | // 2011-10-03 - added automatic Arduino version detection for ease of use 12 | // 2011-10-02 - added Gene Knight's NBWire TwoWire class implementation with small modifications 13 | // 2011-08-31 - added support for Arduino 1.0 Wire library (methods are different from 0.x) 14 | // 2011-08-03 - added optional timeout parameter to read* methods to easily change from default 15 | // 2011-08-02 - added support for 16-bit registers 16 | // - fixed incorrect Doxygen comments on some methods 17 | // - added timeout value for read operations (thanks mem @ Arduino forums) 18 | // 2011-07-30 - changed read/write function structures to return success or byte counts 19 | // - made all methods static for multi-device memory savings 20 | // 2011-07-28 - initial release 21 | 22 | /* ============================================ 23 | I2Cdev device library code is placed under the MIT license 24 | Copyright (c) 2013 Jeff Rowberg 25 | 26 | Permission is hereby granted, free of charge, to any person obtaining a copy 27 | of this software and associated documentation files (the "Software"), to deal 28 | in the Software without restriction, including without limitation the rights 29 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 30 | copies of the Software, and to permit persons to whom the Software is 31 | furnished to do so, subject to the following conditions: 32 | 33 | The above copyright notice and this permission notice shall be included in 34 | all copies or substantial portions of the Software. 35 | 36 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 37 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 38 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 39 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 40 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 41 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 42 | THE SOFTWARE. 43 | =============================================== 44 | */ 45 | 46 | #include "I2Cdev.h" 47 | 48 | #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE 49 | 50 | #ifdef I2CDEV_IMPLEMENTATION_WARNINGS 51 | #if ARDUINO < 100 52 | #warning Using outdated Arduino IDE with Wire library is functionally limiting. 53 | #warning Arduino IDE v1.0.1+ with I2Cdev Fastwire implementation is recommended. 54 | #warning This I2Cdev implementation does not support: 55 | #warning - Repeated starts conditions 56 | #warning - Timeout detection (some Wire requests block forever) 57 | #elif ARDUINO == 100 58 | #warning Using outdated Arduino IDE with Wire library is functionally limiting. 59 | #warning Arduino IDE v1.0.1+ with I2Cdev Fastwire implementation is recommended. 60 | #warning This I2Cdev implementation does not support: 61 | #warning - Repeated starts conditions 62 | #warning - Timeout detection (some Wire requests block forever) 63 | #elif ARDUINO > 100 64 | #warning Using current Arduino IDE with Wire library is functionally limiting. 65 | #warning Arduino IDE v1.0.1+ with I2CDEV_BUILTIN_FASTWIRE implementation is recommended. 66 | #warning This I2Cdev implementation does not support: 67 | #warning - Timeout detection (some Wire requests block forever) 68 | #endif 69 | #endif 70 | 71 | #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE 72 | 73 | //#error The I2CDEV_BUILTIN_FASTWIRE implementation is known to be broken right now. Patience, Iago! 74 | 75 | #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE 76 | 77 | #ifdef I2CDEV_IMPLEMENTATION_WARNINGS 78 | #warning Using I2CDEV_BUILTIN_NBWIRE implementation may adversely affect interrupt detection. 79 | #warning This I2Cdev implementation does not support: 80 | #warning - Repeated starts conditions 81 | #endif 82 | 83 | // NBWire implementation based heavily on code by Gene Knight 84 | // Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html 85 | // Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html 86 | TwoWire Wire; 87 | 88 | #endif 89 | 90 | /** Default constructor. 91 | */ 92 | I2Cdev::I2Cdev() { 93 | } 94 | 95 | /** Read a single bit from an 8-bit device register. 96 | * @param devAddr I2C slave device address 97 | * @param regAddr Register regAddr to read from 98 | * @param bitNum Bit position to read (0-7) 99 | * @param data Container for single bit value 100 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 101 | * @return Status of read operation (true = success) 102 | */ 103 | int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout) { 104 | uint8_t b; 105 | uint8_t count = readByte(devAddr, regAddr, &b, timeout); 106 | *data = b & (1 << bitNum); 107 | return count; 108 | } 109 | 110 | /** Read a single bit from a 16-bit device register. 111 | * @param devAddr I2C slave device address 112 | * @param regAddr Register regAddr to read from 113 | * @param bitNum Bit position to read (0-15) 114 | * @param data Container for single bit value 115 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 116 | * @return Status of read operation (true = success) 117 | */ 118 | int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout) { 119 | uint16_t b; 120 | uint8_t count = readWord(devAddr, regAddr, &b, timeout); 121 | *data = b & (1 << bitNum); 122 | return count; 123 | } 124 | 125 | /** Read multiple bits from an 8-bit device register. 126 | * @param devAddr I2C slave device address 127 | * @param regAddr Register regAddr to read from 128 | * @param bitStart First bit position to read (0-7) 129 | * @param length Number of bits to read (not more than 8) 130 | * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) 131 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 132 | * @return Status of read operation (true = success) 133 | */ 134 | int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout) { 135 | // 01101001 read byte 136 | // 76543210 bit numbers 137 | // xxx args: bitStart=4, length=3 138 | // 010 masked 139 | // -> 010 shifted 140 | uint8_t count, b; 141 | if ((count = readByte(devAddr, regAddr, &b, timeout)) != 0) { 142 | uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); 143 | b &= mask; 144 | b >>= (bitStart - length + 1); 145 | *data = b; 146 | } 147 | return count; 148 | } 149 | 150 | /** Read multiple bits from a 16-bit device register. 151 | * @param devAddr I2C slave device address 152 | * @param regAddr Register regAddr to read from 153 | * @param bitStart First bit position to read (0-15) 154 | * @param length Number of bits to read (not more than 16) 155 | * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) 156 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 157 | * @return Status of read operation (1 = success, 0 = failure, -1 = timeout) 158 | */ 159 | int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout) { 160 | // 1101011001101001 read byte 161 | // fedcba9876543210 bit numbers 162 | // xxx args: bitStart=12, length=3 163 | // 010 masked 164 | // -> 010 shifted 165 | uint8_t count; 166 | uint16_t w; 167 | if ((count = readWord(devAddr, regAddr, &w, timeout)) != 0) { 168 | uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1); 169 | w &= mask; 170 | w >>= (bitStart - length + 1); 171 | *data = w; 172 | } 173 | return count; 174 | } 175 | 176 | /** Read single byte from an 8-bit device register. 177 | * @param devAddr I2C slave device address 178 | * @param regAddr Register regAddr to read from 179 | * @param data Container for byte value read from device 180 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 181 | * @return Status of read operation (true = success) 182 | */ 183 | int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout) { 184 | return readBytes(devAddr, regAddr, 1, data, timeout); 185 | } 186 | 187 | /** Read single word from a 16-bit device register. 188 | * @param devAddr I2C slave device address 189 | * @param regAddr Register regAddr to read from 190 | * @param data Container for word value read from device 191 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 192 | * @return Status of read operation (true = success) 193 | */ 194 | int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout) { 195 | return readWords(devAddr, regAddr, 1, data, timeout); 196 | } 197 | 198 | /** Read multiple bytes from an 8-bit device register. 199 | * @param devAddr I2C slave device address 200 | * @param regAddr First register regAddr to read from 201 | * @param length Number of bytes to read 202 | * @param data Buffer to store read data in 203 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 204 | * @return Number of bytes read (-1 indicates failure) 205 | */ 206 | int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout) { 207 | #ifdef I2CDEV_SERIAL_DEBUG 208 | Serial.print("I2C (0x"); 209 | Serial.print(devAddr, HEX); 210 | Serial.print(") reading "); 211 | Serial.print(length, DEC); 212 | Serial.print(" bytes from 0x"); 213 | Serial.print(regAddr, HEX); 214 | Serial.print("..."); 215 | #endif 216 | 217 | int8_t count = 0; 218 | uint32_t t1 = millis(); 219 | 220 | #if (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE) 221 | 222 | #if (ARDUINO < 100) 223 | // Arduino v00xx (before v1.0), Wire library 224 | 225 | // I2C/TWI subsystem uses internal buffer that breaks with large data requests 226 | // so if user requests more than BUFFER_LENGTH bytes, we have to do it in 227 | // smaller chunks instead of all at once 228 | for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) { 229 | Wire.beginTransmission(devAddr); 230 | Wire.send(regAddr); 231 | Wire.endTransmission(); 232 | Wire.beginTransmission(devAddr); 233 | Wire.requestFrom(devAddr, (uint8_t)min(length - k, BUFFER_LENGTH)); 234 | 235 | for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) { 236 | data[count] = Wire.receive(); 237 | #ifdef I2CDEV_SERIAL_DEBUG 238 | Serial.print(data[count], HEX); 239 | if (count + 1 < length) Serial.print(" "); 240 | #endif 241 | } 242 | 243 | Wire.endTransmission(); 244 | } 245 | #elif (ARDUINO == 100) 246 | // Arduino v1.0.0, Wire library 247 | // Adds standardized write() and read() stream methods instead of send() and receive() 248 | 249 | // I2C/TWI subsystem uses internal buffer that breaks with large data requests 250 | // so if user requests more than BUFFER_LENGTH bytes, we have to do it in 251 | // smaller chunks instead of all at once 252 | for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) { 253 | Wire.beginTransmission(devAddr); 254 | Wire.write(regAddr); 255 | Wire.endTransmission(); 256 | Wire.beginTransmission(devAddr); 257 | Wire.requestFrom(devAddr, (uint8_t)min(length - k, BUFFER_LENGTH)); 258 | 259 | for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) { 260 | data[count] = Wire.read(); 261 | #ifdef I2CDEV_SERIAL_DEBUG 262 | Serial.print(data[count], HEX); 263 | if (count + 1 < length) Serial.print(" "); 264 | #endif 265 | } 266 | 267 | Wire.endTransmission(); 268 | } 269 | #elif (ARDUINO > 100) 270 | // Arduino v1.0.1+, Wire library 271 | // Adds official support for repeated start condition, yay! 272 | 273 | // I2C/TWI subsystem uses internal buffer that breaks with large data requests 274 | // so if user requests more than BUFFER_LENGTH bytes, we have to do it in 275 | // smaller chunks instead of all at once 276 | for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) { 277 | Wire.beginTransmission(devAddr); 278 | Wire.write(regAddr); 279 | Wire.endTransmission(); 280 | Wire.beginTransmission(devAddr); 281 | Wire.requestFrom(devAddr, (uint8_t)min(length - k, BUFFER_LENGTH)); 282 | 283 | for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) { 284 | data[count] = Wire.read(); 285 | #ifdef I2CDEV_SERIAL_DEBUG 286 | Serial.print(data[count], HEX); 287 | if (count + 1 < length) Serial.print(" "); 288 | #endif 289 | } 290 | } 291 | #endif 292 | 293 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) 294 | 295 | // Fastwire library 296 | // no loop required for fastwire 297 | uint8_t status = Fastwire::readBuf(devAddr << 1, regAddr, data, length); 298 | if (status == 0) { 299 | count = length; // success 300 | } else { 301 | count = -1; // error 302 | } 303 | 304 | #endif 305 | 306 | // check for timeout 307 | if (timeout > 0 && millis() - t1 >= timeout && count < length) count = -1; // timeout 308 | 309 | #ifdef I2CDEV_SERIAL_DEBUG 310 | Serial.print(". Done ("); 311 | Serial.print(count, DEC); 312 | Serial.println(" read)."); 313 | #endif 314 | 315 | return count; 316 | } 317 | 318 | /** Read multiple words from a 16-bit device register. 319 | * @param devAddr I2C slave device address 320 | * @param regAddr First register regAddr to read from 321 | * @param length Number of words to read 322 | * @param data Buffer to store read data in 323 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) 324 | * @return Number of words read (-1 indicates failure) 325 | */ 326 | int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout) { 327 | #ifdef I2CDEV_SERIAL_DEBUG 328 | Serial.print("I2C (0x"); 329 | Serial.print(devAddr, HEX); 330 | Serial.print(") reading "); 331 | Serial.print(length, DEC); 332 | Serial.print(" words from 0x"); 333 | Serial.print(regAddr, HEX); 334 | Serial.print("..."); 335 | #endif 336 | 337 | int8_t count = 0; 338 | uint32_t t1 = millis(); 339 | 340 | #if (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE) 341 | 342 | #if (ARDUINO < 100) 343 | // Arduino v00xx (before v1.0), Wire library 344 | 345 | // I2C/TWI subsystem uses internal buffer that breaks with large data requests 346 | // so if user requests more than BUFFER_LENGTH bytes, we have to do it in 347 | // smaller chunks instead of all at once 348 | for (uint8_t k = 0; k < length * 2; k += min(length * 2, BUFFER_LENGTH)) { 349 | Wire.beginTransmission(devAddr); 350 | Wire.send(regAddr); 351 | Wire.endTransmission(); 352 | Wire.beginTransmission(devAddr); 353 | Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes 354 | 355 | bool msb = true; // starts with MSB, then LSB 356 | for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) { 357 | if (msb) { 358 | // first byte is bits 15-8 (MSb=15) 359 | data[count] = Wire.receive() << 8; 360 | } else { 361 | // second byte is bits 7-0 (LSb=0) 362 | data[count] |= Wire.receive(); 363 | #ifdef I2CDEV_SERIAL_DEBUG 364 | Serial.print(data[count], HEX); 365 | if (count + 1 < length) Serial.print(" "); 366 | #endif 367 | count++; 368 | } 369 | msb = !msb; 370 | } 371 | 372 | Wire.endTransmission(); 373 | } 374 | #elif (ARDUINO == 100) 375 | // Arduino v1.0.0, Wire library 376 | // Adds standardized write() and read() stream methods instead of send() and receive() 377 | 378 | // I2C/TWI subsystem uses internal buffer that breaks with large data requests 379 | // so if user requests more than BUFFER_LENGTH bytes, we have to do it in 380 | // smaller chunks instead of all at once 381 | for (uint8_t k = 0; k < length * 2; k += min(length * 2, BUFFER_LENGTH)) { 382 | Wire.beginTransmission(devAddr); 383 | Wire.write(regAddr); 384 | Wire.endTransmission(); 385 | Wire.beginTransmission(devAddr); 386 | Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes 387 | 388 | bool msb = true; // starts with MSB, then LSB 389 | for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) { 390 | if (msb) { 391 | // first byte is bits 15-8 (MSb=15) 392 | data[count] = Wire.read() << 8; 393 | } else { 394 | // second byte is bits 7-0 (LSb=0) 395 | data[count] |= Wire.read(); 396 | #ifdef I2CDEV_SERIAL_DEBUG 397 | Serial.print(data[count], HEX); 398 | if (count + 1 < length) Serial.print(" "); 399 | #endif 400 | count++; 401 | } 402 | msb = !msb; 403 | } 404 | 405 | Wire.endTransmission(); 406 | } 407 | #elif (ARDUINO > 100) 408 | // Arduino v1.0.1+, Wire library 409 | // Adds official support for repeated start condition, yay! 410 | 411 | // I2C/TWI subsystem uses internal buffer that breaks with large data requests 412 | // so if user requests more than BUFFER_LENGTH bytes, we have to do it in 413 | // smaller chunks instead of all at once 414 | for (uint8_t k = 0; k < length * 2; k += min(length * 2, BUFFER_LENGTH)) { 415 | Wire.beginTransmission(devAddr); 416 | Wire.write(regAddr); 417 | Wire.endTransmission(); 418 | Wire.beginTransmission(devAddr); 419 | Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes 420 | 421 | bool msb = true; // starts with MSB, then LSB 422 | for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) { 423 | if (msb) { 424 | // first byte is bits 15-8 (MSb=15) 425 | data[count] = Wire.read() << 8; 426 | } else { 427 | // second byte is bits 7-0 (LSb=0) 428 | data[count] |= Wire.read(); 429 | #ifdef I2CDEV_SERIAL_DEBUG 430 | Serial.print(data[count], HEX); 431 | if (count + 1 < length) Serial.print(" "); 432 | #endif 433 | count++; 434 | } 435 | msb = !msb; 436 | } 437 | 438 | Wire.endTransmission(); 439 | } 440 | #endif 441 | 442 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) 443 | 444 | // Fastwire library 445 | // no loop required for fastwire 446 | uint16_t intermediate[(uint8_t)length]; 447 | uint8_t status = Fastwire::readBuf(devAddr << 1, regAddr, (uint8_t *)intermediate, (uint8_t)(length * 2)); 448 | if (status == 0) { 449 | count = length; // success 450 | for (uint8_t i = 0; i < length; i++) { 451 | data[i] = (intermediate[2*i] << 8) | intermediate[2*i + 1]; 452 | } 453 | } else { 454 | count = -1; // error 455 | } 456 | 457 | #endif 458 | 459 | if (timeout > 0 && millis() - t1 >= timeout && count < length) count = -1; // timeout 460 | 461 | #ifdef I2CDEV_SERIAL_DEBUG 462 | Serial.print(". Done ("); 463 | Serial.print(count, DEC); 464 | Serial.println(" read)."); 465 | #endif 466 | 467 | return count; 468 | } 469 | 470 | /** write a single bit in an 8-bit device register. 471 | * @param devAddr I2C slave device address 472 | * @param regAddr Register regAddr to write to 473 | * @param bitNum Bit position to write (0-7) 474 | * @param value New bit value to write 475 | * @return Status of operation (true = success) 476 | */ 477 | bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) { 478 | uint8_t b; 479 | readByte(devAddr, regAddr, &b); 480 | b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum)); 481 | return writeByte(devAddr, regAddr, b); 482 | } 483 | 484 | /** write a single bit in a 16-bit device register. 485 | * @param devAddr I2C slave device address 486 | * @param regAddr Register regAddr to write to 487 | * @param bitNum Bit position to write (0-15) 488 | * @param value New bit value to write 489 | * @return Status of operation (true = success) 490 | */ 491 | bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data) { 492 | uint16_t w; 493 | readWord(devAddr, regAddr, &w); 494 | w = (data != 0) ? (w | (1 << bitNum)) : (w & ~(1 << bitNum)); 495 | return writeWord(devAddr, regAddr, w); 496 | } 497 | 498 | /** Write multiple bits in an 8-bit device register. 499 | * @param devAddr I2C slave device address 500 | * @param regAddr Register regAddr to write to 501 | * @param bitStart First bit position to write (0-7) 502 | * @param length Number of bits to write (not more than 8) 503 | * @param data Right-aligned value to write 504 | * @return Status of operation (true = success) 505 | */ 506 | bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data) { 507 | // 010 value to write 508 | // 76543210 bit numbers 509 | // xxx args: bitStart=4, length=3 510 | // 00011100 mask byte 511 | // 10101111 original value (sample) 512 | // 10100011 original & ~mask 513 | // 10101011 masked | value 514 | uint8_t b; 515 | if (readByte(devAddr, regAddr, &b) != 0) { 516 | uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); 517 | data <<= (bitStart - length + 1); // shift data into correct position 518 | data &= mask; // zero all non-important bits in data 519 | b &= ~(mask); // zero all important bits in existing byte 520 | b |= data; // combine data with existing byte 521 | return writeByte(devAddr, regAddr, b); 522 | } else { 523 | return false; 524 | } 525 | } 526 | 527 | /** Write multiple bits in a 16-bit device register. 528 | * @param devAddr I2C slave device address 529 | * @param regAddr Register regAddr to write to 530 | * @param bitStart First bit position to write (0-15) 531 | * @param length Number of bits to write (not more than 16) 532 | * @param data Right-aligned value to write 533 | * @return Status of operation (true = success) 534 | */ 535 | bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data) { 536 | // 010 value to write 537 | // fedcba9876543210 bit numbers 538 | // xxx args: bitStart=12, length=3 539 | // 0001110000000000 mask word 540 | // 1010111110010110 original value (sample) 541 | // 1010001110010110 original & ~mask 542 | // 1010101110010110 masked | value 543 | uint16_t w; 544 | if (readWord(devAddr, regAddr, &w) != 0) { 545 | uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1); 546 | data <<= (bitStart - length + 1); // shift data into correct position 547 | data &= mask; // zero all non-important bits in data 548 | w &= ~(mask); // zero all important bits in existing word 549 | w |= data; // combine data with existing word 550 | return writeWord(devAddr, regAddr, w); 551 | } else { 552 | return false; 553 | } 554 | } 555 | 556 | /** Write single byte to an 8-bit device register. 557 | * @param devAddr I2C slave device address 558 | * @param regAddr Register address to write to 559 | * @param data New byte value to write 560 | * @return Status of operation (true = success) 561 | */ 562 | bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) { 563 | return writeBytes(devAddr, regAddr, 1, &data); 564 | } 565 | 566 | /** Write single word to a 16-bit device register. 567 | * @param devAddr I2C slave device address 568 | * @param regAddr Register address to write to 569 | * @param data New word value to write 570 | * @return Status of operation (true = success) 571 | */ 572 | bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) { 573 | return writeWords(devAddr, regAddr, 1, &data); 574 | } 575 | 576 | /** Write multiple bytes to an 8-bit device register. 577 | * @param devAddr I2C slave device address 578 | * @param regAddr First register address to write to 579 | * @param length Number of bytes to write 580 | * @param data Buffer to copy new data from 581 | * @return Status of operation (true = success) 582 | */ 583 | bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t* data) { 584 | #ifdef I2CDEV_SERIAL_DEBUG 585 | Serial.print("I2C (0x"); 586 | Serial.print(devAddr, HEX); 587 | Serial.print(") writing "); 588 | Serial.print(length, DEC); 589 | Serial.print(" bytes to 0x"); 590 | Serial.print(regAddr, HEX); 591 | Serial.print("..."); 592 | #endif 593 | uint8_t status = 0; 594 | #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) 595 | Wire.beginTransmission(devAddr); 596 | Wire.send((uint8_t) regAddr); // send address 597 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) 598 | Wire.beginTransmission(devAddr); 599 | Wire.write((uint8_t) regAddr); // send address 600 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) 601 | Fastwire::beginTransmission(devAddr); 602 | Fastwire::write(regAddr); 603 | #endif 604 | for (uint8_t i = 0; i < length; i++) { 605 | #ifdef I2CDEV_SERIAL_DEBUG 606 | Serial.print(data[i], HEX); 607 | if (i + 1 < length) Serial.print(" "); 608 | #endif 609 | #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) 610 | Wire.send((uint8_t) data[i]); 611 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) 612 | Wire.write((uint8_t) data[i]); 613 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) 614 | Fastwire::write((uint8_t) data[i]); 615 | #endif 616 | } 617 | #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) 618 | Wire.endTransmission(); 619 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) 620 | status = Wire.endTransmission(); 621 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) 622 | Fastwire::stop(); 623 | //status = Fastwire::endTransmission(); 624 | #endif 625 | #ifdef I2CDEV_SERIAL_DEBUG 626 | Serial.println(". Done."); 627 | #endif 628 | return status == 0; 629 | } 630 | 631 | /** Write multiple words to a 16-bit device register. 632 | * @param devAddr I2C slave device address 633 | * @param regAddr First register address to write to 634 | * @param length Number of words to write 635 | * @param data Buffer to copy new data from 636 | * @return Status of operation (true = success) 637 | */ 638 | bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t* data) { 639 | #ifdef I2CDEV_SERIAL_DEBUG 640 | Serial.print("I2C (0x"); 641 | Serial.print(devAddr, HEX); 642 | Serial.print(") writing "); 643 | Serial.print(length, DEC); 644 | Serial.print(" words to 0x"); 645 | Serial.print(regAddr, HEX); 646 | Serial.print("..."); 647 | #endif 648 | uint8_t status = 0; 649 | #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) 650 | Wire.beginTransmission(devAddr); 651 | Wire.send(regAddr); // send address 652 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) 653 | Wire.beginTransmission(devAddr); 654 | Wire.write(regAddr); // send address 655 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) 656 | Fastwire::beginTransmission(devAddr); 657 | Fastwire::write(regAddr); 658 | #endif 659 | for (uint8_t i = 0; i < length * 2; i++) { 660 | #ifdef I2CDEV_SERIAL_DEBUG 661 | Serial.print(data[i], HEX); 662 | if (i + 1 < length) Serial.print(" "); 663 | #endif 664 | #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) 665 | Wire.send((uint8_t)(data[i] >> 8)); // send MSB 666 | Wire.send((uint8_t)data[i++]); // send LSB 667 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) 668 | Wire.write((uint8_t)(data[i] >> 8)); // send MSB 669 | Wire.write((uint8_t)data[i++]); // send LSB 670 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) 671 | Fastwire::write((uint8_t)(data[i] >> 8)); // send MSB 672 | status = Fastwire::write((uint8_t)data[i++]); // send LSB 673 | if (status != 0) break; 674 | #endif 675 | } 676 | #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) 677 | Wire.endTransmission(); 678 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) 679 | status = Wire.endTransmission(); 680 | #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) 681 | Fastwire::stop(); 682 | //status = Fastwire::endTransmission(); 683 | #endif 684 | #ifdef I2CDEV_SERIAL_DEBUG 685 | Serial.println(". Done."); 686 | #endif 687 | return status == 0; 688 | } 689 | 690 | /** Default timeout value for read operations. 691 | * Set this to 0 to disable timeout detection. 692 | */ 693 | uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT; 694 | 695 | #if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE 696 | // I2C library 697 | ////////////////////// 698 | // Copyright(C) 2012 699 | // Francesco Ferrara 700 | // ferrara[at]libero[point]it 701 | ////////////////////// 702 | 703 | /* 704 | FastWire 705 | - 0.24 added stop 706 | - 0.23 added reset 707 | 708 | This is a library to help faster programs to read I2C devices. 709 | Copyright(C) 2012 Francesco Ferrara 710 | occhiobello at gmail dot com 711 | [used by Jeff Rowberg for I2Cdevlib with permission] 712 | */ 713 | 714 | boolean Fastwire::waitInt() { 715 | int l = 250; 716 | while (!(TWCR & (1 << TWINT)) && l-- > 0); 717 | return l > 0; 718 | } 719 | 720 | void Fastwire::setup(int khz, boolean pullup) { 721 | TWCR = 0; 722 | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__) 723 | // activate internal pull-ups for twi (PORTC bits 4 & 5) 724 | // as per note from atmega8 manual pg167 725 | if (pullup) PORTC |= ((1 << 4) | (1 << 5)); 726 | else PORTC &= ~((1 << 4) | (1 << 5)); 727 | #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) 728 | // activate internal pull-ups for twi (PORTC bits 0 & 1) 729 | if (pullup) PORTC |= ((1 << 0) | (1 << 1)); 730 | else PORTC &= ~((1 << 0) | (1 << 1)); 731 | #else 732 | // activate internal pull-ups for twi (PORTD bits 0 & 1) 733 | // as per note from atmega128 manual pg204 734 | if (pullup) PORTD |= ((1 << 0) | (1 << 1)); 735 | else PORTD &= ~((1 << 0) | (1 << 1)); 736 | #endif 737 | 738 | TWSR = 0; // no prescaler => prescaler = 1 739 | TWBR = ((16000L / khz) - 16) / 2; // change the I2C clock rate 740 | TWCR = 1 << TWEN; // enable twi module, no interrupt 741 | } 742 | 743 | // added by Jeff Rowberg 2013-05-07: 744 | // Arduino Wire-style "beginTransmission" function 745 | // (takes 7-bit device address like the Wire method, NOT 8-bit: 0x68, not 0xD0/0xD1) 746 | byte Fastwire::beginTransmission(byte device) { 747 | byte twst, retry; 748 | retry = 2; 749 | do { 750 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA); 751 | if (!waitInt()) return 1; 752 | twst = TWSR & 0xF8; 753 | if (twst != TW_START && twst != TW_REP_START) return 2; 754 | 755 | //Serial.print(device, HEX); 756 | //Serial.print(" "); 757 | TWDR = device << 1; // send device address without read bit (1) 758 | TWCR = (1 << TWINT) | (1 << TWEN); 759 | if (!waitInt()) return 3; 760 | twst = TWSR & 0xF8; 761 | } while (twst == TW_MT_SLA_NACK && retry-- > 0); 762 | if (twst != TW_MT_SLA_ACK) return 4; 763 | return 0; 764 | } 765 | 766 | byte Fastwire::writeBuf(byte device, byte address, byte *data, byte num) { 767 | byte twst, retry; 768 | 769 | retry = 2; 770 | do { 771 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA); 772 | if (!waitInt()) return 1; 773 | twst = TWSR & 0xF8; 774 | if (twst != TW_START && twst != TW_REP_START) return 2; 775 | 776 | //Serial.print(device, HEX); 777 | //Serial.print(" "); 778 | TWDR = device & 0xFE; // send device address without read bit (1) 779 | TWCR = (1 << TWINT) | (1 << TWEN); 780 | if (!waitInt()) return 3; 781 | twst = TWSR & 0xF8; 782 | } while (twst == TW_MT_SLA_NACK && retry-- > 0); 783 | if (twst != TW_MT_SLA_ACK) return 4; 784 | 785 | //Serial.print(address, HEX); 786 | //Serial.print(" "); 787 | TWDR = address; // send data to the previously addressed device 788 | TWCR = (1 << TWINT) | (1 << TWEN); 789 | if (!waitInt()) return 5; 790 | twst = TWSR & 0xF8; 791 | if (twst != TW_MT_DATA_ACK) return 6; 792 | 793 | for (byte i = 0; i < num; i++) { 794 | //Serial.print(data[i], HEX); 795 | //Serial.print(" "); 796 | TWDR = data[i]; // send data to the previously addressed device 797 | TWCR = (1 << TWINT) | (1 << TWEN); 798 | if (!waitInt()) return 7; 799 | twst = TWSR & 0xF8; 800 | if (twst != TW_MT_DATA_ACK) return 8; 801 | } 802 | //Serial.print("\n"); 803 | 804 | return 0; 805 | } 806 | 807 | byte Fastwire::write(byte value) { 808 | byte twst; 809 | //Serial.println(value, HEX); 810 | TWDR = value; // send data 811 | TWCR = (1 << TWINT) | (1 << TWEN); 812 | if (!waitInt()) return 1; 813 | twst = TWSR & 0xF8; 814 | if (twst != TW_MT_DATA_ACK) return 2; 815 | return 0; 816 | } 817 | 818 | byte Fastwire::readBuf(byte device, byte address, byte *data, byte num) { 819 | byte twst, retry; 820 | 821 | retry = 2; 822 | do { 823 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA); 824 | if (!waitInt()) return 16; 825 | twst = TWSR & 0xF8; 826 | if (twst != TW_START && twst != TW_REP_START) return 17; 827 | 828 | //Serial.print(device, HEX); 829 | //Serial.print(" "); 830 | TWDR = device & 0xfe; // send device address to write 831 | TWCR = (1 << TWINT) | (1 << TWEN); 832 | if (!waitInt()) return 18; 833 | twst = TWSR & 0xF8; 834 | } while (twst == TW_MT_SLA_NACK && retry-- > 0); 835 | if (twst != TW_MT_SLA_ACK) return 19; 836 | 837 | //Serial.print(address, HEX); 838 | //Serial.print(" "); 839 | TWDR = address; // send data to the previously addressed device 840 | TWCR = (1 << TWINT) | (1 << TWEN); 841 | if (!waitInt()) return 20; 842 | twst = TWSR & 0xF8; 843 | if (twst != TW_MT_DATA_ACK) return 21; 844 | 845 | /***/ 846 | 847 | retry = 2; 848 | do { 849 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA); 850 | if (!waitInt()) return 22; 851 | twst = TWSR & 0xF8; 852 | if (twst != TW_START && twst != TW_REP_START) return 23; 853 | 854 | //Serial.print(device, HEX); 855 | //Serial.print(" "); 856 | TWDR = device | 0x01; // send device address with the read bit (1) 857 | TWCR = (1 << TWINT) | (1 << TWEN); 858 | if (!waitInt()) return 24; 859 | twst = TWSR & 0xF8; 860 | } while (twst == TW_MR_SLA_NACK && retry-- > 0); 861 | if (twst != TW_MR_SLA_ACK) return 25; 862 | 863 | for (uint8_t i = 0; i < num; i++) { 864 | if (i == num - 1) 865 | TWCR = (1 << TWINT) | (1 << TWEN); 866 | else 867 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); 868 | if (!waitInt()) return 26; 869 | twst = TWSR & 0xF8; 870 | if (twst != TW_MR_DATA_ACK && twst != TW_MR_DATA_NACK) return twst; 871 | data[i] = TWDR; 872 | //Serial.print(data[i], HEX); 873 | //Serial.print(" "); 874 | } 875 | //Serial.print("\n"); 876 | stop(); 877 | 878 | return 0; 879 | } 880 | 881 | void Fastwire::reset() { 882 | TWCR = 0; 883 | } 884 | 885 | byte Fastwire::stop() { 886 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); 887 | if (!waitInt()) return 1; 888 | return 0; 889 | } 890 | #endif 891 | 892 | #if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE 893 | // NBWire implementation based heavily on code by Gene Knight 894 | // Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html 895 | // Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html 896 | 897 | /* 898 | call this version 1.0 899 | 900 | Offhand, the only funky part that I can think of is in nbrequestFrom, where the buffer 901 | length and index are set *before* the data is actually read. The problem is that these 902 | are variables local to the TwoWire object, and by the time we actually have read the 903 | data, and know what the length actually is, we have no simple access to the object's 904 | variables. The actual bytes read *is* given to the callback function, though. 905 | 906 | The ISR code for a slave receiver is commented out. I don't have that setup, and can't 907 | verify it at this time. Save it for 2.0! 908 | 909 | The handling of the read and write processes here is much like in the demo sketch code: 910 | the process is broken down into sequential functions, where each registers the next as a 911 | callback, essentially. 912 | 913 | For example, for the Read process, twi_read00 just returns if TWI is not yet in a 914 | ready state. When there's another interrupt, and the interface *is* ready, then it 915 | sets up the read, starts it, and registers twi_read01 as the function to call after 916 | the *next* interrupt. twi_read01, then, just returns if the interface is still in a 917 | "reading" state. When the reading is done, it copies the information to the buffer, 918 | cleans up, and calls the user-requested callback function with the actual number of 919 | bytes read. 920 | 921 | The writing is similar. 922 | 923 | Questions, comments and problems can go to Gene@Telobot.com. 924 | 925 | Thumbs Up! 926 | Gene Knight 927 | 928 | */ 929 | 930 | uint8_t TwoWire::rxBuffer[NBWIRE_BUFFER_LENGTH]; 931 | uint8_t TwoWire::rxBufferIndex = 0; 932 | uint8_t TwoWire::rxBufferLength = 0; 933 | 934 | uint8_t TwoWire::txAddress = 0; 935 | uint8_t TwoWire::txBuffer[NBWIRE_BUFFER_LENGTH]; 936 | uint8_t TwoWire::txBufferIndex = 0; 937 | uint8_t TwoWire::txBufferLength = 0; 938 | 939 | //uint8_t TwoWire::transmitting = 0; 940 | void (*TwoWire::user_onRequest)(void); 941 | void (*TwoWire::user_onReceive)(int); 942 | 943 | static volatile uint8_t twi_transmitting; 944 | static volatile uint8_t twi_state; 945 | static uint8_t twi_slarw; 946 | static volatile uint8_t twi_error; 947 | static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; 948 | static volatile uint8_t twi_masterBufferIndex; 949 | static uint8_t twi_masterBufferLength; 950 | static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; 951 | static volatile uint8_t twi_rxBufferIndex; 952 | //static volatile uint8_t twi_Interrupt_Continue_Command; 953 | static volatile uint8_t twi_Return_Value; 954 | static volatile uint8_t twi_Done; 955 | void (*twi_cbendTransmissionDone)(int); 956 | void (*twi_cbreadFromDone)(int); 957 | 958 | void twi_init() { 959 | // initialize state 960 | twi_state = TWI_READY; 961 | 962 | // activate internal pull-ups for twi 963 | // as per note from atmega8 manual pg167 964 | sbi(PORTC, 4); 965 | sbi(PORTC, 5); 966 | 967 | // initialize twi prescaler and bit rate 968 | cbi(TWSR, TWPS0); // TWI Status Register - Prescaler bits 969 | cbi(TWSR, TWPS1); 970 | 971 | /* twi bit rate formula from atmega128 manual pg 204 972 | SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) 973 | note: TWBR should be 10 or higher for master mode 974 | It is 72 for a 16mhz Wiring board with 100kHz TWI */ 975 | 976 | TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2; // bitrate register 977 | // enable twi module, acks, and twi interrupt 978 | 979 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); 980 | 981 | /* TWEN - TWI Enable Bit 982 | TWIE - TWI Interrupt Enable 983 | TWEA - TWI Enable Acknowledge Bit 984 | TWINT - TWI Interrupt Flag 985 | TWSTA - TWI Start Condition 986 | */ 987 | } 988 | 989 | typedef struct { 990 | uint8_t address; 991 | uint8_t* data; 992 | uint8_t length; 993 | uint8_t wait; 994 | uint8_t i; 995 | } twi_Write_Vars; 996 | 997 | twi_Write_Vars *ptwv = 0; 998 | static void (*fNextInterruptFunction)(void) = 0; 999 | 1000 | void twi_Finish(byte bRetVal) { 1001 | if (ptwv) { 1002 | free(ptwv); 1003 | ptwv = 0; 1004 | } 1005 | twi_Done = 0xFF; 1006 | twi_Return_Value = bRetVal; 1007 | fNextInterruptFunction = 0; 1008 | } 1009 | 1010 | uint8_t twii_WaitForDone(uint16_t timeout) { 1011 | uint32_t endMillis = millis() + timeout; 1012 | while (!twi_Done && (timeout == 0 || millis() < endMillis)) continue; 1013 | return twi_Return_Value; 1014 | } 1015 | 1016 | void twii_SetState(uint8_t ucState) { 1017 | twi_state = ucState; 1018 | } 1019 | 1020 | void twii_SetError(uint8_t ucError) { 1021 | twi_error = ucError ; 1022 | } 1023 | 1024 | void twii_InitBuffer(uint8_t ucPos, uint8_t ucLength) { 1025 | twi_masterBufferIndex = 0; 1026 | twi_masterBufferLength = ucLength; 1027 | } 1028 | 1029 | void twii_CopyToBuf(uint8_t* pData, uint8_t ucLength) { 1030 | uint8_t i; 1031 | for (i = 0; i < ucLength; ++i) { 1032 | twi_masterBuffer[i] = pData[i]; 1033 | } 1034 | } 1035 | 1036 | void twii_CopyFromBuf(uint8_t *pData, uint8_t ucLength) { 1037 | uint8_t i; 1038 | for (i = 0; i < ucLength; ++i) { 1039 | pData[i] = twi_masterBuffer[i]; 1040 | } 1041 | } 1042 | 1043 | void twii_SetSlaRW(uint8_t ucSlaRW) { 1044 | twi_slarw = ucSlaRW; 1045 | } 1046 | 1047 | void twii_SetStart() { 1048 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); 1049 | } 1050 | 1051 | void twi_write01() { 1052 | if (TWI_MTX == twi_state) return; // blocking test 1053 | twi_transmitting = 0 ; 1054 | if (twi_error == 0xFF) 1055 | twi_Finish (0); // success 1056 | else if (twi_error == TW_MT_SLA_NACK) 1057 | twi_Finish (2); // error: address send, nack received 1058 | else if (twi_error == TW_MT_DATA_NACK) 1059 | twi_Finish (3); // error: data send, nack received 1060 | else 1061 | twi_Finish (4); // other twi error 1062 | if (twi_cbendTransmissionDone) return twi_cbendTransmissionDone(twi_Return_Value); 1063 | return; 1064 | } 1065 | 1066 | 1067 | void twi_write00() { 1068 | if (TWI_READY != twi_state) return; // blocking test 1069 | if (TWI_BUFFER_LENGTH < ptwv -> length) { 1070 | twi_Finish(1); // end write with error 1 1071 | return; 1072 | } 1073 | twi_Done = 0x00; // show as working 1074 | twii_SetState(TWI_MTX); // to transmitting 1075 | twii_SetError(0xFF); // to No Error 1076 | twii_InitBuffer(0, ptwv -> length); // pointer and length 1077 | twii_CopyToBuf(ptwv -> data, ptwv -> length); // get the data 1078 | twii_SetSlaRW((ptwv -> address << 1) | TW_WRITE); // write command 1079 | twii_SetStart(); // start the cycle 1080 | fNextInterruptFunction = twi_write01; // next routine 1081 | return twi_write01(); 1082 | } 1083 | 1084 | void twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait) { 1085 | uint8_t i; 1086 | ptwv = (twi_Write_Vars *)malloc(sizeof(twi_Write_Vars)); 1087 | ptwv -> address = address; 1088 | ptwv -> data = data; 1089 | ptwv -> length = length; 1090 | ptwv -> wait = wait; 1091 | fNextInterruptFunction = twi_write00; 1092 | return twi_write00(); 1093 | } 1094 | 1095 | void twi_read01() { 1096 | if (TWI_MRX == twi_state) return; // blocking test 1097 | if (twi_masterBufferIndex < ptwv -> length) ptwv -> length = twi_masterBufferIndex; 1098 | twii_CopyFromBuf(ptwv -> data, ptwv -> length); 1099 | twi_Finish(ptwv -> length); 1100 | if (twi_cbreadFromDone) return twi_cbreadFromDone(twi_Return_Value); 1101 | return; 1102 | } 1103 | 1104 | void twi_read00() { 1105 | if (TWI_READY != twi_state) return; // blocking test 1106 | if (TWI_BUFFER_LENGTH < ptwv -> length) twi_Finish(0); // error return 1107 | twi_Done = 0x00; // show as working 1108 | twii_SetState(TWI_MRX); // reading 1109 | twii_SetError(0xFF); // reset error 1110 | twii_InitBuffer(0, ptwv -> length - 1); // init to one less than length 1111 | twii_SetSlaRW((ptwv -> address << 1) | TW_READ); // read command 1112 | twii_SetStart(); // start cycle 1113 | fNextInterruptFunction = twi_read01; 1114 | return twi_read01(); 1115 | } 1116 | 1117 | void twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) { 1118 | uint8_t i; 1119 | 1120 | ptwv = (twi_Write_Vars *)malloc(sizeof(twi_Write_Vars)); 1121 | ptwv -> address = address; 1122 | ptwv -> data = data; 1123 | ptwv -> length = length; 1124 | fNextInterruptFunction = twi_read00; 1125 | return twi_read00(); 1126 | } 1127 | 1128 | void twi_reply(uint8_t ack) { 1129 | // transmit master read ready signal, with or without ack 1130 | if (ack){ 1131 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); 1132 | } else { 1133 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); 1134 | } 1135 | } 1136 | 1137 | void twi_stop(void) { 1138 | // send stop condition 1139 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); 1140 | 1141 | // wait for stop condition to be exectued on bus 1142 | // TWINT is not set after a stop condition! 1143 | while (TWCR & _BV(TWSTO)) { 1144 | continue; 1145 | } 1146 | 1147 | // update twi state 1148 | twi_state = TWI_READY; 1149 | } 1150 | 1151 | void twi_releaseBus(void) { 1152 | // release bus 1153 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); 1154 | 1155 | // update twi state 1156 | twi_state = TWI_READY; 1157 | } 1158 | 1159 | SIGNAL(TWI_vect) { 1160 | switch (TW_STATUS) { 1161 | // All Master 1162 | case TW_START: // sent start condition 1163 | case TW_REP_START: // sent repeated start condition 1164 | // copy device address and r/w bit to output register and ack 1165 | TWDR = twi_slarw; 1166 | twi_reply(1); 1167 | break; 1168 | 1169 | // Master Transmitter 1170 | case TW_MT_SLA_ACK: // slave receiver acked address 1171 | case TW_MT_DATA_ACK: // slave receiver acked data 1172 | // if there is data to send, send it, otherwise stop 1173 | if (twi_masterBufferIndex < twi_masterBufferLength) { 1174 | // copy data to output register and ack 1175 | TWDR = twi_masterBuffer[twi_masterBufferIndex++]; 1176 | twi_reply(1); 1177 | } else { 1178 | twi_stop(); 1179 | } 1180 | break; 1181 | 1182 | case TW_MT_SLA_NACK: // address sent, nack received 1183 | twi_error = TW_MT_SLA_NACK; 1184 | twi_stop(); 1185 | break; 1186 | 1187 | case TW_MT_DATA_NACK: // data sent, nack received 1188 | twi_error = TW_MT_DATA_NACK; 1189 | twi_stop(); 1190 | break; 1191 | 1192 | case TW_MT_ARB_LOST: // lost bus arbitration 1193 | twi_error = TW_MT_ARB_LOST; 1194 | twi_releaseBus(); 1195 | break; 1196 | 1197 | // Master Receiver 1198 | case TW_MR_DATA_ACK: // data received, ack sent 1199 | // put byte into buffer 1200 | twi_masterBuffer[twi_masterBufferIndex++] = TWDR; 1201 | 1202 | case TW_MR_SLA_ACK: // address sent, ack received 1203 | // ack if more bytes are expected, otherwise nack 1204 | if (twi_masterBufferIndex < twi_masterBufferLength) { 1205 | twi_reply(1); 1206 | } else { 1207 | twi_reply(0); 1208 | } 1209 | break; 1210 | 1211 | case TW_MR_DATA_NACK: // data received, nack sent 1212 | // put final byte into buffer 1213 | twi_masterBuffer[twi_masterBufferIndex++] = TWDR; 1214 | 1215 | case TW_MR_SLA_NACK: // address sent, nack received 1216 | twi_stop(); 1217 | break; 1218 | 1219 | // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case 1220 | 1221 | // Slave Receiver (NOT IMPLEMENTED YET) 1222 | /* 1223 | case TW_SR_SLA_ACK: // addressed, returned ack 1224 | case TW_SR_GCALL_ACK: // addressed generally, returned ack 1225 | case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack 1226 | case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack 1227 | // enter slave receiver mode 1228 | twi_state = TWI_SRX; 1229 | 1230 | // indicate that rx buffer can be overwritten and ack 1231 | twi_rxBufferIndex = 0; 1232 | twi_reply(1); 1233 | break; 1234 | 1235 | case TW_SR_DATA_ACK: // data received, returned ack 1236 | case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack 1237 | // if there is still room in the rx buffer 1238 | if (twi_rxBufferIndex < TWI_BUFFER_LENGTH) { 1239 | // put byte in buffer and ack 1240 | twi_rxBuffer[twi_rxBufferIndex++] = TWDR; 1241 | twi_reply(1); 1242 | } else { 1243 | // otherwise nack 1244 | twi_reply(0); 1245 | } 1246 | break; 1247 | 1248 | case TW_SR_STOP: // stop or repeated start condition received 1249 | // put a null char after data if there's room 1250 | if (twi_rxBufferIndex < TWI_BUFFER_LENGTH) { 1251 | twi_rxBuffer[twi_rxBufferIndex] = 0; 1252 | } 1253 | 1254 | // sends ack and stops interface for clock stretching 1255 | twi_stop(); 1256 | 1257 | // callback to user defined callback 1258 | twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); 1259 | 1260 | // since we submit rx buffer to "wire" library, we can reset it 1261 | twi_rxBufferIndex = 0; 1262 | 1263 | // ack future responses and leave slave receiver state 1264 | twi_releaseBus(); 1265 | break; 1266 | 1267 | case TW_SR_DATA_NACK: // data received, returned nack 1268 | case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack 1269 | // nack back at master 1270 | twi_reply(0); 1271 | break; 1272 | 1273 | // Slave Transmitter 1274 | case TW_ST_SLA_ACK: // addressed, returned ack 1275 | case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack 1276 | // enter slave transmitter mode 1277 | twi_state = TWI_STX; 1278 | 1279 | // ready the tx buffer index for iteration 1280 | twi_txBufferIndex = 0; 1281 | 1282 | // set tx buffer length to be zero, to verify if user changes it 1283 | twi_txBufferLength = 0; 1284 | 1285 | // request for txBuffer to be filled and length to be set 1286 | // note: user must call twi_transmit(bytes, length) to do this 1287 | twi_onSlaveTransmit(); 1288 | 1289 | // if they didn't change buffer & length, initialize it 1290 | if (0 == twi_txBufferLength) { 1291 | twi_txBufferLength = 1; 1292 | twi_txBuffer[0] = 0x00; 1293 | } 1294 | 1295 | // transmit first byte from buffer, fall through 1296 | 1297 | case TW_ST_DATA_ACK: // byte sent, ack returned 1298 | // copy data to output register 1299 | TWDR = twi_txBuffer[twi_txBufferIndex++]; 1300 | 1301 | // if there is more to send, ack, otherwise nack 1302 | if (twi_txBufferIndex < twi_txBufferLength) { 1303 | twi_reply(1); 1304 | } else { 1305 | twi_reply(0); 1306 | } 1307 | break; 1308 | 1309 | case TW_ST_DATA_NACK: // received nack, we are done 1310 | case TW_ST_LAST_DATA: // received ack, but we are done already! 1311 | // ack future responses 1312 | twi_reply(1); 1313 | // leave slave receiver state 1314 | twi_state = TWI_READY; 1315 | break; 1316 | */ 1317 | 1318 | // all 1319 | case TW_NO_INFO: // no state information 1320 | break; 1321 | 1322 | case TW_BUS_ERROR: // bus error, illegal stop/start 1323 | twi_error = TW_BUS_ERROR; 1324 | twi_stop(); 1325 | break; 1326 | } 1327 | 1328 | if (fNextInterruptFunction) return fNextInterruptFunction(); 1329 | } 1330 | 1331 | TwoWire::TwoWire() { } 1332 | 1333 | void TwoWire::begin(void) { 1334 | rxBufferIndex = 0; 1335 | rxBufferLength = 0; 1336 | 1337 | txBufferIndex = 0; 1338 | txBufferLength = 0; 1339 | 1340 | twi_init(); 1341 | } 1342 | 1343 | void TwoWire::beginTransmission(uint8_t address) { 1344 | //beginTransmission((uint8_t)address); 1345 | 1346 | // indicate that we are transmitting 1347 | twi_transmitting = 1; 1348 | 1349 | // set address of targeted slave 1350 | txAddress = address; 1351 | 1352 | // reset tx buffer iterator vars 1353 | txBufferIndex = 0; 1354 | txBufferLength = 0; 1355 | } 1356 | 1357 | uint8_t TwoWire::endTransmission(uint16_t timeout) { 1358 | // transmit buffer (blocking) 1359 | //int8_t ret = 1360 | twi_cbendTransmissionDone = NULL; 1361 | twi_writeTo(txAddress, txBuffer, txBufferLength, 1); 1362 | int8_t ret = twii_WaitForDone(timeout); 1363 | 1364 | // reset tx buffer iterator vars 1365 | txBufferIndex = 0; 1366 | txBufferLength = 0; 1367 | 1368 | // indicate that we are done transmitting 1369 | // twi_transmitting = 0; 1370 | return ret; 1371 | } 1372 | 1373 | void TwoWire::nbendTransmission(void (*function)(int)) { 1374 | twi_cbendTransmissionDone = function; 1375 | twi_writeTo(txAddress, txBuffer, txBufferLength, 1); 1376 | return; 1377 | } 1378 | 1379 | void TwoWire::send(uint8_t data) { 1380 | if (twi_transmitting) { 1381 | // in master transmitter mode 1382 | // don't bother if buffer is full 1383 | if (txBufferLength >= NBWIRE_BUFFER_LENGTH) { 1384 | return; 1385 | } 1386 | 1387 | // put byte in tx buffer 1388 | txBuffer[txBufferIndex] = data; 1389 | ++txBufferIndex; 1390 | 1391 | // update amount in buffer 1392 | txBufferLength = txBufferIndex; 1393 | } else { 1394 | // in slave send mode 1395 | // reply to master 1396 | //twi_transmit(&data, 1); 1397 | } 1398 | } 1399 | 1400 | uint8_t TwoWire::receive(void) { 1401 | // default to returning null char 1402 | // for people using with char strings 1403 | uint8_t value = 0; 1404 | 1405 | // get each successive byte on each call 1406 | if (rxBufferIndex < rxBufferLength) { 1407 | value = rxBuffer[rxBufferIndex]; 1408 | ++rxBufferIndex; 1409 | } 1410 | 1411 | return value; 1412 | } 1413 | 1414 | uint8_t TwoWire::requestFrom(uint8_t address, int quantity, uint16_t timeout) { 1415 | // clamp to buffer length 1416 | if (quantity > NBWIRE_BUFFER_LENGTH) { 1417 | quantity = NBWIRE_BUFFER_LENGTH; 1418 | } 1419 | 1420 | // perform blocking read into buffer 1421 | twi_cbreadFromDone = NULL; 1422 | twi_readFrom(address, rxBuffer, quantity); 1423 | uint8_t read = twii_WaitForDone(timeout); 1424 | 1425 | // set rx buffer iterator vars 1426 | rxBufferIndex = 0; 1427 | rxBufferLength = read; 1428 | 1429 | return read; 1430 | } 1431 | 1432 | void TwoWire::nbrequestFrom(uint8_t address, int quantity, void (*function)(int)) { 1433 | // clamp to buffer length 1434 | if (quantity > NBWIRE_BUFFER_LENGTH) { 1435 | quantity = NBWIRE_BUFFER_LENGTH; 1436 | } 1437 | 1438 | // perform blocking read into buffer 1439 | twi_cbreadFromDone = function; 1440 | twi_readFrom(address, rxBuffer, quantity); 1441 | //uint8_t read = twii_WaitForDone(); 1442 | 1443 | // set rx buffer iterator vars 1444 | //rxBufferIndex = 0; 1445 | //rxBufferLength = read; 1446 | 1447 | rxBufferIndex = 0; 1448 | rxBufferLength = quantity; // this is a hack 1449 | 1450 | return; //read; 1451 | } 1452 | 1453 | uint8_t TwoWire::available(void) { 1454 | return rxBufferLength - rxBufferIndex; 1455 | } 1456 | 1457 | #endif 1458 | -------------------------------------------------------------------------------- /lib/lib/I2Cdev/I2Cdev.h: -------------------------------------------------------------------------------- 1 | // I2Cdev library collection - Main I2C device class header file 2 | // Abstracts bit and byte I2C R/W functions into a convenient class 3 | // 6/9/2012 by Jeff Rowberg 4 | // 5 | // Changelog: 6 | // 2013-05-06 - add Francesco Ferrara's Fastwire v0.24 implementation with small modifications 7 | // 2013-05-05 - fix issue with writing bit values to words (Sasquatch/Farzanegan) 8 | // 2012-06-09 - fix major issue with reading > 32 bytes at a time with Arduino Wire 9 | // - add compiler warnings when using outdated or IDE or limited I2Cdev implementation 10 | // 2011-11-01 - fix write*Bits mask calculation (thanks sasquatch @ Arduino forums) 11 | // 2011-10-03 - added automatic Arduino version detection for ease of use 12 | // 2011-10-02 - added Gene Knight's NBWire TwoWire class implementation with small modifications 13 | // 2011-08-31 - added support for Arduino 1.0 Wire library (methods are different from 0.x) 14 | // 2011-08-03 - added optional timeout parameter to read* methods to easily change from default 15 | // 2011-08-02 - added support for 16-bit registers 16 | // - fixed incorrect Doxygen comments on some methods 17 | // - added timeout value for read operations (thanks mem @ Arduino forums) 18 | // 2011-07-30 - changed read/write function structures to return success or byte counts 19 | // - made all methods static for multi-device memory savings 20 | // 2011-07-28 - initial release 21 | 22 | /* ============================================ 23 | I2Cdev device library code is placed under the MIT license 24 | Copyright (c) 2013 Jeff Rowberg 25 | 26 | Permission is hereby granted, free of charge, to any person obtaining a copy 27 | of this software and associated documentation files (the "Software"), to deal 28 | in the Software without restriction, including without limitation the rights 29 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 30 | copies of the Software, and to permit persons to whom the Software is 31 | furnished to do so, subject to the following conditions: 32 | 33 | The above copyright notice and this permission notice shall be included in 34 | all copies or substantial portions of the Software. 35 | 36 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 37 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 38 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 39 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 40 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 41 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 42 | THE SOFTWARE. 43 | =============================================== 44 | */ 45 | 46 | #ifndef _I2CDEV_H_ 47 | #define _I2CDEV_H_ 48 | 49 | // ----------------------------------------------------------------------------- 50 | // I2C interface implementation setting 51 | // ----------------------------------------------------------------------------- 52 | #define I2CDEV_IMPLEMENTATION I2CDEV_ARDUINO_WIRE 53 | //#define I2CDEV_IMPLEMENTATION I2CDEV_BUILTIN_FASTWIRE 54 | 55 | // comment this out if you are using a non-optimal IDE/implementation setting 56 | // but want the compiler to shut up about it 57 | #define I2CDEV_IMPLEMENTATION_WARNINGS 58 | 59 | // ----------------------------------------------------------------------------- 60 | // I2C interface implementation options 61 | // ----------------------------------------------------------------------------- 62 | #define I2CDEV_ARDUINO_WIRE 1 // Wire object from Arduino 63 | #define I2CDEV_BUILTIN_NBWIRE 2 // Tweaked Wire object from Gene Knight's NBWire project 64 | // ^^^ NBWire implementation is still buggy w/some interrupts! 65 | #define I2CDEV_BUILTIN_FASTWIRE 3 // FastWire object from Francesco Ferrara's project 66 | #define I2CDEV_I2CMASTER_LIBRARY 4 // I2C object from DSSCircuits I2C-Master Library at https://github.com/DSSCircuits/I2C-Master-Library 67 | 68 | // ----------------------------------------------------------------------------- 69 | // Arduino-style "Serial.print" debug constant (uncomment to enable) 70 | // ----------------------------------------------------------------------------- 71 | //#define I2CDEV_SERIAL_DEBUG 72 | 73 | #ifdef ARDUINO 74 | #if ARDUINO < 100 75 | #include "WProgram.h" 76 | #else 77 | #include "Arduino.h" 78 | #endif 79 | #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE 80 | #include 81 | #endif 82 | #if I2CDEV_IMPLEMENTATION == I2CDEV_I2CMASTER_LIBRARY 83 | #include 84 | #endif 85 | #endif 86 | 87 | // 1000ms default read timeout (modify with "I2Cdev::readTimeout = [ms];") 88 | #define I2CDEV_DEFAULT_READ_TIMEOUT 1000 89 | 90 | class I2Cdev { 91 | public: 92 | I2Cdev(); 93 | 94 | static int8_t readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); 95 | static int8_t readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); 96 | static int8_t readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); 97 | static int8_t readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); 98 | static int8_t readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); 99 | static int8_t readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); 100 | static int8_t readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); 101 | static int8_t readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); 102 | 103 | static bool writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data); 104 | static bool writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data); 105 | static bool writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data); 106 | static bool writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data); 107 | static bool writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data); 108 | static bool writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data); 109 | static bool writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data); 110 | static bool writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data); 111 | 112 | static uint16_t readTimeout; 113 | }; 114 | 115 | #if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE 116 | ////////////////////// 117 | // FastWire 0.24 118 | // This is a library to help faster programs to read I2C devices. 119 | // Copyright(C) 2012 120 | // Francesco Ferrara 121 | ////////////////////// 122 | 123 | /* Master */ 124 | #define TW_START 0x08 125 | #define TW_REP_START 0x10 126 | 127 | /* Master Transmitter */ 128 | #define TW_MT_SLA_ACK 0x18 129 | #define TW_MT_SLA_NACK 0x20 130 | #define TW_MT_DATA_ACK 0x28 131 | #define TW_MT_DATA_NACK 0x30 132 | #define TW_MT_ARB_LOST 0x38 133 | 134 | /* Master Receiver */ 135 | #define TW_MR_ARB_LOST 0x38 136 | #define TW_MR_SLA_ACK 0x40 137 | #define TW_MR_SLA_NACK 0x48 138 | #define TW_MR_DATA_ACK 0x50 139 | #define TW_MR_DATA_NACK 0x58 140 | 141 | #define TW_OK 0 142 | #define TW_ERROR 1 143 | 144 | class Fastwire { 145 | private: 146 | static boolean waitInt(); 147 | 148 | public: 149 | static void setup(int khz, boolean pullup); 150 | static byte beginTransmission(byte device); 151 | static byte write(byte value); 152 | static byte writeBuf(byte device, byte address, byte *data, byte num); 153 | static byte readBuf(byte device, byte address, byte *data, byte num); 154 | static void reset(); 155 | static byte stop(); 156 | }; 157 | #endif 158 | 159 | #if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE 160 | // NBWire implementation based heavily on code by Gene Knight 161 | // Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html 162 | // Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html 163 | 164 | #define NBWIRE_BUFFER_LENGTH 32 165 | 166 | class TwoWire { 167 | private: 168 | static uint8_t rxBuffer[]; 169 | static uint8_t rxBufferIndex; 170 | static uint8_t rxBufferLength; 171 | 172 | static uint8_t txAddress; 173 | static uint8_t txBuffer[]; 174 | static uint8_t txBufferIndex; 175 | static uint8_t txBufferLength; 176 | 177 | // static uint8_t transmitting; 178 | static void (*user_onRequest)(void); 179 | static void (*user_onReceive)(int); 180 | static void onRequestService(void); 181 | static void onReceiveService(uint8_t*, int); 182 | 183 | public: 184 | TwoWire(); 185 | void begin(); 186 | void begin(uint8_t); 187 | void begin(int); 188 | void beginTransmission(uint8_t); 189 | //void beginTransmission(int); 190 | uint8_t endTransmission(uint16_t timeout=0); 191 | void nbendTransmission(void (*function)(int)) ; 192 | uint8_t requestFrom(uint8_t, int, uint16_t timeout=0); 193 | //uint8_t requestFrom(int, int); 194 | void nbrequestFrom(uint8_t, int, void (*function)(int)); 195 | void send(uint8_t); 196 | void send(uint8_t*, uint8_t); 197 | //void send(int); 198 | void send(char*); 199 | uint8_t available(void); 200 | uint8_t receive(void); 201 | void onReceive(void (*)(int)); 202 | void onRequest(void (*)(void)); 203 | }; 204 | 205 | #define TWI_READY 0 206 | #define TWI_MRX 1 207 | #define TWI_MTX 2 208 | #define TWI_SRX 3 209 | #define TWI_STX 4 210 | 211 | #define TW_WRITE 0 212 | #define TW_READ 1 213 | 214 | #define TW_MT_SLA_NACK 0x20 215 | #define TW_MT_DATA_NACK 0x30 216 | 217 | #define CPU_FREQ 16000000L 218 | #define TWI_FREQ 100000L 219 | #define TWI_BUFFER_LENGTH 32 220 | 221 | /* TWI Status is in TWSR, in the top 5 bits: TWS7 - TWS3 */ 222 | 223 | #define TW_STATUS_MASK (_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|_BV(TWS3)) 224 | #define TW_STATUS (TWSR & TW_STATUS_MASK) 225 | #define TW_START 0x08 226 | #define TW_REP_START 0x10 227 | #define TW_MT_SLA_ACK 0x18 228 | #define TW_MT_SLA_NACK 0x20 229 | #define TW_MT_DATA_ACK 0x28 230 | #define TW_MT_DATA_NACK 0x30 231 | #define TW_MT_ARB_LOST 0x38 232 | #define TW_MR_ARB_LOST 0x38 233 | #define TW_MR_SLA_ACK 0x40 234 | #define TW_MR_SLA_NACK 0x48 235 | #define TW_MR_DATA_ACK 0x50 236 | #define TW_MR_DATA_NACK 0x58 237 | #define TW_ST_SLA_ACK 0xA8 238 | #define TW_ST_ARB_LOST_SLA_ACK 0xB0 239 | #define TW_ST_DATA_ACK 0xB8 240 | #define TW_ST_DATA_NACK 0xC0 241 | #define TW_ST_LAST_DATA 0xC8 242 | #define TW_SR_SLA_ACK 0x60 243 | #define TW_SR_ARB_LOST_SLA_ACK 0x68 244 | #define TW_SR_GCALL_ACK 0x70 245 | #define TW_SR_ARB_LOST_GCALL_ACK 0x78 246 | #define TW_SR_DATA_ACK 0x80 247 | #define TW_SR_DATA_NACK 0x88 248 | #define TW_SR_GCALL_DATA_ACK 0x90 249 | #define TW_SR_GCALL_DATA_NACK 0x98 250 | #define TW_SR_STOP 0xA0 251 | #define TW_NO_INFO 0xF8 252 | #define TW_BUS_ERROR 0x00 253 | 254 | //#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr)) 255 | //#define _SFR_BYTE(sfr) _MMIO_BYTE(_SFR_ADDR(sfr)) 256 | 257 | #ifndef sbi // set bit 258 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 259 | #endif // sbi 260 | 261 | #ifndef cbi // clear bit 262 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 263 | #endif // cbi 264 | 265 | extern TwoWire Wire; 266 | 267 | #endif // I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE 268 | 269 | #endif /* _I2CDEV_H_ */ 270 | -------------------------------------------------------------------------------- /lib/lib/I2Cdev/_Stub/_Stub.cpp: -------------------------------------------------------------------------------- 1 | // I2Cdev library collection - MYDEVSTUB I2C device class 2 | // Based on [Manufacturer Name] MYDEVSTUB datasheet, [datasheet date] 3 | // [current release date] by [Author Name] <[Author Email]> 4 | // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib 5 | // 6 | // Changelog: 7 | // [YYYY-mm-dd] - updated some broken thing 8 | // [YYYY-mm-dd] - initial release 9 | 10 | /* ============================================ 11 | I2Cdev device library code is placed under the MIT license 12 | Copyright (c) 2011 [Author Name], Jeff Rowberg 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy 15 | of this software and associated documentation files (the "Software"), to deal 16 | in the Software without restriction, including without limitation the rights 17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the Software is 19 | furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in 22 | all copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30 | THE SOFTWARE. 31 | =============================================== 32 | */ 33 | 34 | #include "MYDEVSTUB.h" 35 | 36 | // ============================================================================ 37 | // DEVICE LIBRARY CONVENTIONS: 38 | // 39 | // 1. The class name should be the same as the device model if at all possible. 40 | // No spaces or hyphens, and ideally no underlines unless they're absolutely 41 | // necessary for clarity. ALL CAPS for model numbers, or FirstInitial caps 42 | // for full names. For example: 43 | // - ADXL345 44 | // - MPU6050 45 | // - TCA6424A 46 | // - PanelPilot 47 | // 48 | // 2. All #defines should use a device-specific prefix that is the same as the 49 | // all-caps version of the class name ("MYDEVSTUB_" in this example). 50 | // 51 | // 3. All #defines should be ALL CAPS, no matter what. This makes them clearly 52 | // distinctive from variables, classes, and functions. 53 | // 54 | // 4. Class methods and member variables should be named using camelCaps. 55 | // 56 | // 5. Every device class should contain an "initialize()" method which takes 57 | // no parameters and resets any important settings back to a known state, 58 | // ideally the defaults outlined in the datasheet. Some devices have a 59 | // RESET command available, which may be suitable. Some devices may not 60 | // require any specific initialization, but an empty method should be 61 | // created for consistency anyway. 62 | // 63 | // 6. Every device class should contain a "testConnection()" method which 64 | // returns TRUE if the device appears to be connected, or FALSE otherwise. 65 | // If a known ID register or device code is available, check for that. Since 66 | // such an ID register is not always available, at least check to make sure 67 | // that an I2C read may be performed on a specific register and that data 68 | // does actually come back (the I2Cdev class returns a "bytes read" value 69 | // for all read operations). 70 | // 71 | // 7. All class methods should be documented with useful information in Doxygen 72 | // format. You can take the info right out of the datasheet if you want to, 73 | // since that's likely to be helpful. Writing your own info is fine as well. 74 | // The goal is to have enough clear documentation right in the code that 75 | // someone can determine how the device works by studying the code alone. 76 | // 77 | // ============================================================================ 78 | 79 | /* ============================================================================ 80 | I2Cdev Class Quick Primer: 81 | 82 | The I2Cdev class provides simple methods for reading and writing from I2C 83 | device registers without messing with the underlying TWI/I2C functions. You 84 | just specify the device address, register address, and source or destination 85 | data according to which action you are doing. Here is the list of relevant 86 | function prototypes from the I2Cdev class (more info in the .cpp/.h files): 87 | 88 | static int8_t readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); 89 | static int8_t readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); 90 | static int8_t readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); 91 | static int8_t readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); 92 | static int8_t readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); 93 | static int8_t readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); 94 | static int8_t readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); 95 | static int8_t readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); 96 | 97 | static bool writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data); 98 | static bool writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data); 99 | static bool writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data); 100 | static bool writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data); 101 | static bool writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data); 102 | static bool writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data); 103 | static bool writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data); 104 | static bool writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data); 105 | 106 | Note that ALL OF THESE METHODS ARE STATIC. No I2Cdev object is needed; just 107 | use the static class methods. 108 | 109 | Also note that the first two parameters of every one of these methods are 110 | the same: "devAddr" and "regAddr". For every method, you need to specify the 111 | target/slave address and the register address. 112 | 113 | If your device uses 8-bit registers, you will want to use the following: 114 | readBit, readBits, readByte, readBytes 115 | writeBit, writeBits, writeByte, writeBytes 116 | 117 | ...but if it uses 16-bit registers, you will want to use these instead: 118 | readBitW, readBitsW, readWord, readWords 119 | writeBitW, writeBitsW, writeWord, writeWords 120 | 121 | Here's a sample of how to use a few of the methods. Note that in each case, 122 | the "buffer" variable is a uint8_t array or pointer, and the "value" variable 123 | (in three of the write examples) is a uint8_t single byte. The multi-byte 124 | write methods still require an array or pointer. 125 | 126 | READ 1 BIT FROM DEVICE 0x68, REGISTER 0x02, BIT POSITION 4 127 | bytesRead = I2Cdev::readBit(0x68, 0x02, 4, buffer); 128 | 129 | READ 3 BITS FROM DEVICE 0x68, REGISTER 0x02, BIT POSITION 4 130 | bytesRead = I2Cdev::readBits(0x68, 0x02, 4, 3, buffer); 131 | 132 | READ 1 BYTE FROM DEVICE 0x68, REGISTER 0x02 133 | bytesRead = I2Cdev::readByte(0x68, 0x02, buffer); 134 | 135 | READ 2 BYTES FROM DEVICE 0x68, REGISTER 0x02 (AND 0x03 FOR 2ND BYTE) 136 | bytesRead = I2Cdev::readBytes(0x68, 0x02, 2, buffer); 137 | 138 | WRITE 1 BIT TO DEVICE 0x68, REGISTER 0x02, BIT POSITION 4 139 | status = I2Cdev::writeBit(0x68, 0x02, 4, value); 140 | 141 | WRITE 3 BITS TO DEVICE 0x68, REGISTER 0x02, BIT POSITION 4 142 | status = I2Cdev::writeBits(0x68, 0x02, 4, 3, value); 143 | 144 | WRITE 1 BYTE TO DEVICE 0x68, REGISTER 0x02 145 | status = I2Cdev::writeByte(0x68, 0x02, value); 146 | 147 | WRITE 2 BYTES TO DEVICE 0x68, REGISTER 0x02 (AND 0x03 FOR 2ND BYTE) 148 | status = I2Cdev::writeBytes(0x68, 0x02, 2, buffer); 149 | 150 | The word-based methods are exactly the same, except they use 16-bit variables 151 | instead of 8-bit ones. 152 | 153 | ============================================================================ */ 154 | 155 | /** Default constructor, uses default I2C address. 156 | * @see MYDEVSTUB_DEFAULT_ADDRESS 157 | */ 158 | MYDEVSTUB::MYDEVSTUB() { 159 | devAddr = MYDEVSTUB_DEFAULT_ADDRESS; 160 | } 161 | 162 | /** Specific address constructor. 163 | * @param address I2C address 164 | * @see MYDEVSTUB_DEFAULT_ADDRESS 165 | * @see MYDEVSTUB_ADDRESS 166 | */ 167 | MYDEVSTUB::MYDEVSTUB(uint8_t address) { 168 | devAddr = address; 169 | } 170 | 171 | /** Power on and prepare for general usage. 172 | */ 173 | void MYDEVSTUB::initialize() { 174 | // ---------------------------------------------------------------------------- 175 | // STUB TODO: 176 | // Perform any important initialization here. Maybe nothing is required, but 177 | // the method should exist anyway. 178 | // ---------------------------------------------------------------------------- 179 | } 180 | 181 | /** Verify the I2C connection. 182 | * Make sure the device is connected and responds as expected. 183 | * @return True if connection is valid, false otherwise 184 | */ 185 | bool MYDEVSTUB::testConnection() { 186 | if (I2Cdev::readByte(devAddr, MYDEVSTUB_RA_WHO_AM_I, buffer) == 1) { 187 | return true; 188 | } 189 | return false; 190 | } 191 | 192 | // ---------------------------------------------------------------------------- 193 | // STUB TODO: 194 | // Define methods to fully cover all available functionality provided by the 195 | // device, according to the datasheet and/or register map. Unless there is very 196 | // clear reason not to, try to follow the get/set naming convention for all 197 | // values, for instance: 198 | // - uint8_t getThreshold() 199 | // - void setThreshold(uint8_t threshold) 200 | // - uint8_t getRate() 201 | // - void setRate(uint8_t rate) 202 | // 203 | // Some methods may be named differently if it makes sense. As long as all 204 | // functionality is covered, that's the important part. The methods here are 205 | // only examples and should not be kept for your real device. 206 | // ---------------------------------------------------------------------------- 207 | 208 | // MEASURE1 register, read-only 209 | 210 | uint8_t MYDEVSTUB::getMeasurement1() { 211 | // read a single byte and return it 212 | I2Cdev::readByte(devAddr, MYDEVSTUB_RA_MEASURE1, buffer); 213 | return buffer[0]; 214 | } 215 | 216 | // MEASURE2 register, read-only 217 | 218 | uint8_t MYDEVSTUB::getMeasurement2() { 219 | // read a single byte and return it 220 | I2Cdev::readByte(devAddr, MYDEVSTUB_RA_MEASURE2, buffer); 221 | return buffer[0]; 222 | } 223 | 224 | // MEASURE3 register, read-only 225 | 226 | uint8_t MYDEVSTUB::getMeasurement3() { 227 | // read a single byte and return it 228 | I2Cdev::readByte(devAddr, MYDEVSTUB_RA_MEASURE3, buffer); 229 | return buffer[0]; 230 | } 231 | 232 | // CONFIG1 register, r/w 233 | 234 | void MYDEVSTUB::reset() { 235 | // write a single bit to the RESET position in the CONFIG1 register 236 | I2Cdev::writeBit(devAddr, MYDEVSTUB_RA_CONFIG1, MYDEVSTUB_CONFIG1_RESET_BIT, 1); 237 | } 238 | bool MYDEVSTUB::getFIFOEnabled() { 239 | // read a single bit from the FIFO_EN position in the CONFIG1 regsiter 240 | I2Cdev::readBit(devAddr, MYDEVSTUB_RA_CONFIG1, MYDEVSTUB_CONFIG1_FIFO_EN_BIT, buffer); 241 | return buffer[0]; 242 | } 243 | void MYDEVSTUB::setFIFOEnabled(bool enabled) { 244 | // write a single bit to the FIFO_EN position in the CONFIG1 regsiter 245 | I2Cdev::writeBit(devAddr, MYDEVSTUB_RA_CONFIG1, MYDEVSTUB_CONFIG1_FIFO_EN_BIT, enabled); 246 | } 247 | 248 | // CONFIG2 register, r/w 249 | 250 | uint8_t MYDEVSTUB::getInterruptMode() { 251 | // reading a single bit from a register 252 | I2Cdev::readBit(devAddr, MYDEVSTUB_RA_CONFIG2, MYDEVSTUB_CONFIG2_INTMODE_BIT, buffer); 253 | return buffer[0]; 254 | } 255 | void MYDEVSTUB::setInterruptMode(uint8_t mode) { 256 | // writing a single bit into a register 257 | } 258 | uint8_t MYDEVSTUB::getRate() { 259 | // reading multiple single bit from a register 260 | I2Cdev::readBits(devAddr, MYDEVSTUB_RA_CONFIG2, MYDEVSTUB_CONFIG2_RATE_BIT, MYDEVSTUB_CONFIG2_RATE_LENGTH, buffer); 261 | return buffer[0]; 262 | } 263 | void MYDEVSTUB::setRate(uint8_t rate) { 264 | // writing multiple bits into a register 265 | I2Cdev::writeBits(devAddr, MYDEVSTUB_RA_CONFIG2, MYDEVSTUB_CONFIG2_RATE_BIT, MYDEVSTUB_CONFIG2_RATE_LENGTH, rate); 266 | } 267 | 268 | // DATA_* registers, r/w 269 | 270 | uint16_t MYDEVSTUB::getData() { 271 | // reading two H/L bytes and bit-shifting them into a 16-bit value 272 | I2Cdev::readBytes(devAddr, MYDEVSTUB_RA_DATA_H, 2, buffer); 273 | return (buffer[0] << 8) + buffer[1]; 274 | } 275 | void MYDEVSTUB::setData(uint16_t value) { 276 | // splitting a 16-bit value into two H/L bytes and writing them 277 | buffer[0] = value >> 8; 278 | buffer[1] = value & 0xFF; 279 | I2Cdev::writeBytes(devAddr, MYDEVSTUB_RA_DATA_H, 2, buffer); 280 | } 281 | 282 | // WHO_AM_I register, read-only 283 | 284 | uint8_t MYDEVSTUB::getDeviceID() { 285 | // read a single byte and return it 286 | I2Cdev::readByte(devAddr, MYDEVSTUB_RA_WHO_AM_I, buffer); 287 | return buffer[0]; 288 | } 289 | -------------------------------------------------------------------------------- /lib/lib/I2Cdev/_Stub/_Stub.h: -------------------------------------------------------------------------------- 1 | // I2Cdev library collection - MYDEVSTUB I2C device class header file 2 | // Based on [Manufacturer Name] MYDEVSTUB datasheet, [datasheet date] 3 | // [current release date] by [Author Name] <[Author Email]> 4 | // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib 5 | // 6 | // Changelog: 7 | // [YYYY-mm-dd] - updated some broken thing 8 | // [YYYY-mm-dd] - initial release 9 | 10 | /* ============================================ 11 | I2Cdev device library code is placed under the MIT license 12 | Copyright (c) 2011 [Author Name], Jeff Rowberg 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy 15 | of this software and associated documentation files (the "Software"), to deal 16 | in the Software without restriction, including without limitation the rights 17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the Software is 19 | furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in 22 | all copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30 | THE SOFTWARE. 31 | =============================================== 32 | */ 33 | 34 | #ifndef _MYDEVSTUB_H_ 35 | #define _MYDEVSTUB_H_ 36 | 37 | #include "I2Cdev.h" 38 | 39 | // ============================================================================ 40 | // DEVICE LIBRARY CONVENTIONS: 41 | // 42 | // 1. The class name should be the same as the device model if at all possible. 43 | // No spaces or hyphens, and ideally no underlines unless they're absolutely 44 | // necessary for clarity. ALL CAPS for model numbers, or FirstInitial caps 45 | // for full names. For example: 46 | // - ADXL345 47 | // - MPU6050 48 | // - TCA6424A 49 | // - PanelPilot 50 | // 51 | // 2. All #defines should use a device-specific prefix that is the same as the 52 | // all-caps version of the class name ("MYDEVSTUB_" in this example). 53 | // 54 | // 3. All #defines should be ALL CAPS, no matter what. This makes them clearly 55 | // distinctive from variables, classes, and functions. 56 | // 57 | // 4. Class methods and member variables should be named using camelCaps. 58 | // 59 | // 5. Every device class should contain an "initialize()" method which takes 60 | // no parameters and resets any important settings back to a known state, 61 | // ideally the defaults outlined in the datasheet. Some devices have a 62 | // RESET command available, which may be suitable. Some devices may not 63 | // require any specific initialization, but an empty method should be 64 | // created for consistency anyway. 65 | // 66 | // 6. Every device class should contain a "testConnection()" method which 67 | // returns TRUE if the device appears to be connected, or FALSE otherwise. 68 | // If a known ID register or device code is available, check for that. Since 69 | // such an ID register is not always available, at least check to make sure 70 | // that an I2C read may be performed on a specific register and that data 71 | // does actually come back (the I2Cdev class returns a "bytes read" value 72 | // for all read operations). 73 | // 74 | // 7. All class methods should be documented with useful information in Doxygen 75 | // format. You can take the info right out of the datasheet if you want to, 76 | // since that's likely to be helpful. Writing your own info is fine as well. 77 | // The goal is to have enough clear documentation right in the code that 78 | // someone can determine how the device works by studying the code alone. 79 | // 80 | // ============================================================================ 81 | 82 | // ---------------------------------------------------------------------------- 83 | // STUB TODO: 84 | // List all possible device I2C addresses here, if they are predefined. Some 85 | // devices only have one possible address, in which case that one should be 86 | // defined as both [MYDEVSTUB]_ADDRESS and [MYDEVSTUB]_DEFAULT_ADDRESS for 87 | // consistency. The *_DEFAULT address will be used if a device object is 88 | // created without an address provided in the constructor. Note that I2C 89 | // devices conventionally use 7-bit addresses, so these will generally be 90 | // between 0x00 and 0x7F. 91 | // ---------------------------------------------------------------------------- 92 | #define MYDEVSTUB_ADDRESS_AD0_LOW 0x20 93 | #define MYDEVSTUB_ADDRESS_AD0_HIGH 0x21 94 | #define MYDEVSTUB_DEFAULT_ADDRESS 0x20 95 | 96 | // ---------------------------------------------------------------------------- 97 | // STUB TODO: 98 | // List all registers that this device has. The goal for all device libraries 99 | // is to have complete coverage of all possible functions, so be sure to add 100 | // everything in the datasheet. Register address constants should use the extra 101 | // prefix "RA_", followed by the datasheet's given name for each register. 102 | // ---------------------------------------------------------------------------- 103 | #define MYDEVSTUB_RA_MEASURE1 0x00 104 | #define MYDEVSTUB_RA_MEASURE2 0x01 105 | #define MYDEVSTUB_RA_MEASURE3 0x02 106 | #define MYDEVSTUB_RA_CONFIG1 0x03 107 | #define MYDEVSTUB_RA_CONFIG2 0x04 108 | #define MYDEVSTUB_RA_DATA_H 0x05 109 | #define MYDEVSTUB_RA_DATA_L 0x06 110 | #define MYDEVSTUB_RA_WHO_AM_I 0x07 111 | 112 | // ---------------------------------------------------------------------------- 113 | // STUB TODO: 114 | // List register structures wherever necessary. Bit position constants should 115 | // end in "_BIT", and are defined from 7 to 0, with 7 being the left/MSB and 116 | // 0 being the right/LSB. If the device uses 16-bit registers instead of the 117 | // more common 8-bit registers, the range is 15 to 0. Field length constants 118 | // should end in "_LENGTH", but otherwise match the name of bit position 119 | // constant that it complements. Fields that are a single bit in length don't 120 | // need a separate field length constant. 121 | // ---------------------------------------------------------------------------- 122 | #define MYDEVSTUB_MEASURE1_RATE_BIT 4 123 | #define MYDEVSTUB_MEASURE1_RATE_LENGTH 3 124 | 125 | #define MYDEVSTUB_CONFIG1_FIFO_BIT 1 126 | #define MYDEVSTUB_CONFIG1_RESET_BIT 0 127 | 128 | // ---------------------------------------------------------------------------- 129 | // STUB TODO: 130 | // List any special predefined values for each register according to the 131 | // datasheet. For example, MEMS devices often provide different options for 132 | // measurement rates, say 25Hz, 50Hz, 100Hz, and 200Hz. These are typically 133 | // represented by arbitrary bit values, say 0b00, 0b01, 0b10, and 0b11 (or 0x0, 134 | // 0x1, 0x2, and 0x3). Defining them here makes it easy to know which options 135 | // are available. 136 | // ---------------------------------------------------------------------------- 137 | #define MYDEVSTUB_RATE_10 0x00 138 | #define MYDEVSTUB_RATE_20 0x01 139 | #define MYDEVSTUB_RATE_40 0x02 140 | #define MYDEVSTUB_RATE_80 0x03 141 | #define MYDEVSTUB_RATE_160 0x04 142 | 143 | class MYDEVSTUB { 144 | public: 145 | MYDEVSTUB(); 146 | MYDEVSTUB(uint8_t address); 147 | 148 | void initialize(); 149 | bool testConnection(); 150 | 151 | // ---------------------------------------------------------------------------- 152 | // STUB TODO: 153 | // Declare methods to fully cover all available functionality provided by the 154 | // device, according to the datasheet and/or register map. Unless there is very 155 | // clear reason not to, try to follow the get/set naming convention for all 156 | // values, for instance: 157 | // - uint8_t getThreshold() 158 | // - void setThreshold(uint8_t threshold) 159 | // - uint8_t getRate() 160 | // - void setRate(uint8_t rate) 161 | // 162 | // Some methods may be named differently if it makes sense. As long as all 163 | // functionality is covered, that's the important part. The methods here are 164 | // only examples and should not be kept for your real device. 165 | // ---------------------------------------------------------------------------- 166 | 167 | // MEASURE1 register, read-only 168 | uint8_t getMeasurement1(); 169 | 170 | // MEASURE2 register, read-only 171 | uint8_t getMeasurement2(); 172 | 173 | // MEASURE3 register, read-only 174 | uint8_t getMeasurement3(); 175 | 176 | // CONFIG1 register, r/w 177 | void reset(); // <-- special method that resets entire device 178 | bool getFIFOEnabled(); 179 | void setFIFOEnabled(bool enabled); 180 | 181 | // CONFIG2 register, r/w 182 | uint8_t getInterruptMode(); 183 | void setInterruptMode(uint8_t mode); 184 | uint8_t getRate(); 185 | void setRate(uint8_t rate); 186 | 187 | // DATA_* registers, r/w 188 | uint16_t getData(); 189 | void setData(uint16_t value); 190 | 191 | // WHO_AM_I register, read-only 192 | uint8_t getDeviceID(); 193 | 194 | // ---------------------------------------------------------------------------- 195 | // STUB TODO: 196 | // Declare private object helper variables or local storage for particular 197 | // device settings, if required. All devices need a "devAddr" variable to store 198 | // the I2C slave address for easy access. Most devices also need a buffer for 199 | // reads (the I2Cdev class' read methods use a pointer for the storage location 200 | // of any read data). The buffer should be of type "uint8_t" if the device uses 201 | // 8-bit registers, or type "uint16_t" if the device uses 16-bit registers. 202 | // Many devices will not require more member variables than this. 203 | // ---------------------------------------------------------------------------- 204 | private: 205 | uint8_t devAddr; 206 | uint8_t buffer[6]; 207 | }; 208 | 209 | #endif /* _MYDEVSTUB_H_ */ 210 | -------------------------------------------------------------------------------- /lib/lib/I2Cdev/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For I2Cdev 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | I2Cdev KEYWORD1 9 | 10 | ####################################### 11 | # Methods and Functions (KEYWORD2) 12 | ####################################### 13 | 14 | readBit KEYWORD2 15 | readBitW KEYWORD2 16 | readBits KEYWORD2 17 | readBitsW KEYWORD2 18 | readByte KEYWORD2 19 | readBytes KEYWORD2 20 | readWord KEYWORD2 21 | readWords KEYWORD2 22 | writeBit KEYWORD2 23 | writeBitW KEYWORD2 24 | writeBits KEYWORD2 25 | writeBitsW KEYWORD2 26 | writeByte KEYWORD2 27 | writeBytes KEYWORD2 28 | writeWord KEYWORD2 29 | writeWords KEYWORD2 30 | 31 | ####################################### 32 | # Instances (KEYWORD2) 33 | ####################################### 34 | 35 | ####################################### 36 | # Constants (LITERAL1) 37 | ####################################### 38 | 39 | -------------------------------------------------------------------------------- /lib/lib/MemoryFree/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.orig 3 | .*.swp 4 | -------------------------------------------------------------------------------- /lib/lib/MemoryFree/MemoryFree.cpp: -------------------------------------------------------------------------------- 1 | extern unsigned int __bss_end; 2 | extern unsigned int __heap_start; 3 | extern void *__brkval; 4 | 5 | 6 | #include "MemoryFree.h" 7 | 8 | 9 | int freeMemory() { 10 | int free_memory; 11 | 12 | if((int)__brkval == 0) 13 | free_memory = ((int)&free_memory) - ((int)&__bss_end); 14 | else 15 | free_memory = ((int)&free_memory) - ((int)__brkval); 16 | 17 | return free_memory; 18 | } 19 | -------------------------------------------------------------------------------- /lib/lib/MemoryFree/MemoryFree.h: -------------------------------------------------------------------------------- 1 | #ifndef MEMORY_FREE_H 2 | #define MEMORY_FREE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | int freeMemory(); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif 15 | 16 | -------------------------------------------------------------------------------- /lib/lib/MemoryFree/README: -------------------------------------------------------------------------------- 1 | This is the excellent MemoryFree library from http://www.arduino.cc/playground/Code/AvailableMemory. 2 | 3 | I am hosting it here so there is a quick and easy way to pull it down. 4 | -------------------------------------------------------------------------------- /lib/lib/MemoryFree/examples/FreeMemory/FreeMemory.pde: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Reported free memory with str commented out: 4 | // 1848 bytes 5 | // 6 | // Reported free memory with str and Serial.println(str) uncommented: 7 | // 1834 8 | // 9 | // Difference: 14 bytes (13 ascii chars + null terminator 10 | 11 | // 14-bytes string 12 | //char str[] = "Hallo, world!"; 13 | 14 | 15 | void setup() { 16 | Serial.begin(115200); 17 | } 18 | 19 | 20 | void loop() { 21 | //Serial.println(str); 22 | 23 | Serial.print("freeMemory()="); 24 | Serial.println(freeMemory()); 25 | 26 | delay(1000); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /lib/lib/MsTimer2/MsTimer2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MsTimer2.h - Using timer2 with 1ms resolution 3 | Javier Valencia 4 | 5 | History: 6 | 29/Dec/11 - V0.6 added support for ATmega32u4, AT90USB646, AT90USB1286 (paul@pjrc.com) 7 | some improvements added by Bill Perry 8 | note: uses timer4 on Atmega32u4 9 | 29/May/09 - V0.5 added support for Atmega1280 (thanks to Manuel Negri) 10 | 19/Mar/09 - V0.4 added support for ATmega328P (thanks to Jerome Despatis) 11 | 11/Jun/08 - V0.3 12 | changes to allow working with different CPU frequencies 13 | added support for ATMega128 (using timer2) 14 | compatible with ATMega48/88/168/8 15 | 10/May/08 - V0.2 added some security tests and volatile keywords 16 | 9/May/08 - V0.1 released working on ATMEGA168 only 17 | 18 | 19 | This library is free software; you can redistribute it and/or 20 | modify it under the terms of the GNU Lesser General Public 21 | License as published by the Free Software Foundation; either 22 | version 2.1 of the License, or (at your option) any later version. 23 | 24 | This library is distributed in the hope that it will be useful, 25 | but WITHOUT ANY WARRANTY; without even the implied warranty of 26 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 27 | Lesser General Public License for more details. 28 | 29 | You should have received a copy of the GNU Lesser General Public 30 | License along with this library; if not, write to the Free Software 31 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 32 | */ 33 | 34 | #include 35 | 36 | unsigned long MsTimer2::msecs; 37 | void (*MsTimer2::func)(); 38 | volatile unsigned long MsTimer2::count; 39 | volatile char MsTimer2::overflowing; 40 | volatile unsigned int MsTimer2::tcnt2; 41 | 42 | void MsTimer2::set(unsigned long ms, void (*f)()) { 43 | float prescaler = 0.0; 44 | 45 | if (ms == 0) 46 | msecs = 1; 47 | else 48 | msecs = ms; 49 | 50 | func = f; 51 | 52 | #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) 53 | TIMSK2 &= ~(1<= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 60 | TCCR2B |= (1< 16Mhz, prescaler set to 128 68 | TCCR2B |= ((1<= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 79 | TCCR2 |= (1< 16Mhz, prescaler set to 128 87 | TCCR2 |= ((1<= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 97 | TCCR2 |= ((1< 16Mhz, prescaler set to 256 105 | TCCR2 |= (1<= 16000000L) { 116 | TCCR4B = (1<= 8000000L) { 119 | TCCR4B = (1<= 4000000L) { 122 | TCCR4B = (1<= 2000000L) { 125 | TCCR4B = (1<= 1000000L) { 128 | TCCR4B = (1<= 500000L) { 131 | TCCR4B = (1<= msecs && !overflowing) { 182 | overflowing = 1; 183 | count = count - msecs; // subtract ms to catch missed overflows 184 | // set to 0 if you don't want this. 185 | (*func)(); 186 | overflowing = 0; 187 | } 188 | } 189 | 190 | #if defined (__AVR_ATmega32U4__) 191 | ISR(TIMER4_OVF_vect) { 192 | #else 193 | ISR(TIMER2_OVF_vect) { 194 | #endif 195 | #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) 196 | TCNT2 = MsTimer2::tcnt2; 197 | #elif defined (__AVR_ATmega128__) 198 | TCNT2 = MsTimer2::tcnt2; 199 | #elif defined (__AVR_ATmega8__) 200 | TCNT2 = MsTimer2::tcnt2; 201 | #elif defined (__AVR_ATmega32U4__) 202 | // not necessary on 32u4's high speed timer4 203 | #endif 204 | MsTimer2::_overflow(); 205 | } 206 | 207 | -------------------------------------------------------------------------------- /lib/lib/MsTimer2/MsTimer2.h: -------------------------------------------------------------------------------- 1 | #ifndef MsTimer2_h 2 | #define MsTimer2_h 3 | 4 | #ifdef __AVR__ 5 | #include 6 | #else 7 | #error MsTimer2 library only works on AVR architecture 8 | #endif 9 | 10 | namespace MsTimer2 { 11 | extern unsigned long msecs; 12 | extern void (*func)(); 13 | extern volatile unsigned long count; 14 | extern volatile char overflowing; 15 | extern volatile unsigned int tcnt2; 16 | 17 | void set(unsigned long ms, void (*f)()); 18 | void start(); 19 | void stop(); 20 | void _overflow(); 21 | } 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /lib/lib/MsTimer2/examples/FlashLed/FlashLed.pde: -------------------------------------------------------------------------------- 1 | char dummyvar; // to get Arduinoi IDE to include core headers properly 2 | 3 | /* 4 | MsTimer2 is a small and very easy to use library to interface Timer2 with 5 | humans. It's called MsTimer2 because it "hardcodes" a resolution of 1 6 | millisecond on timer2 7 | For Details see: http://www.arduino.cc/playground/Main/MsTimer2 8 | */ 9 | #include 10 | 11 | // Switch on LED on and off each half second 12 | 13 | #if defined(ARDUINO) && ARDUINO >= 100 14 | const int led_pin = LED_BUILTIN; // 1.0 built in LED pin var 15 | #else 16 | #if defined(CORE_LED0_PIN) 17 | const int led_pin = CORE_LED0_PIN; // 3rd party LED pin define 18 | #else 19 | const int led_pin = 13; // default to pin 13 20 | #endif 21 | #endif 22 | 23 | 24 | void flash() 25 | { 26 | static boolean output = HIGH; 27 | 28 | digitalWrite(led_pin, output); 29 | output = !output; 30 | } 31 | 32 | void setup() 33 | { 34 | pinMode(led_pin, OUTPUT); 35 | 36 | MsTimer2::set(500, flash); // 500ms period 37 | MsTimer2::start(); 38 | } 39 | 40 | void loop() 41 | { 42 | } 43 | -------------------------------------------------------------------------------- /lib/lib/MsTimer2/keywords.txt: -------------------------------------------------------------------------------- 1 | MsTimer2 KEYWORD1 2 | set KEYWORD2 3 | start KEYWORD2 4 | stop KEYWORD2 5 | -------------------------------------------------------------------------------- /lib/lib/SSD1306/SSD1306.cpp: -------------------------------------------------------------------------------- 1 | // some of this code was written by originally; 2 | // it is in the public domain. 3 | 4 | //#include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "SSD1306.h" 10 | #include "glcdfont.c" 11 | 12 | static uint8_t is_reversed = 0; 13 | 14 | // a 5x7 font table 15 | extern const uint8_t PROGMEM font[]; 16 | 17 | // the memory buffer for the LCD 18 | 19 | static uint8_t buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH/8]={ 20 | /*-- 宽度x高度=128x64 Gizwits--*/ 21 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 22 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80, 23 | 0x80,0xC0,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00, 24 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 25 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00, 26 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 27 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 28 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 29 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 30 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xFC,0xFE,0x0F,0x03,0x01,0x01, 31 | 0x01,0xC0,0xC1,0x81,0xC3,0xCF,0x8E,0xC8,0x00,0x00,0x00,0xF9,0xF3,0x00,0x00,0x10, 32 | 0x18,0x18,0x10,0x18,0xD8,0xF0,0xF8,0x38,0x10,0x00,0x78,0xF8,0xC0,0x00,0x00,0xC0, 33 | 0xF8,0x78,0xF0,0x80,0x00,0x00,0xE0,0xF8,0x18,0x00,0x00,0xF9,0xF9,0x00,0x00,0x18, 34 | 0xFF,0xFF,0x18,0x18,0x00,0xA0,0xF0,0xF8,0x98,0x18,0x18,0x18,0x30,0x70,0x00,0x00, 35 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 36 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 37 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 38 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0F,0x1F,0x38,0x70,0x60,0x60, 39 | 0x60,0x40,0x60,0x60,0x30,0x39,0x7F,0x7F,0x00,0x00,0x00,0x7F,0x7F,0x00,0x00,0x60, 40 | 0x78,0x7C,0x6E,0x67,0x63,0x61,0x60,0x60,0x60,0x00,0x00,0x03,0x3F,0x7C,0x78,0x3F, 41 | 0x03,0x00,0x07,0x7F,0x78,0x7E,0x0F,0x01,0x00,0x00,0x00,0x7F,0x7F,0x00,0x00,0x00, 42 | 0x3F,0x7F,0x60,0x60,0x00,0x18,0x39,0x71,0x63,0x43,0xE3,0x67,0x6E,0x3E,0x18,0x00, 43 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 44 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 45 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 46 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 47 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 48 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 49 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 50 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 51 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 52 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 53 | #if(SSD1306_LCDHEIGHT==64) 54 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 55 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 56 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 57 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 58 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 59 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 60 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 61 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 62 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 63 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 64 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 65 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 66 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 67 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 68 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 69 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 70 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 71 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 72 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 73 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 74 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 75 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 76 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 77 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 78 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 79 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 80 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 81 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 82 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 83 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 84 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 85 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 86 | #endif 87 | }; 88 | 89 | void SSD1306::drawbitmap(uint8_t x, uint8_t y, 90 | const uint8_t *bitmap, uint8_t w, uint8_t h, 91 | uint8_t color) { 92 | for (uint8_t j=0; j= SSD1306_LCDWIDTH) { 107 | x = 0; // ran out of this line 108 | line++; 109 | } 110 | if (line >= (SSD1306_LCDHEIGHT/8)) 111 | return; // ran out of space :( 112 | } 113 | 114 | } 115 | 116 | void SSD1306::drawchar(uint8_t x, uint8_t line, uint8_t c) { 117 | if ((line >= SSD1306_LCDHEIGHT/8) || (x >= (SSD1306_LCDWIDTH - 6))) 118 | return; 119 | for (uint8_t i =0; i<5; i++ ) { 120 | buffer[x + (line*128) ] = pgm_read_byte(font+(c*5)+i); 121 | x++; 122 | } 123 | } 124 | 125 | 126 | // bresenham's algorithm - thx wikpedia 127 | void SSD1306::drawline(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, 128 | uint8_t color) { 129 | uint8_t steep = abs(y1 - y0) > abs(x1 - x0); 130 | if (steep) { 131 | swap(x0, y0); 132 | swap(x1, y1); 133 | } 134 | 135 | if (x0 > x1) { 136 | swap(x0, x1); 137 | swap(y0, y1); 138 | } 139 | 140 | uint8_t dx, dy; 141 | dx = x1 - x0; 142 | dy = abs(y1 - y0); 143 | 144 | int8_t err = dx / 2; 145 | int8_t ystep; 146 | 147 | if (y0 < y1) { 148 | ystep = 1; 149 | } else { 150 | ystep = -1;} 151 | 152 | for (; x0= 0) { 208 | y--; 209 | ddF_y += 2; 210 | f += ddF_y; 211 | } 212 | x++; 213 | ddF_x += 2; 214 | f += ddF_x; 215 | 216 | setpixel(x0 + x, y0 + y, color); 217 | setpixel(x0 - x, y0 + y, color); 218 | setpixel(x0 + x, y0 - y, color); 219 | setpixel(x0 - x, y0 - y, color); 220 | 221 | setpixel(x0 + y, y0 + x, color); 222 | setpixel(x0 - y, y0 + x, color); 223 | setpixel(x0 + y, y0 - x, color); 224 | setpixel(x0 - y, y0 - x, color); 225 | 226 | } 227 | } 228 | 229 | void SSD1306::fillcircle(uint8_t x0, uint8_t y0, uint8_t r, 230 | uint8_t color) { 231 | int8_t f = 1 - r; 232 | int8_t ddF_x = 1; 233 | int8_t ddF_y = -2 * r; 234 | int8_t x = 0; 235 | int8_t y = r; 236 | 237 | for (uint8_t i=y0-r; i<=y0+r; i++) { 238 | setpixel(x0, i, color); 239 | } 240 | 241 | while (x= 0) { 243 | y--; 244 | ddF_y += 2; 245 | f += ddF_y; 246 | } 247 | x++; 248 | ddF_x += 2; 249 | f += ddF_x; 250 | 251 | for (uint8_t i=y0-y; i<=y0+y; i++) { 252 | setpixel(x0+x, i, color); 253 | setpixel(x0-x, i, color); 254 | } 255 | for (uint8_t i=y0-x; i<=y0+x; i++) { 256 | setpixel(x0+y, i, color); 257 | setpixel(x0-y, i, color); 258 | } 259 | } 260 | } 261 | 262 | // the most basic function, set a single pixel 263 | void SSD1306::setpixel(uint8_t x, uint8_t y, uint8_t color) { 264 | if ((x >= SSD1306_LCDWIDTH) || (y >= SSD1306_LCDHEIGHT)) 265 | return; 266 | 267 | // x is which column 268 | if (color == WHITE) 269 | buffer[x+ (y/8)*SSD1306_LCDWIDTH] |= _BV((y%8)); 270 | else 271 | buffer[x+ (y/8)*SSD1306_LCDWIDTH] &= ~_BV((y%8)); 272 | 273 | } 274 | 275 | void SSD1306::ssd1306_init(uint8_t vccstate) { 276 | // set pin directions 277 | pinMode(sid, OUTPUT); 278 | pinMode(sclk, OUTPUT); 279 | pinMode(dc, OUTPUT); 280 | pinMode(rst, OUTPUT); 281 | pinMode(cs, OUTPUT); 282 | 283 | digitalWrite(rst, HIGH); 284 | // VDD (3.3V) goes high at start, lets just chill for a ms 285 | delay(1); 286 | // bring0xset low 287 | digitalWrite(rst, LOW); 288 | // wait 10ms 289 | delay(10); 290 | // bring out of reset 291 | digitalWrite(rst, HIGH); 292 | // turn on VCC (9V?) 293 | 294 | #if defined SSD1306_128_32 295 | // Init sequence for 128x32 OLED module 296 | ssd1306_command(SSD1306_DISPLAYOFF); // 0xAE 297 | ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5 298 | ssd1306_command(0x80); // the suggested ratio 0x80 299 | ssd1306_command(SSD1306_SETMULTIPLEX); // 0xA8 300 | ssd1306_command(0x1F); 301 | ssd1306_command(SSD1306_SETDISPLAYOFFSET); // 0xD3 302 | ssd1306_command(0x0); // no offset 303 | ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0 304 | ssd1306_command(SSD1306_CHARGEPUMP); // 0x8D 305 | if (vccstate == SSD1306_EXTERNALVCC) 306 | { ssd1306_command(0x10); } 307 | else 308 | { ssd1306_command(0x14); } 309 | ssd1306_command(SSD1306_MEMORYMODE); // 0x20 310 | ssd1306_command(0x00); // 0x0 act like ks0108 311 | ssd1306_command(SSD1306_SEGREMAP | 0x1); 312 | ssd1306_command(SSD1306_COMSCANDEC); 313 | ssd1306_command(SSD1306_SETCOMPINS); // 0xDA 314 | ssd1306_command(0x02); 315 | ssd1306_command(SSD1306_SETCONTRAST); // 0x81 316 | ssd1306_command(0x8F); 317 | ssd1306_command(SSD1306_SETPRECHARGE); // 0xd9 318 | if (vccstate == SSD1306_EXTERNALVCC) 319 | { ssd1306_command(0x22); } 320 | else 321 | { ssd1306_command(0xF1); } 322 | ssd1306_command(SSD1306_SETVCOMDETECT); // 0xDB 323 | ssd1306_command(0x40); 324 | ssd1306_command(SSD1306_DISPLAYALLON_RESUME); // 0xA4 325 | ssd1306_command(SSD1306_NORMALDISPLAY); // 0xA6 326 | #endif 327 | 328 | #if defined SSD1306_128_64 329 | // Init sequence for 128x64 OLED module 330 | ssd1306_command(SSD1306_DISPLAYOFF); // 0xAE 331 | ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5 332 | ssd1306_command(0x80); // the suggested ratio 0x80 333 | ssd1306_command(SSD1306_SETMULTIPLEX); // 0xA8 334 | ssd1306_command(0x3F); 335 | ssd1306_command(SSD1306_SETDISPLAYOFFSET); // 0xD3 336 | ssd1306_command(0x0); // no offset 337 | ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0 338 | ssd1306_command(SSD1306_CHARGEPUMP); // 0x8D 339 | if (vccstate == SSD1306_EXTERNALVCC) 340 | { ssd1306_command(0x10); } 341 | else 342 | { ssd1306_command(0x14); } 343 | ssd1306_command(SSD1306_MEMORYMODE); // 0x20 344 | ssd1306_command(0x00); // 0x0 act like ks0108 345 | ssd1306_command(SSD1306_SEGREMAP | 0x1); 346 | ssd1306_command(SSD1306_COMSCANDEC); 347 | ssd1306_command(SSD1306_SETCOMPINS); // 0xDA 348 | ssd1306_command(0x12); 349 | ssd1306_command(SSD1306_SETCONTRAST); // 0x81 350 | if (vccstate == SSD1306_EXTERNALVCC) 351 | { ssd1306_command(0x9F); } 352 | else 353 | { ssd1306_command(0xCF); } 354 | ssd1306_command(SSD1306_SETPRECHARGE); // 0xd9 355 | if (vccstate == SSD1306_EXTERNALVCC) 356 | { ssd1306_command(0x22); } 357 | else 358 | { ssd1306_command(0xF1); } 359 | ssd1306_command(SSD1306_SETVCOMDETECT); // 0xDB 360 | ssd1306_command(0x40); 361 | ssd1306_command(SSD1306_DISPLAYALLON_RESUME); // 0xA4 362 | ssd1306_command(SSD1306_NORMALDISPLAY); // 0xA6 363 | #endif 364 | 365 | ssd1306_command(SSD1306_DISPLAYON);//--turn on oled panel 366 | } 367 | 368 | 369 | void SSD1306::invert(uint8_t i) { 370 | if (i) { 371 | ssd1306_command(SSD1306_INVERTDISPLAY); 372 | } else { 373 | ssd1306_command(SSD1306_NORMALDISPLAY); 374 | } 375 | } 376 | 377 | inline void SSD1306::spiwrite(uint8_t c) { 378 | shiftOut(sid, sclk, MSBFIRST, c); 379 | 380 | } 381 | void SSD1306::ssd1306_command(uint8_t c) { 382 | digitalWrite(cs, HIGH); 383 | digitalWrite(dc, LOW); 384 | digitalWrite(cs, LOW); 385 | spiwrite(c); 386 | digitalWrite(cs, HIGH); 387 | } 388 | 389 | void SSD1306::ssd1306_data(uint8_t c) { 390 | digitalWrite(cs, HIGH); 391 | digitalWrite(dc, HIGH); 392 | digitalWrite(cs, LOW); 393 | spiwrite(c); 394 | digitalWrite(cs, HIGH); 395 | } 396 | 397 | void SSD1306::ssd1306_set_brightness(uint8_t val) { 398 | 399 | } 400 | 401 | 402 | void SSD1306::display(void) { 403 | ssd1306_command(SSD1306_SETLOWCOLUMN | 0x0); // low col = 0 404 | ssd1306_command(SSD1306_SETHIGHCOLUMN | 0x0); // hi col = 0 405 | ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0 406 | 407 | for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) { 408 | ssd1306_data(buffer[i]); 409 | } 410 | // i wonder why we have to do this (check datasheet) 411 | if (SSD1306_LCDHEIGHT == 32) { 412 | for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) { 413 | ssd1306_data(0); 414 | } 415 | } 416 | } 417 | 418 | // clear everything 419 | void SSD1306::clear(void) { 420 | memset(buffer, 0, (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8)); 421 | } 422 | 423 | void SSD1306::clear_display(void) { 424 | clear(); 425 | display(); 426 | } 427 | -------------------------------------------------------------------------------- /lib/lib/SSD1306/SSD1306.h: -------------------------------------------------------------------------------- 1 | #if ARDUINO >= 100 2 | #include "Arduino.h" 3 | #else 4 | #include "WProgram.h" 5 | #endif 6 | 7 | #define swap(a, b) { uint8_t t = a; a = b; b = t; } 8 | 9 | #define BLACK 0 10 | #define WHITE 1 11 | 12 | /*========================================================================= 13 | SSD1306 Displays 14 | ----------------------------------------------------------------------- 15 | The driver is used in multiple displays (128x64, 128x32, etc.). 16 | Select the appropriate display below to create an appropriately 17 | sized framebuffer, etc. 18 | 19 | SSD1306_128_64 128x64 pixel display 20 | 21 | SSD1306_128_32 128x32 pixel display 22 | 23 | You also need to set the LCDWIDTH and LCDHEIGHT defines to an 24 | appropriate size 25 | 26 | -----------------------------------------------------------------------*/ 27 | #define SSD1306_128_64 28 | // #define SSD1306_128_32 29 | /*=========================================================================*/ 30 | 31 | #if defined SSD1306_128_64 && defined SSD1306_128_32 32 | #error "Only one SSD1306 display can be specified at once in SSD1306.h" 33 | #endif 34 | #if !defined SSD1306_128_64 && !defined SSD1306_128_32 35 | #error "At least one SSD1306 display must be specified in SSD1306.h" 36 | #endif 37 | 38 | #if defined SSD1306_128_64 39 | #define SSD1306_LCDWIDTH 128 40 | #define SSD1306_LCDHEIGHT 32 41 | #endif 42 | #if defined SSD1306_128_32 43 | #define SSD1306_LCDWIDTH 128 44 | #define SSD1306_LCDHEIGHT 32 45 | #endif 46 | 47 | #define SSD1306_SETCONTRAST 0x81 48 | #define SSD1306_DISPLAYALLON_RESUME 0xA4 49 | #define SSD1306_DISPLAYALLON 0xA5 50 | #define SSD1306_NORMALDISPLAY 0xA6 51 | #define SSD1306_INVERTDISPLAY 0xA7 52 | #define SSD1306_DISPLAYOFF 0xAE 53 | #define SSD1306_DISPLAYON 0xAF 54 | 55 | #define SSD1306_SETDISPLAYOFFSET 0xD3 56 | #define SSD1306_SETCOMPINS 0xDA 57 | 58 | #define SSD1306_SETVCOMDETECT 0xDB 59 | 60 | #define SSD1306_SETDISPLAYCLOCKDIV 0xD5 61 | #define SSD1306_SETPRECHARGE 0xD9 62 | 63 | #define SSD1306_SETMULTIPLEX 0xA8 64 | 65 | #define SSD1306_SETLOWCOLUMN 0x00 66 | #define SSD1306_SETHIGHCOLUMN 0x10 67 | 68 | #define SSD1306_SETSTARTLINE 0x40 69 | 70 | #define SSD1306_MEMORYMODE 0x20 71 | 72 | #define SSD1306_COMSCANINC 0xC0 73 | #define SSD1306_COMSCANDEC 0xC8 74 | 75 | #define SSD1306_SEGREMAP 0xA0 76 | 77 | #define SSD1306_CHARGEPUMP 0x8D 78 | 79 | #define SSD1306_EXTERNALVCC 0x1 80 | #define SSD1306_SWITCHCAPVCC 0x2 81 | 82 | class SSD1306 { 83 | public: 84 | SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS) :sid(SID), sclk(SCLK), dc(DC), rst(RST), cs(CS) {} 85 | SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST) :sid(SID), sclk(SCLK), dc(DC), rst(RST), cs(-1) {} 86 | 87 | 88 | void ssd1306_init(uint8_t switchvcc); 89 | void ssd1306_command(uint8_t c); 90 | void ssd1306_data(uint8_t c); 91 | void ssd1306_set_brightness(uint8_t val); 92 | void clear_display(void); 93 | void clear(); 94 | void invert(uint8_t i); 95 | void display(); 96 | 97 | void setpixel(uint8_t x, uint8_t y, uint8_t color); 98 | void fillcircle(uint8_t x0, uint8_t y0, uint8_t r, 99 | uint8_t color); 100 | void drawcircle(uint8_t x0, uint8_t y0, uint8_t r, 101 | uint8_t color); 102 | void drawrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, 103 | uint8_t color); 104 | void fillrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, 105 | uint8_t color); 106 | void drawline(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, 107 | uint8_t color); 108 | void drawchar(uint8_t x, uint8_t line, uint8_t c); 109 | void drawstring(uint8_t x, uint8_t line, char *c); 110 | 111 | void drawbitmap(uint8_t x, uint8_t y, 112 | const uint8_t *bitmap, uint8_t w, uint8_t h, 113 | uint8_t color); 114 | 115 | private: 116 | int8_t sid, sclk, dc, rst, cs; 117 | void spiwrite(uint8_t c); 118 | 119 | //uint8_t buffer[128*64/8]; 120 | }; 121 | -------------------------------------------------------------------------------- /lib/lib/SSD1306/glcdfont.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef FONT5X7_H 5 | #define FONT5X7_H 6 | 7 | // standard ascii 5x7 font 8 | 9 | static const unsigned char __attribute__ ((progmem)) font[] PROGMEM = { 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 12 | 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 13 | 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 14 | 0x18, 0x3C, 0x7E, 0x3C, 0x18, 15 | 0x1C, 0x57, 0x7D, 0x57, 0x1C, 16 | 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 17 | 0x00, 0x18, 0x3C, 0x18, 0x00, 18 | 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 19 | 0x00, 0x18, 0x24, 0x18, 0x00, 20 | 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 21 | 0x30, 0x48, 0x3A, 0x06, 0x0E, 22 | 0x26, 0x29, 0x79, 0x29, 0x26, 23 | 0x40, 0x7F, 0x05, 0x05, 0x07, 24 | 0x40, 0x7F, 0x05, 0x25, 0x3F, 25 | 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 26 | 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 27 | 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 28 | 0x14, 0x22, 0x7F, 0x22, 0x14, 29 | 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 30 | 0x06, 0x09, 0x7F, 0x01, 0x7F, 31 | 0x00, 0x66, 0x89, 0x95, 0x6A, 32 | 0x60, 0x60, 0x60, 0x60, 0x60, 33 | 0x94, 0xA2, 0xFF, 0xA2, 0x94, 34 | 0x08, 0x04, 0x7E, 0x04, 0x08, 35 | 0x10, 0x20, 0x7E, 0x20, 0x10, 36 | 0x08, 0x08, 0x2A, 0x1C, 0x08, 37 | 0x08, 0x1C, 0x2A, 0x08, 0x08, 38 | 0x1E, 0x10, 0x10, 0x10, 0x10, 39 | 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 40 | 0x30, 0x38, 0x3E, 0x38, 0x30, 41 | 0x06, 0x0E, 0x3E, 0x0E, 0x06, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x5F, 0x00, 0x00, 44 | 0x00, 0x07, 0x00, 0x07, 0x00, 45 | 0x14, 0x7F, 0x14, 0x7F, 0x14, 46 | 0x24, 0x2A, 0x7F, 0x2A, 0x12, 47 | 0x23, 0x13, 0x08, 0x64, 0x62, 48 | 0x36, 0x49, 0x56, 0x20, 0x50, 49 | 0x00, 0x08, 0x07, 0x03, 0x00, 50 | 0x00, 0x1C, 0x22, 0x41, 0x00, 51 | 0x00, 0x41, 0x22, 0x1C, 0x00, 52 | 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 53 | 0x08, 0x08, 0x3E, 0x08, 0x08, 54 | 0x00, 0x80, 0x70, 0x30, 0x00, 55 | 0x08, 0x08, 0x08, 0x08, 0x08, 56 | 0x00, 0x00, 0x60, 0x60, 0x00, 57 | 0x20, 0x10, 0x08, 0x04, 0x02, 58 | 0x3E, 0x51, 0x49, 0x45, 0x3E, 59 | 0x00, 0x42, 0x7F, 0x40, 0x00, 60 | 0x72, 0x49, 0x49, 0x49, 0x46, 61 | 0x21, 0x41, 0x49, 0x4D, 0x33, 62 | 0x18, 0x14, 0x12, 0x7F, 0x10, 63 | 0x27, 0x45, 0x45, 0x45, 0x39, 64 | 0x3C, 0x4A, 0x49, 0x49, 0x31, 65 | 0x41, 0x21, 0x11, 0x09, 0x07, 66 | 0x36, 0x49, 0x49, 0x49, 0x36, 67 | 0x46, 0x49, 0x49, 0x29, 0x1E, 68 | 0x00, 0x00, 0x14, 0x00, 0x00, 69 | 0x00, 0x40, 0x34, 0x00, 0x00, 70 | 0x00, 0x08, 0x14, 0x22, 0x41, 71 | 0x14, 0x14, 0x14, 0x14, 0x14, 72 | 0x00, 0x41, 0x22, 0x14, 0x08, 73 | 0x02, 0x01, 0x59, 0x09, 0x06, 74 | 0x3E, 0x41, 0x5D, 0x59, 0x4E, 75 | 0x7C, 0x12, 0x11, 0x12, 0x7C, 76 | 0x7F, 0x49, 0x49, 0x49, 0x36, 77 | 0x3E, 0x41, 0x41, 0x41, 0x22, 78 | 0x7F, 0x41, 0x41, 0x41, 0x3E, 79 | 0x7F, 0x49, 0x49, 0x49, 0x41, 80 | 0x7F, 0x09, 0x09, 0x09, 0x01, 81 | 0x3E, 0x41, 0x41, 0x51, 0x73, 82 | 0x7F, 0x08, 0x08, 0x08, 0x7F, 83 | 0x00, 0x41, 0x7F, 0x41, 0x00, 84 | 0x20, 0x40, 0x41, 0x3F, 0x01, 85 | 0x7F, 0x08, 0x14, 0x22, 0x41, 86 | 0x7F, 0x40, 0x40, 0x40, 0x40, 87 | 0x7F, 0x02, 0x1C, 0x02, 0x7F, 88 | 0x7F, 0x04, 0x08, 0x10, 0x7F, 89 | 0x3E, 0x41, 0x41, 0x41, 0x3E, 90 | 0x7F, 0x09, 0x09, 0x09, 0x06, 91 | 0x3E, 0x41, 0x51, 0x21, 0x5E, 92 | 0x7F, 0x09, 0x19, 0x29, 0x46, 93 | 0x26, 0x49, 0x49, 0x49, 0x32, 94 | 0x03, 0x01, 0x7F, 0x01, 0x03, 95 | 0x3F, 0x40, 0x40, 0x40, 0x3F, 96 | 0x1F, 0x20, 0x40, 0x20, 0x1F, 97 | 0x3F, 0x40, 0x38, 0x40, 0x3F, 98 | 0x63, 0x14, 0x08, 0x14, 0x63, 99 | 0x03, 0x04, 0x78, 0x04, 0x03, 100 | 0x61, 0x59, 0x49, 0x4D, 0x43, 101 | 0x00, 0x7F, 0x41, 0x41, 0x41, 102 | 0x02, 0x04, 0x08, 0x10, 0x20, 103 | 0x00, 0x41, 0x41, 0x41, 0x7F, 104 | 0x04, 0x02, 0x01, 0x02, 0x04, 105 | 0x40, 0x40, 0x40, 0x40, 0x40, 106 | 0x00, 0x03, 0x07, 0x08, 0x00, 107 | 0x20, 0x54, 0x54, 0x78, 0x40, 108 | 0x7F, 0x28, 0x44, 0x44, 0x38, 109 | 0x38, 0x44, 0x44, 0x44, 0x28, 110 | 0x38, 0x44, 0x44, 0x28, 0x7F, 111 | 0x38, 0x54, 0x54, 0x54, 0x18, 112 | 0x00, 0x08, 0x7E, 0x09, 0x02, 113 | 0x18, 0xA4, 0xA4, 0x9C, 0x78, 114 | 0x7F, 0x08, 0x04, 0x04, 0x78, 115 | 0x00, 0x44, 0x7D, 0x40, 0x00, 116 | 0x20, 0x40, 0x40, 0x3D, 0x00, 117 | 0x7F, 0x10, 0x28, 0x44, 0x00, 118 | 0x00, 0x41, 0x7F, 0x40, 0x00, 119 | 0x7C, 0x04, 0x78, 0x04, 0x78, 120 | 0x7C, 0x08, 0x04, 0x04, 0x78, 121 | 0x38, 0x44, 0x44, 0x44, 0x38, 122 | 0xFC, 0x18, 0x24, 0x24, 0x18, 123 | 0x18, 0x24, 0x24, 0x18, 0xFC, 124 | 0x7C, 0x08, 0x04, 0x04, 0x08, 125 | 0x48, 0x54, 0x54, 0x54, 0x24, 126 | 0x04, 0x04, 0x3F, 0x44, 0x24, 127 | 0x3C, 0x40, 0x40, 0x20, 0x7C, 128 | 0x1C, 0x20, 0x40, 0x20, 0x1C, 129 | 0x3C, 0x40, 0x30, 0x40, 0x3C, 130 | 0x44, 0x28, 0x10, 0x28, 0x44, 131 | 0x4C, 0x90, 0x90, 0x90, 0x7C, 132 | 0x44, 0x64, 0x54, 0x4C, 0x44, 133 | 0x00, 0x08, 0x36, 0x41, 0x00, 134 | 0x00, 0x00, 0x77, 0x00, 0x00, 135 | 0x00, 0x41, 0x36, 0x08, 0x00, 136 | 0x02, 0x01, 0x02, 0x04, 0x02, 137 | 0x3C, 0x26, 0x23, 0x26, 0x3C, 138 | 0x1E, 0xA1, 0xA1, 0x61, 0x12, 139 | 0x3A, 0x40, 0x40, 0x20, 0x7A, 140 | 0x38, 0x54, 0x54, 0x55, 0x59, 141 | 0x21, 0x55, 0x55, 0x79, 0x41, 142 | 0x21, 0x54, 0x54, 0x78, 0x41, 143 | 0x21, 0x55, 0x54, 0x78, 0x40, 144 | 0x20, 0x54, 0x55, 0x79, 0x40, 145 | 0x0C, 0x1E, 0x52, 0x72, 0x12, 146 | 0x39, 0x55, 0x55, 0x55, 0x59, 147 | 0x39, 0x54, 0x54, 0x54, 0x59, 148 | 0x39, 0x55, 0x54, 0x54, 0x58, 149 | 0x00, 0x00, 0x45, 0x7C, 0x41, 150 | 0x00, 0x02, 0x45, 0x7D, 0x42, 151 | 0x00, 0x01, 0x45, 0x7C, 0x40, 152 | 0xF0, 0x29, 0x24, 0x29, 0xF0, 153 | 0xF0, 0x28, 0x25, 0x28, 0xF0, 154 | 0x7C, 0x54, 0x55, 0x45, 0x00, 155 | 0x20, 0x54, 0x54, 0x7C, 0x54, 156 | 0x7C, 0x0A, 0x09, 0x7F, 0x49, 157 | 0x32, 0x49, 0x49, 0x49, 0x32, 158 | 0x32, 0x48, 0x48, 0x48, 0x32, 159 | 0x32, 0x4A, 0x48, 0x48, 0x30, 160 | 0x3A, 0x41, 0x41, 0x21, 0x7A, 161 | 0x3A, 0x42, 0x40, 0x20, 0x78, 162 | 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 163 | 0x39, 0x44, 0x44, 0x44, 0x39, 164 | 0x3D, 0x40, 0x40, 0x40, 0x3D, 165 | 0x3C, 0x24, 0xFF, 0x24, 0x24, 166 | 0x48, 0x7E, 0x49, 0x43, 0x66, 167 | 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 168 | 0xFF, 0x09, 0x29, 0xF6, 0x20, 169 | 0xC0, 0x88, 0x7E, 0x09, 0x03, 170 | 0x20, 0x54, 0x54, 0x79, 0x41, 171 | 0x00, 0x00, 0x44, 0x7D, 0x41, 172 | 0x30, 0x48, 0x48, 0x4A, 0x32, 173 | 0x38, 0x40, 0x40, 0x22, 0x7A, 174 | 0x00, 0x7A, 0x0A, 0x0A, 0x72, 175 | 0x7D, 0x0D, 0x19, 0x31, 0x7D, 176 | 0x26, 0x29, 0x29, 0x2F, 0x28, 177 | 0x26, 0x29, 0x29, 0x29, 0x26, 178 | 0x30, 0x48, 0x4D, 0x40, 0x20, 179 | 0x38, 0x08, 0x08, 0x08, 0x08, 180 | 0x08, 0x08, 0x08, 0x08, 0x38, 181 | 0x2F, 0x10, 0xC8, 0xAC, 0xBA, 182 | 0x2F, 0x10, 0x28, 0x34, 0xFA, 183 | 0x00, 0x00, 0x7B, 0x00, 0x00, 184 | 0x08, 0x14, 0x2A, 0x14, 0x22, 185 | 0x22, 0x14, 0x2A, 0x14, 0x08, 186 | 0xAA, 0x00, 0x55, 0x00, 0xAA, 187 | 0xAA, 0x55, 0xAA, 0x55, 0xAA, 188 | 0x00, 0x00, 0x00, 0xFF, 0x00, 189 | 0x10, 0x10, 0x10, 0xFF, 0x00, 190 | 0x14, 0x14, 0x14, 0xFF, 0x00, 191 | 0x10, 0x10, 0xFF, 0x00, 0xFF, 192 | 0x10, 0x10, 0xF0, 0x10, 0xF0, 193 | 0x14, 0x14, 0x14, 0xFC, 0x00, 194 | 0x14, 0x14, 0xF7, 0x00, 0xFF, 195 | 0x00, 0x00, 0xFF, 0x00, 0xFF, 196 | 0x14, 0x14, 0xF4, 0x04, 0xFC, 197 | 0x14, 0x14, 0x17, 0x10, 0x1F, 198 | 0x10, 0x10, 0x1F, 0x10, 0x1F, 199 | 0x14, 0x14, 0x14, 0x1F, 0x00, 200 | 0x10, 0x10, 0x10, 0xF0, 0x00, 201 | 0x00, 0x00, 0x00, 0x1F, 0x10, 202 | 0x10, 0x10, 0x10, 0x1F, 0x10, 203 | 0x10, 0x10, 0x10, 0xF0, 0x10, 204 | 0x00, 0x00, 0x00, 0xFF, 0x10, 205 | 0x10, 0x10, 0x10, 0x10, 0x10, 206 | 0x10, 0x10, 0x10, 0xFF, 0x10, 207 | 0x00, 0x00, 0x00, 0xFF, 0x14, 208 | 0x00, 0x00, 0xFF, 0x00, 0xFF, 209 | 0x00, 0x00, 0x1F, 0x10, 0x17, 210 | 0x00, 0x00, 0xFC, 0x04, 0xF4, 211 | 0x14, 0x14, 0x17, 0x10, 0x17, 212 | 0x14, 0x14, 0xF4, 0x04, 0xF4, 213 | 0x00, 0x00, 0xFF, 0x00, 0xF7, 214 | 0x14, 0x14, 0x14, 0x14, 0x14, 215 | 0x14, 0x14, 0xF7, 0x00, 0xF7, 216 | 0x14, 0x14, 0x14, 0x17, 0x14, 217 | 0x10, 0x10, 0x1F, 0x10, 0x1F, 218 | 0x14, 0x14, 0x14, 0xF4, 0x14, 219 | 0x10, 0x10, 0xF0, 0x10, 0xF0, 220 | 0x00, 0x00, 0x1F, 0x10, 0x1F, 221 | 0x00, 0x00, 0x00, 0x1F, 0x14, 222 | 0x00, 0x00, 0x00, 0xFC, 0x14, 223 | 0x00, 0x00, 0xF0, 0x10, 0xF0, 224 | 0x10, 0x10, 0xFF, 0x10, 0xFF, 225 | 0x14, 0x14, 0x14, 0xFF, 0x14, 226 | 0x10, 0x10, 0x10, 0x1F, 0x00, 227 | 0x00, 0x00, 0x00, 0xF0, 0x10, 228 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 229 | 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 230 | 0xFF, 0xFF, 0xFF, 0x00, 0x00, 231 | 0x00, 0x00, 0x00, 0xFF, 0xFF, 232 | 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 233 | 0x38, 0x44, 0x44, 0x38, 0x44, 234 | 0x7C, 0x2A, 0x2A, 0x3E, 0x14, 235 | 0x7E, 0x02, 0x02, 0x06, 0x06, 236 | 0x02, 0x7E, 0x02, 0x7E, 0x02, 237 | 0x63, 0x55, 0x49, 0x41, 0x63, 238 | 0x38, 0x44, 0x44, 0x3C, 0x04, 239 | 0x40, 0x7E, 0x20, 0x1E, 0x20, 240 | 0x06, 0x02, 0x7E, 0x02, 0x02, 241 | 0x99, 0xA5, 0xE7, 0xA5, 0x99, 242 | 0x1C, 0x2A, 0x49, 0x2A, 0x1C, 243 | 0x4C, 0x72, 0x01, 0x72, 0x4C, 244 | 0x30, 0x4A, 0x4D, 0x4D, 0x30, 245 | 0x30, 0x48, 0x78, 0x48, 0x30, 246 | 0xBC, 0x62, 0x5A, 0x46, 0x3D, 247 | 0x3E, 0x49, 0x49, 0x49, 0x00, 248 | 0x7E, 0x01, 0x01, 0x01, 0x7E, 249 | 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 250 | 0x44, 0x44, 0x5F, 0x44, 0x44, 251 | 0x40, 0x51, 0x4A, 0x44, 0x40, 252 | 0x40, 0x44, 0x4A, 0x51, 0x40, 253 | 0x00, 0x00, 0xFF, 0x01, 0x03, 254 | 0xE0, 0x80, 0xFF, 0x00, 0x00, 255 | 0x08, 0x08, 0x6B, 0x6B, 0x08, 256 | 0x36, 0x12, 0x36, 0x24, 0x36, 257 | 0x06, 0x0F, 0x09, 0x0F, 0x06, 258 | 0x00, 0x00, 0x18, 0x18, 0x00, 259 | 0x00, 0x00, 0x10, 0x10, 0x00, 260 | 0x30, 0x40, 0xFF, 0x01, 0x01, 261 | 0x00, 0x1F, 0x01, 0x01, 0x1E, 262 | 0x00, 0x19, 0x1D, 0x17, 0x12, 263 | 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 264 | 0x00, 0x00, 0x00, 0x00, 0x00, 265 | }; 266 | #endif 267 | -------------------------------------------------------------------------------- /protocol.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "protocol.h" 4 | 5 | #include "GoKit.h" 6 | extern SSD1306 oled; 7 | 8 | unsigned long check_status_time=0; 9 | unsigned long report_status_idle_time=0; 10 | 11 | unsigned char CheckSum( unsigned char *buf, int packLen ) 12 | { 13 | int i; 14 | unsigned char sum; 15 | 16 | if(buf == NULL || packLen <= 0) return 0; 17 | 18 | sum = 0; 19 | for(i=2; i> 1; 60 | // ʹÓÃcmd_byteµÄµÚ2ºÍ3룬00:user define, 01: yellow, 10: purple, 11: pink 61 | 62 | if(tmp_cmd_buf == 0x00) 63 | { 64 | gokit_setColorRGB(m_w2m_controlMcu.status_w.led_r, m_m2w_mcuStatus.status_w.led_g, m_m2w_mcuStatus.status_w.led_b); 65 | m_m2w_mcuStatus.status_w.cmd_byte = (m_m2w_mcuStatus.status_w.cmd_byte & 0xF9); 66 | } 67 | else if(tmp_cmd_buf == 0x01) 68 | { 69 | gokit_setColorRGB(254, 70, 0); 70 | m_m2w_mcuStatus.status_w.cmd_byte = (m_m2w_mcuStatus.status_w.cmd_byte | 0x02); 71 | m_m2w_mcuStatus.status_w.cmd_byte = (m_m2w_mcuStatus.status_w.cmd_byte & 0xFB); 72 | } 73 | else if(tmp_cmd_buf == 0x02) 74 | { 75 | gokit_setColorRGB(254, 0, 70); 76 | m_m2w_mcuStatus.status_w.cmd_byte = (m_m2w_mcuStatus.status_w.cmd_byte | 0x04); 77 | m_m2w_mcuStatus.status_w.cmd_byte = (m_m2w_mcuStatus.status_w.cmd_byte & 0xFD); 78 | } 79 | else if(tmp_cmd_buf == 0x03) 80 | { 81 | gokit_setColorRGB(238, 30, 30); 82 | m_m2w_mcuStatus.status_w.cmd_byte = (m_m2w_mcuStatus.status_w.cmd_byte | 0x06); 83 | } 84 | } 85 | 86 | tmp_cmd_buf = (m_m2w_mcuStatus.status_w.cmd_byte & 0x06) >> 1; 87 | 88 | if((m_w2m_controlMcu.cmd_tag & 0x04) == 0x04) 89 | { 90 | 91 | if(tmp_cmd_buf == 0x00){ 92 | gokit_setColorRGB(m_w2m_controlMcu.status_w.led_r, m_m2w_mcuStatus.status_w.led_g, m_m2w_mcuStatus.status_w.led_b); 93 | m_m2w_mcuStatus.status_w.led_r = m_w2m_controlMcu.status_w.led_r; 94 | } 95 | } 96 | 97 | if((m_w2m_controlMcu.cmd_tag & 0x08) == 0x08) 98 | { 99 | //µ±LED×éºÏÑÕɫΪÓû§×Ô¶¨ÒåʱÉúЧ 100 | if(tmp_cmd_buf == 0x00){ 101 | gokit_setColorRGB(m_m2w_mcuStatus.status_w.led_r, m_w2m_controlMcu.status_w.led_g, m_m2w_mcuStatus.status_w.led_b); 102 | m_m2w_mcuStatus.status_w.led_g = m_w2m_controlMcu.status_w.led_g; 103 | } 104 | } 105 | 106 | //¿ØÖÆ LED B 107 | if((m_w2m_controlMcu.cmd_tag & 0x10) == 0x10) 108 | { 109 | //µ±LED×éºÏÑÕɫΪÓû§×Ô¶¨ÒåʱÉúЧ 110 | if(tmp_cmd_buf == 0x00){ 111 | gokit_setColorRGB(m_m2w_mcuStatus.status_w.led_r, m_m2w_mcuStatus.status_w.led_g, m_w2m_controlMcu.status_w.led_b); 112 | m_m2w_mcuStatus.status_w.led_b = m_w2m_controlMcu.status_w.led_b; 113 | } 114 | } 115 | 116 | //¿ØÖƵç»ú 117 | if((m_w2m_controlMcu.cmd_tag & 0x20) == 0x20) 118 | { 119 | gokit_motorstatus(m_w2m_controlMcu.status_w.motor_speed); 120 | m_m2w_mcuStatus.status_w.motor_speed = m_w2m_controlMcu.status_w.motor_speed; 121 | } 122 | 123 | gokit_ReportStatus(REPORT_STATUS); 124 | } 125 | } 126 | void Handle_uartdata(unsigned char *buf,int len) 127 | { 128 | if( len < 4 ) return ; 129 | 130 | pro_headPart tmp_headPart; 131 | memset(&tmp_headPart, 0, sizeof(pro_headPart)); 132 | memcpy(&tmp_headPart, buf, sizeof(pro_headPart)); 133 | if(CheckSum(buf,len)!=buf[len-1]) 134 | { 135 | SendErrorCmd(ERROR_CHECKSUM, tmp_headPart.sn); 136 | #if(DEBUG==1) 137 | Serial.println("CheckSum error!"); 138 | mySerial.println("CheckSum error!"); 139 | #endif 140 | return ; 141 | } 142 | #if(DEBUG==1) 143 | Serial.print("sn = "); 144 | Serial.println(tmp_headPart.sn); 145 | 146 | mySerial.println("receive:"); 147 | for (int i = 0; i < len; ++i) 148 | { 149 | mySerial.print(" "); mySerial.print(buf[i],HEX); 150 | } 151 | mySerial.println(""); 152 | #endif 153 | switch( tmp_headPart.cmd ) 154 | { 155 | 156 | case CMD_GET_MCU_INFO : 157 | #if(DEBUG==1) 158 | Serial.println("CMD_GET_MCU_INFO"); 159 | mySerial.println("CMD_GET_MCU_INFO"); 160 | #endif 161 | CmdGetMcuInfo(tmp_headPart.sn); 162 | 163 | break; 164 | 165 | case CMD_SEND_MCU_P0 : 166 | #if(DEBUG==1) 167 | Serial.println("CMD_SEND_MCU_P0"); 168 | mySerial.println("CMD_SEND_MCU_P0"); 169 | #endif 170 | CmdSendMcuP0(buf); 171 | break; 172 | case CMD_SEND_HEARTBEAT: 173 | #if(DEBUG==1) 174 | Serial.println("CMD_SEND_HEARTBEAT"); 175 | mySerial.println("CMD_SEND_HEARTBEAT"); 176 | #endif 177 | SendCommonCmd(CMD_SEND_HEARTBEAT_ACK,tmp_headPart.sn); 178 | break; 179 | /* 180 | case CMD_REPORT_MODULE_STATUS: 181 | #if(DEBUG==1) 182 | Serial.println("CMD_REPORT_MODULE_STATUS"); 183 | #endif 184 | break; 185 | */ 186 | default: 187 | #if(DEBUG==1) 188 | //Serial.println("default"); 189 | #endif 190 | //SendErrorCmd(ERROR_CMD, tmp_headPart.sn); 191 | break; 192 | } 193 | 194 | } 195 | void Handle_keyeven() 196 | { 197 | /* 长按是指按住按键3s以上 */ 198 | switch(gokit_keydown()) 199 | { 200 | case KEY1_SHORT_PRESS: 201 | #if (DEBUG==1) 202 | Serial.println("KEY1_SHORT_PRESS"); 203 | #endif 204 | 205 | break; 206 | case KEY1_LONG_PRESS: 207 | #if (DEBUG==1) 208 | Serial.println("KEY1_LONG_PRESS"); 209 | #endif 210 | gokit_ResetWiFi(); 211 | break; 212 | case KEY2_SHORT_PRESS: 213 | #if (DEBUG==1) 214 | Serial.println("KEY2_SHORT_PRESS"); 215 | #endif 216 | gokit_sendAirlink(); 217 | break; 218 | case KEY2_LONG_PRESS: 219 | #if (DEBUG==1) 220 | Serial.println("KEY2_LONG_PRESS"); 221 | #endif 222 | gokit_sendApCmd(); 223 | break; 224 | default: break; 225 | } 226 | //KEY1 : D6 227 | //KEY2 : D7 228 | } 229 | void Check_Status() 230 | { 231 | int i, diff; 232 | uint8_t *index_new, *index_old; 233 | 234 | diff = 0; 235 | gokit_DHT11_Read_Data(&m_m2w_mcuStatus.status_r.temputure, &m_m2w_mcuStatus.status_r.humidity); 236 | 237 | if(gokit_time_s()-check_status_time < 10 ) return ; 238 | 239 | check_status_time = gokit_time_s(); 240 | index_new = (uint8_t *)&(m_m2w_mcuStatus.status_w); 241 | index_old = (uint8_t *)&(m_m2w_mcuStatus_reported.status_w); 242 | 243 | for(i=0; i 0 || gokit_time_s()-report_status_idle_time > GOKIT_REPORT_TIME) 276 | { 277 | gokit_ReportStatus(REPORT_STATUS); 278 | report_status_idle_time = gokit_time_s(); 279 | } 280 | 281 | } 282 | void GoKit_Handle() 283 | { 284 | Handle_uartdata( uart_buf,get_onepackage(uart_buf)); 285 | Handle_keyeven(); 286 | Check_Status(); 287 | } 288 | 289 | -------------------------------------------------------------------------------- /protocol.h: -------------------------------------------------------------------------------- 1 | #ifndef _PROTOCOL_H 2 | #define _PROTOCOL_H 3 | #include 4 | #include 5 | #include 6 | 7 | #define REPORT_STATUS 0x00 8 | #define REQUEST_STATUS 0x01 9 | 10 | #define ERROR_CHECKSUM 0x01 11 | #define ERROR_CMD 0x02 12 | #define ERROR_OTHER 0x03 13 | 14 | #define CMD_GET_MCU_INFO 0x01 15 | #define CMD_GET_MCU_INFO_ACK 0x02 16 | #define CMD_SEND_MCU_P0 0x03 17 | #define CMD_SEND_MCU_P0_ACK 0x04 18 | #define CMD_SEND_MODULE_P0 0x05 19 | #define CMD_SEND_MODULE_P0_ACK 0x06 20 | #define CMD_SEND_HEARTBEAT 0x07 21 | #define CMD_SEND_HEARTBEAT_ACK 0x08 22 | #define CMD_SET_MODULE_WORKMODE 0x09 23 | #define CMD_SET_MODULE_WORKMODE_ACK 0x0A 24 | #define CMD_RESET_MODULE 0x0B 25 | #define CMD_RESET_MODULE_ACK 0x0C 26 | #define CMD_REPORT_MODULE_STATUS 0x0D 27 | #define CMD_REPORT_MODULE_STATUS_ACK 0x0E 28 | #define CMD_REBOOT_MCU 0x0F 29 | #define CMD_REBOOT_MCU_ACK 0x10 30 | #define CMD_MODULE_CMD_ERROR_ACK 0x11 31 | #define CMD_MCU_CMD_ERROR_ACK 0x12 32 | 33 | #define SUB_CMD_CONTROL_MCU 0x01 34 | #define SUB_CMD_REQUIRE_STATUS 0x02 35 | #define SUB_CMD_REQUIRE_STATUS_ACK 0x03 36 | #define SUB_CMD_REPORT_MCU_STATUS 0x04 37 | 38 | #define GOKIT_REPORT_TIME 10 // 20s 39 | #define PASSCODE_TIME 0 40 | 41 | 42 | #define PRO_VER "00000004" 43 | #define P0_VER "00000004" 44 | #define HARD_VER "00000001" 45 | #define SOFT_VER "00000001" 46 | #define PRODUCT_KEY "6f3074fe43894547a4f1314bd7e3ae0b" 47 | 48 | 49 | 50 | typedef struct _status_writable status_writable; 51 | typedef struct _status_readonly status_readonly; 52 | typedef struct _pro_headPart pro_headPart; 53 | typedef struct _pro_commonCmd pro_commonCmd; 54 | typedef struct _m2w_returnMcuInfo m2w_returnMcuInfo; 55 | typedef struct _m2w_setModule m2w_setModule; 56 | typedef struct _w2m_controlMcu w2m_controlMcu; 57 | typedef struct _m2w_mcuStatus m2w_mcuStatus; 58 | typedef struct _w2m_reportModuleStatus w2m_reportModuleStatus; 59 | typedef struct _pro_errorCmd pro_errorCmd; 60 | 61 | struct _status_writable 62 | { 63 | uint8_t cmd_byte; 64 | uint8_t led_r; 65 | uint8_t led_g; 66 | uint8_t led_b; 67 | short motor_speed; 68 | }; 69 | 70 | struct _status_readonly 71 | { 72 | uint8_t ir_status; 73 | uint8_t temputure; 74 | uint8_t humidity; 75 | uint8_t alert_byte; 76 | uint8_t fault_byte; 77 | }; 78 | struct _pro_headPart 79 | { 80 | uint8_t head[2]; 81 | short len; 82 | uint8_t cmd; 83 | uint8_t sn; 84 | uint8_t flags[2]; 85 | }; 86 | struct _m2w_returnMcuInfo 87 | { 88 | pro_headPart head_part; 89 | uint8_t pro_ver[8]; 90 | uint8_t p0_ver[8]; 91 | uint8_t hard_ver[8]; 92 | uint8_t soft_ver[8]; 93 | uint8_t product_key[32]; 94 | short binable_time; 95 | uint8_t sum; 96 | }; 97 | struct _pro_commonCmd 98 | { 99 | pro_headPart head_part; 100 | uint8_t sum; 101 | }; 102 | struct _pro_errorCmd 103 | { 104 | pro_headPart head_part; 105 | uint8_t error; 106 | uint8_t sum; 107 | }; 108 | struct _m2w_setModule 109 | { 110 | pro_headPart head_part; 111 | uint8_t config_info; 112 | uint8_t sum; 113 | }; 114 | struct _w2m_controlMcu 115 | { 116 | pro_headPart head_part; 117 | uint8_t sub_cmd; 118 | uint8_t cmd_tag; 119 | status_writable status_w; 120 | uint8_t sum; 121 | }; 122 | struct _m2w_mcuStatus 123 | { 124 | pro_headPart head_part; 125 | uint8_t sub_cmd; 126 | status_writable status_w; 127 | status_readonly status_r; 128 | uint8_t sum; 129 | }; 130 | 131 | struct _w2m_reportModuleStatus 132 | { 133 | pro_headPart head_part; 134 | uint8_t status[2]; 135 | uint8_t sum; 136 | }; 137 | 138 | unsigned char CheckSum( unsigned char *buf, int packLen ); 139 | void Handle_uartdata(unsigned char *buf,int len); 140 | void Handle_keyeven(); 141 | void Check_Status(); 142 | void GoKit_Handle(); 143 | #endif 144 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | ****************************************************************** 2 | * * 3 | * gokit_2 arduino 工程配置说明 2015-01-04 * 4 | * * 5 | ****************************************************************** 6 | 7 | 串口属性 8 | 9 | 波特率 : 9600 10 | 流控制 : 无 11 | 数据位 : 8 12 | 停止位 : 1 13 | 奇偶校验 : 无 14 | 15 | 把lib 文件夹下的lib.zip解压之后,把所有的文件拷贝到Arudino IDE 安装路径下的库目录下, 16 | (x/Contents/Resources/Java/libraries). 17 | --------------------------------------------------------------------------------