// -------------------------------------- // "Nonagon DRV8830 PCB" Arduino driver // // Le 14 Mai 2018 by Mej ///////////////////////////////////////////////////////////////////////////////////////////// //## DRV8830 (H-Bridge Voltage-Controlled Motor Driver) //Addresses #IC Output const byte DRV8830_1 = B1100000; // 0x60 adress=110+ 0000 1 1+/1- const byte DRV8830_2 = B1100001; // 0x61 adress=110+ 0001 2 2+/2- const byte DRV8830_3 = B1100010; // 0x62 adress=110+ 0010 3 3+/3- const byte DRV8830_4 = B1100011; // 0x62 adress=110+ 0011 4 ... const byte DRV8830_5 = B1100100; // 0x62 adress=110+ 0100 5 const byte DRV8830_6 = B1100101; // 0x62 adress=110+ 0101 6 const byte DRV8830_7 = B1100110; // 0x62 adress=110+ 0110 7 const byte DRV8830_8 = B1100111; // 0x62 adress=110+ 0111 8 const byte DRV8830_0 = B1101000; // 0x62 adress=110+ 1000 9 9+/9- const byte DRV8830 = DRV8830_0; const byte DRV8830s[9] = {DRV8830_0, DRV8830_1, DRV8830_2, DRV8830_3, DRV8830_4, DRV8830_5, DRV8830_6, DRV8830_7, DRV8830_8}; //Registers const byte DRV8830_CONTROL = 0x00; const byte DRV8830_FAULT = 0x01; //CONTROL registry tools //const byte DRV8830_VSETmax = B111111; // 0x3F D63 // Output voltage = 5.06V (PWM controled) //const byte DRV8830_VSETmax = B110010; // 0x32 D50 // Output voltage = 4.02V (PWM controled) const byte DRV8830_VSETmax = B100110; // 0x26 D38 // Output voltage = 3.05V (PWM controled) const byte DRV8830_VSETmin = B000110; // 0x06 D6 // Output voltage = 0.48V (PWM controled) byte DRV8830s_VSET[9] = {DRV8830_VSETmin, DRV8830_VSETmin, DRV8830_VSETmin, DRV8830_VSETmin, DRV8830_VSETmin, DRV8830_VSETmin, DRV8830_VSETmin, DRV8830_VSETmin, DRV8830_VSETmin}; //PWM average voltage bool DRV8830s_IN1[9] = {0,0,0,0,0,0,0,0,0}; //H-Brigdes logic bool DRV8830s_IN2[9] = {0,0,0,0,0,0,0,0,0}; byte DRV8830s_control[9]={0,0,0,0,0,0,0,0,0}; //Value to be loaded in register //FAULT registry tools const byte DRV8830_fault_clear = B10000000; //0x80 used to clear FAULT byte DRV8830_fault; //used to store FAULT register ///////////////////////////////////////////////////////////////////////////////////////////////////////// // Other variables //timing unsigned long t_0 = millis(); //Time since startup in ms. Overflow after 50 days. unsigned long t = millis(); unsigned long loop_cnt = 0; //loop count ////Steping sequence 1: "Wave drive" //const bool Sequence_L1_P1[4] = {1, 0, 0, 0}; //1st Coil, 1st Phase //const bool Sequence_L1_P2[4] = {0, 0, 1, 0}; //1st Coil, 2nd Phase //const bool Sequence_L2_P1[4] = {0, 1, 0, 0}; //2nd Coil, 1st Phase //const bool Sequence_L2_P2[4] = {0, 0, 0, 1}; //2nd Coil, 2nd Phase //const byte Under_step = 4; //Number of steps in "one step" //Steping sequence 2: "Full step" const bool Sequence_L1_P1[4] = {1, 1, 0, 0}; //1st Coil, 1st Phase const bool Sequence_L1_P2[4] = {0, 0, 1, 1}; //1st Coil, 2nd Phase const bool Sequence_L2_P1[4] = {0, 1, 1, 0}; //2nd Coil, 1st Phase const bool Sequence_L2_P2[4] = {1, 0, 0, 1}; //2nd Coil, 2nd Phase const byte Under_step = 4; //Number of steps in "one step" //////Steping sequence 2: "Half step" //const bool Sequence_L1_P1[8] = {1, 1, 0, 0, 0, 0, 0, 1}; //1st Coil, 1st Phase //const bool Sequence_L1_P2[8] = {0, 0, 0, 1, 1, 1, 0, 0}; //1st Coil, 2nd Phase //const bool Sequence_L2_P1[8] = {0, 1, 1, 1, 0, 0, 0, 0}; //2nd Coil, 1st Phase //const bool Sequence_L2_P2[8] = {0, 0, 0, 0, 0, 1, 1, 1}; //2nd Coil, 2nd Phase //const byte Under_step = 8; //Number of steps in "one step" void set_Step(char channel, byte STEP) //There à 4 stepper-motor channel: 'A' (DRV1&2) - 'B' (DRV3&4)- 'C' (DRV5&6)and 'D'(DRV7&8). { int c = 10; if(channel=='A'){ c = 1;} if(channel=='B'){ c = 3;} if(channel=='C'){ c = 5;} if(channel=='D'){ c = 7;} STEP = STEP%Under_step; if (c!=10) { DRV8830s_IN1[c] = Sequence_L1_P1[STEP]; DRV8830s_IN2[c] = Sequence_L1_P2[STEP]; DRV8830s_IN1[c+1] = Sequence_L2_P1[STEP]; DRV8830s_IN2[c+1] = Sequence_L2_P2[STEP]; } } ///////////////////////////////////////////////////////////////////////////////////////////////////////// // Wire and functions #include void set_I2C_register(byte ADDRESS, byte REGISTER, byte VALUE) { Wire.beginTransmission(ADDRESS); Wire.write(REGISTER); Wire.write(VALUE); Wire.endTransmission(); } byte get_I2C_register(byte ADDRESS, byte REGISTER) { Wire.beginTransmission(ADDRESS); Wire.write(REGISTER); Wire.endTransmission(); Wire.requestFrom(ADDRESS, 1); //read 1 byte byte x = Wire.read(); return x; } ///////////////////////////////////////////////////////////////////////////////////////////////////////// SETUP // void setup() { Wire.begin(); Serial.begin(115200); delay(100); while (!Serial); // wait for serial monitor Serial.println("\n"); Serial.println("\nI2C is up at 9600 baud"); Serial.print("\n"); for (int i=0; i < 9; i++) { Serial.print("DRV8830_"); Serial.print(i); Serial.print(" address = 0x"); Serial.print(DRV8830s[i], HEX); Serial.print(" = B"); Serial.println(DRV8830s[i], BIN); } //Clear all DRV8830 and set them at DRV8830_VSETmin Serial.println("\n"); Serial.print("\nClearing DRVs: "); for (int i=0; i < 9; i++) { set_I2C_register(DRV8830s[i], DRV8830_CONTROL, 4*DRV8830_VSETmin + 2*0 + 0); // Standby/coast //set_I2C_register(DRV8830s[i], DRV8830_CONTROL, 4*DRV8830_VSETmin + 2*1 + 1); // Break set_I2C_register(DRV8830s[i], DRV8830_FAULT, DRV8830_fault_clear); //Clear fault Serial.print(i); Serial.print(" "); } //Choose configurations of DC motor, drived by DRV8830_0 on connector 9+/9- DRV8830s_IN1[0] = 1; DRV8830s_IN2[0] = 0; DRV8830s_VSET[0] = (DRV8830_VSETmax+DRV8830_VSETmin)/2; Serial.println(""); Serial.print("VSET DC = "); Serial.println(DRV8830s_VSET[0]); //Choose configurations of Stepper-motor, on connector 1+/1-/2+/2- , 3+/3-/4+/4- , ... byte VSET_steppers = DRV8830_VSETmax; Serial.print("VSET steppers = "); Serial.println(VSET_steppers); set_Step('A', 0); DRV8830s_VSET[1] = VSET_steppers; DRV8830s_VSET[2] = VSET_steppers; set_Step('B', 0); DRV8830s_VSET[3] = VSET_steppers; DRV8830s_VSET[4] = VSET_steppers; set_Step('C', 0); DRV8830s_VSET[5] = VSET_steppers; DRV8830s_VSET[6] = VSET_steppers; set_Step('D', 0); DRV8830s_VSET[7] = VSET_steppers; DRV8830s_VSET[8] = VSET_steppers; //Set Motor Serial.print("\n"); Serial.print("DRV8830s_control="); for (int i=0; i < 9; i++) { DRV8830s_control[i] = 4*DRV8830s_VSET[i] + 2*DRV8830s_IN2[i] + DRV8830s_IN1[i]; set_I2C_register(DRV8830s[i], DRV8830_CONTROL, DRV8830s_control[i]); Serial.print("\t"); Serial.print(DRV8830s_control[i], HEX); } delay(1000); //Read and print CONTROL registers Serial.print("\nDRV8830s_control="); for (int i=0; i < 9; i++) { Serial.print("\t"); Serial.print(get_I2C_register(DRV8830s[i], DRV8830_CONTROL), HEX); } Serial.print(" (checked from register)"); delay(1000); //Read and print FAULT registers (see Table 8 of datasheet) of all DRV8830s Serial.print("\n"); for (int i=0; i < 9; i++) { DRV8830_fault = get_I2C_register(DRV8830s[i], DRV8830_FAULT); Serial.print("\nDRV8830_"); Serial.print(i); Serial.print(" is"); Serial.print(DRV8830_fault, BIN); if (bitRead(DRV8830_fault,0)==1) //D0: FAULT { Serial.print("faulty:"); if (bitRead(DRV8830_fault,1)==1){ //D1: OCP Serial.print(" OCP = Overcurrent event!");} else if (bitRead(DRV8830_fault,2)==1){ //D2: UVLO Serial.print(" UVLO = Undervoltage lockout!");} else if (bitRead(DRV8830_fault,3)==1){ //D3: OTS Serial.print(" OTS = Overtemperature condition!");} else if (bitRead(DRV8830_fault,4)==1){ //D4: ILIMIT Serial.print(" OTS = extended current limit event!");} } else { Serial.print(" OK"); } } Serial.println("\n"); } ///////////////////////////////////////////////////////////////////////////////////////////////////////// LOOP // void loop() { loop_cnt = loop_cnt+1; t = millis(); Serial.print("\nt= "); Serial.print(t/1000.0, 3); Serial.print("s"); //Update DC DRV8830s_IN1[0] = !DRV8830s_IN1[0]; DRV8830s_IN2[0] = !DRV8830s_IN2[0]; //Update Stepper motors byte state = loop_cnt%256; if (state>128) { set_Step('A', state); set_Step('B', state); set_Step('C', state); set_Step('D', state); } else { set_Step('A', 256-state); set_Step('B', 256-state); set_Step('C', 256-state); set_Step('D', 256-state); } //Print IN1-IN2 config (Direction, Break, Free) Serial.print("\tIN12= "); Serial.print(DRV8830s_IN1[0]); Serial.print(DRV8830s_IN2[0]); Serial.print(" "); Serial.print(DRV8830s_IN1[1]); Serial.print(DRV8830s_IN2[1]); Serial.print(DRV8830s_IN1[2]); Serial.print(DRV8830s_IN2[2]); Serial.print(" "); Serial.print(DRV8830s_IN1[3]); Serial.print(DRV8830s_IN2[3]); Serial.print(DRV8830s_IN1[4]); Serial.print(DRV8830s_IN2[4]); Serial.print(" "); Serial.print(DRV8830s_IN1[5]); Serial.print(DRV8830s_IN2[5]); Serial.print(DRV8830s_IN1[6]); Serial.print(DRV8830s_IN2[6]); Serial.print(" "); Serial.print(DRV8830s_IN1[7]); Serial.print(DRV8830s_IN2[7]); Serial.print(DRV8830s_IN1[8]); Serial.print(DRV8830s_IN2[8]); //Set all DRV8830 for (int i=0; i < 9; i++) { DRV8830s_control[i] = 4*DRV8830s_VSET[i] + 2*DRV8830s_IN2[i] + DRV8830s_IN1[i]; set_I2C_register(DRV8830s[i], DRV8830_CONTROL, DRV8830s_control[i]); } //Read CONTROL register and check is has expected value Serial.print(" CONTROL: "); for (int i=0; i < 9; i++) { byte DRV8830_control_check = get_I2C_register(DRV8830s[i], DRV8830_CONTROL); if (DRV8830_control_check == DRV8830s_control[i]) { 1+1; //Serial.print("ok "); } else { Serial.print("\t!!! CONTROL of DRV8830_"); Serial.print(i); Serial.print(" is "); Serial.print(DRV8830_control_check,BIN); Serial.print(" instead of "); Serial.print(DRV8830s_control[i] ,BIN); } } //Check FAULT register Serial.print(" FAULT: "); for (int i=0; i < 9; i++) { DRV8830_fault = get_I2C_register(DRV8830s[i], DRV8830_FAULT); if (bitRead(DRV8830_fault,0)==1) //D0: FAULT { Serial.print("\tDRV8830_"); Serial.print(i); Serial.print(" is faulty:"); if (bitRead(DRV8830_fault,1)==1){ //D1: OCP Serial.print(" OCP = Overcurrent event!");} else if (bitRead(DRV8830_fault,2)==1){ //D2: UVLO Serial.print(" UVLO = Undervoltage lockout!");} else if (bitRead(DRV8830_fault,3)==1){ //D3: OTS Serial.print(" OTS = Overtemperature condition!");} else if (bitRead(DRV8830_fault,4)==1){ //D4: ILIMIT Serial.print(" OTS = extended current limit event!");} } else { //Serial.print("ok "); // Serial.print("\t"); // Serial.print(i); // Serial.print(":"); // Serial.print(DRV8830_fault,BIN); } } //delay(1); }