/* Copyright (c) 2012 Arduino LLC. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "ArduinoRobotMotorBoard.h" #include "EasyTransfer2.h" #include "Multiplexer.h" #include "LineFollow.h" RobotMotorBoard::RobotMotorBoard(){ //LineFollow::LineFollow(); } /*void RobotMotorBoard::beginIRReceiver(){ IRrecv::enableIRIn(); }*/ void RobotMotorBoard::begin(){ //initialze communication Serial1.begin(9600); messageIn.begin(&Serial1); messageOut.begin(&Serial1); //init MUX uint8_t MuxPins[]={MUXA,MUXB,MUXC}; this->IRs.begin(MuxPins,MUX_IN,3); pinMode(MUXI,INPUT); digitalWrite(MUXI,LOW); isPaused=false; } void RobotMotorBoard::process(){ if(isPaused)return;//skip process if the mode is paused if(mode==MODE_SIMPLE){ //Serial.println("s"); //do nothing? Simple mode is just about getting commands }else if(mode==MODE_LINE_FOLLOW){ //do line following stuff here. LineFollow::runLineFollow(); }else if(mode==MODE_ADJUST_MOTOR){ //Serial.println('a'); //motorAdjustment=analogRead(POT); //setSpeed(255,255); //delay(100); } } void RobotMotorBoard::pauseMode(bool onOff){ if(onOff){ isPaused=true; }else{ isPaused=false; } stopCurrentActions(); } void RobotMotorBoard::parseCommand(){ uint8_t modeName; uint8_t codename; int value; int speedL; int speedR; if(this->messageIn.receiveData()){ //Serial.println("data received"); uint8_t command=messageIn.readByte(); //Serial.println(command); switch(command){ case COMMAND_SWITCH_MODE: modeName=messageIn.readByte(); setMode(modeName); break; case COMMAND_RUN: if(mode==MODE_LINE_FOLLOW)break;//in follow line mode, the motor does not follow commands speedL=messageIn.readInt(); speedR=messageIn.readInt(); motorsWrite(speedL,speedR); break; case COMMAND_MOTORS_STOP: motorsStop(); break; case COMMAND_ANALOG_WRITE: codename=messageIn.readByte(); value=messageIn.readInt(); _analogWrite(codename,value); break; case COMMAND_DIGITAL_WRITE: codename=messageIn.readByte(); value=messageIn.readByte(); _digitalWrite(codename,value); break; case COMMAND_ANALOG_READ: codename=messageIn.readByte(); _analogRead(codename); break; case COMMAND_DIGITAL_READ: codename=messageIn.readByte(); _digitalRead(codename); break; case COMMAND_READ_IR: _readIR(); break; case COMMAND_READ_TRIM: _readTrim(); break; case COMMAND_PAUSE_MODE: pauseMode(messageIn.readByte());//onOff state break; case COMMAND_LINE_FOLLOW_CONFIG: LineFollow::config( messageIn.readByte(), //KP messageIn.readByte(), //KD messageIn.readByte(), //robotSpeed messageIn.readByte() //IntegrationTime ); break; } } //delay(5); } uint8_t RobotMotorBoard::parseCodename(uint8_t codename){ switch(codename){ case B_TK1: return TK1; case B_TK2: return TK2; case B_TK3: return TK3; case B_TK4: return TK4; } } uint8_t RobotMotorBoard::codenameToAPin(uint8_t codename){ switch(codename){ case B_TK1: return A0; case B_TK2: return A1; case B_TK3: return A6; case B_TK4: return A11; } } void RobotMotorBoard::setMode(uint8_t mode){ if(mode==MODE_LINE_FOLLOW){ LineFollow::calibIRs(); } /*if(mode==SET_MOTOR_ADJUSTMENT){ save_motor_adjustment_to_EEPROM(); } */ /*if(mode==MODE_IR_CONTROL){ beginIRReceiver(); }*/ this->mode=mode; //stopCurrentActions();//If line following, this should stop the motors } void RobotMotorBoard::stopCurrentActions(){ motorsStop(); //motorsWrite(0,0); } void RobotMotorBoard::motorsWrite(int speedL, int speedR){ /*Serial.print(speedL); Serial.print(" "); Serial.println(speedR);*/ //motor adjustment, using percentage _refreshMotorAdjustment(); if(motorAdjustment<0){ speedR*=(1+motorAdjustment); }else{ speedL*=(1-motorAdjustment); } if(speedR>0){ analogWrite(IN_A1,speedR); analogWrite(IN_A2,0); }else{ analogWrite(IN_A1,0); analogWrite(IN_A2,-speedR); } if(speedL>0){ analogWrite(IN_B1,speedL); analogWrite(IN_B2,0); }else{ analogWrite(IN_B1,0); analogWrite(IN_B2,-speedL); } } void RobotMotorBoard::motorsWritePct(int speedLpct, int speedRpct){ //speedLpct, speedRpct ranges from -100 to 100 motorsWrite(speedLpct*2.55,speedRpct*2.55); } void RobotMotorBoard::motorsStop(){ analogWrite(IN_A1,255); analogWrite(IN_A2,255); analogWrite(IN_B1,255); analogWrite(IN_B2,255); } /* * * * Input and Output ports * * */ void RobotMotorBoard::_digitalWrite(uint8_t codename,bool value){ uint8_t pin=parseCodename(codename); digitalWrite(pin,value); } void RobotMotorBoard::_analogWrite(uint8_t codename,int value){ //There's no PWM available on motor board } void RobotMotorBoard::_digitalRead(uint8_t codename){ uint8_t pin=parseCodename(codename); bool value=digitalRead(pin); messageOut.writeByte(COMMAND_DIGITAL_READ_RE); messageOut.writeByte(codename); messageOut.writeByte(value); messageOut.sendData(); } void RobotMotorBoard::_analogRead(uint8_t codename){ uint8_t pin=codenameToAPin(codename); int value=analogRead(pin); messageOut.writeByte(COMMAND_ANALOG_READ_RE); messageOut.writeByte(codename); messageOut.writeInt(value); messageOut.sendData(); } int RobotMotorBoard::IRread(uint8_t num){ return _IRread(num-1); //To make consistant with the pins labeled on the board } int RobotMotorBoard::_IRread(uint8_t num){ IRs.selectPin(num); return IRs.getAnalogValue(); } void RobotMotorBoard::_readIR(){ int value; messageOut.writeByte(COMMAND_READ_IR_RE); for(int i=0;i<5;i++){ value=_IRread(i); messageOut.writeInt(value); } messageOut.sendData(); } void RobotMotorBoard::_readTrim(){ int value=analogRead(TRIM); messageOut.writeByte(COMMAND_READ_TRIM_RE); messageOut.writeInt(value); messageOut.sendData(); } void RobotMotorBoard::_refreshMotorAdjustment(){ motorAdjustment=map(analogRead(TRIM),0,1023,-30,30)/100.0; } void RobotMotorBoard::reportActionDone(){ setMode(MODE_SIMPLE); messageOut.writeByte(COMMAND_ACTION_DONE); messageOut.sendData(); } RobotMotorBoard RobotMotor=RobotMotorBoard();