Closed hawkeye1103 closed 1 year ago
"Couldn't connect to OBD scanner - Phase 1"
means your Arduino can't pair/connect to the ELM327. You need to make sure you use the correct Bluetooth device name in your sketch that corresponds to your ELM327. You also need to make sure the ELM327 isn't connected to another device (i.e. your phone).
Also, I am NOT taking a look at your 1 million lines of unformatted code.
Already done all of that including deleting the history of connected devices of my esp32. It's a esp32, not arduino.
Fixed by connecting via MAC Address although it doesn't have the standard AA:BB:CC:11:22:33 mac address it seems to work... it was bench tested for now, I'm going to try it on the car later. Tested very quickly and easily with the BluetoothSerial example: SerialtoserialBTM
Hello,
I have 3 elm327 modules with the same issue. I'm guessing i'm doing something wrong and I need your help to find out what. My code is compiling correctly. Two of the modules I have bought recently because I suspected my old module is not working ok. So I tested them with bluetooth terminal from my phone and I got the following result from them.
I'm guessing the one that doesn't have the J is the one that looks ok.
I also added my code below maybe you can spot an issue with it .... already tried on the first elm327 to use the code you provided and I was not able to connect to it either way, also tried a different esp32 module same issue. Now I'm fresh out of ideas and don't know how to solve it. Maybe you guys can shed some new light on the problem.
The code is a from a shiftlight module called Chippernut and was originally designed for an Arduino Nano and I made it work for ESP32. If you need further clarification I'm here to try anything:).
Forgot to mention the issue I have is that I get the first error "Couldn't connect to OBD scanner - Phase 1"
Thanks in advance for all your help.
` /*
/ _/ / (_)_ __ _ ___ / /_ / / / \/ / \/ \/ _ \/ / \/ / / / / / // / / / / // / // / / / / / / / // / /
__// /// ./ ._/_// // //_,_/\/
// //
Visit us: www.chippernut.com ARDUINO RPM TACHOMETER MULTI-DISPLAY Written by Jonduino (Chippernut) 03-20-2016 Updated 08-09-2017 *** Version NOTES **** /* v1.0 BETA 11/17/2013 -- Initial Release v1.1 03/09/2014 - Fixed bug with flasher that didn't correspond to brightness value Improved sleep function, now it shuts off after 5-seconds of engine OFF Other minor improvements. v2.1 08/10/2015 -- Too many to list here. v2.2 01/17/2016 -- New Display Support v2.4 03/20/2016 -- Added dimmer support Fixed array mathematics (bug) Improved rotary encoder response Finer PPr Control (0.1) v3.0 08/08/2017
// Include these libraries
include
include
include
include
include "SSD1306Ascii.h"
include "SSD1306AsciiWire.h"
include "BluetoothSerial.h"
include "ELMduino.h"
//Uncomment for ELM327 connection >>>
if !defined(CONFIG_BT_SPP_ENABLED)
error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
endif
BluetoothSerial SerialBT;
define ELM_PORT SerialBT
ELM327 myELM327; String MACadd = "11:22:33:AA:BB:CC"; uint8_t address[6] = {0x11, 0x22, 0x33, 0xAA, 0xBB, 0xCC};; //MAC Address //uint32_t rpm;
// <<< Uncomment for ELM327 connection
// void(* resetFunc) (void) = 0; int DEBUG; int NUMPIXELS;
define PIN 2
define RST_PIN -1
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
//const int rpmPin = 3; //Uncomment for analog input. should be paired with a 2N3906 transistor const int dimPin = 25; const int sensorInterrupt = 3; //same as RPM PIN also attachInterrupt const int timeoutValue = 10; volatile unsigned long lastPulseTime; volatile unsigned long interval = 3; volatile int timeoutCounter; long rpm; //Uncomment for analog input.
long rpm_last; //Uncomment for analog input.
int display_rpm; int activation_rpm; int shift_rpm; int menu_enter = 0; int current_seg_number = 1; int seg_mover = 0; long previousMillis = 0; int shiftinterval = 50; boolean flashbool = true;
int prev_animation; int prev_color; boolean testbright = false; int prev_variable; int prev_menu; boolean testdim = false; int justfixed;
//array for rpm averaging, filtering comparison const int numReadings = 5; int rpmarray[numReadings]; int curreading = 0; // the index of the current reading long total = 0; // the running total long average = 0; // the average
//These are stored memory variables for adjusting the (5) colors, activation rpm, shift rpm, brightness //Stored in EEPROM Memory int c1; int c2; int c3; int c4; int c5; int brightval; //7-seg brightness int dimval; //7-seg dim brightness int sb; //strip brightness int dimsb; // strip dim brightness boolean dimmer = false; boolean dimmerlogic = false; int pixelanim=1;
int smoothing; int rpmscaler; int shift_rpm1; // USED TO BE A LONG!! int shift_rpm2; int shift_rpm3; int shift_rpm4; int seg1_start = 1; int seg1_end = 1; int seg2_end = 2; int seg3_end = 3; int activation_rpm1; int activation_rpm2; int activation_rpm3; int activation_rpm4; int a;
int rst = 0; int cal;
int prev_cal;
// COLOR VARIABLES - for use w/ the strips and translated into 255 RGB colors long color1; long color2; long color3; long flclr1;
//Creates a 32 wide table for our pixel animations int rpmtable[32][2];
// ROTARY ENCODER VARIABLES int button_pin = 14; int menuvar; int val; int rotaryval = 0;
// CONFIGURATION FOR OLED DISPLAY SSD1306AsciiWire oled;
define OLED_SDA 5
define OLED_SCL 4
// CONFIGURATION FOR THE ROTARY ENCODER // Arduino pins the encoder is attached to. Attach the center to ground.
define ROTARY_PIN1 13
define ROTARY_PIN2 12
// Use the full-step state table (emits a code at 00 only) const char ttable[7][4] = { {0x0, 0x2, 0x4, 0x0}, {0x3, 0x0, 0x1, 0x40}, {0x3, 0x2, 0x0, 0x0}, {0x3, 0x2, 0x1, 0x0}, {0x6, 0x0, 0x4, 0x0}, {0x6, 0x5, 0x0, 0x80}, {0x6, 0x5, 0x4, 0x0}, };
volatile unsigned char state = 0;
char rotary_process() { char pinstate = (digitalRead(ROTARY_PIN2) << 1) | digitalRead(ROTARY_PIN1); state = ttable[state & 0xf][pinstate]; return (state & 0xc0); }
//Helper Color Manager - This translates our 255 value into a meaningful color uint32_t load_color(int cx){ unsigned int r,g,b; if (cx == 0){ r = 0; g = 0; b = 0; }
if (cx>0 && cx<=85){ r = 255-(cx3); g = cx3; b=0; }
if (cx>85 && cx < 170){ r = 0; g = 255 - ((cx-85)3); b = (cx-85)3; }
if (cx >= 170 && cx<255){ r = (cx-170)3; g = 0; b = 255 - ((cx-170)3); }
if (cx == 255){ r=255; g=255; b=255; }
if (digitalRead(dimPin)== dimmerlogic || testdim == true){ r = (r/dimsb); g = (g/dimsb); b = (b/dimsb);
} else { r = (r/sb); g = (g/sb); b = (b/sb); }
return strip.Color(r,g,b); }
void buildarrays(){
int x; //rpm increment int y; //starting point pixel address int ya; // second starting point pixel address (for middle-out animation only) int i; //temporary for loop variable
if(DEBUG){ Serial.print("NUMPIXELS: "); Serial.println(NUMPIXELS); Serial.print("PIXELANIM: "); Serial.println(pixelanim); Serial.print("Start1: "); Serial.println(seg1_start); Serial.print("End1: "); Serial.println(seg1_end); Serial.print("End2: "); Serial.println(seg2_end); Serial.print("End3: "); Serial.println(seg3_end); Serial.print(" Activation RPM "); Serial.println(activation_rpm); Serial.print(" SHIFT RPM "); Serial.println(shift_rpm); }
switch(pixelanim){
case 3:
y=0; x = ((shift_rpm - activation_rpm)/NUMPIXELS); for (i = NUMPIXELS-1; i>seg1_end-1; i--){ rpmtable[i][0] = activation_rpm + (yx); rpmtable[i][1] = 1; y++; } for (i = seg1_end-1; i>seg2_end-1; i--){ rpmtable[i][0] = activation_rpm + (yx); rpmtable[i][1] = 2; y++; } for (i = seg2_end-1; i>seg3_end-1; i--){ rpmtable[i][0] = activation_rpm + (y*x); rpmtable[i][1] = 3; y++; } break;
case 4:
if (((NUMPIXELS-1)%2)> 0){
x = ((shift_rpm - activation_rpm)/(NUMPIXELS/2)); //EVEN PIXELS }else{ x = ((shift_rpm - activation_rpm)/((NUMPIXELS/2)+1)); //ODD PIXELS
}
}
if(DEBUG){ for (i = 0; i<NUMPIXELS; i++){ Serial.print(rpmtable[i][0]); Serial.print(" "); Serial.println(rpmtable[i][1]); } } }
/*****
//This subroutine reads the stored variables from memory void getEEPROM(){ brightval = EEPROM.read(0); sb = EEPROM.read(1); c1 = EEPROM.read(2); c2 = EEPROM.read(3); c3 = EEPROM.read(4); c4 = EEPROM.read(5); c5 = EEPROM.read(6); activation_rpm = EEPROM.read(7); pixelanim = EEPROM.read(8); //senseoption = EEPROM.read(9); smoothing = EEPROM.read(10); NUMPIXELS = EEPROM.read(11); rpmscaler = EEPROM.read(12); shift_rpm1 = EEPROM.read(13); shift_rpm2 = EEPROM.read(14); shift_rpm3 = EEPROM.read(15); shift_rpm4 = EEPROM.read(16); DEBUG = EEPROM.read(17); seg1_start = EEPROM.read(18); seg1_end = EEPROM.read(19); //seg2_start = EEPROM.read(20); seg2_end = EEPROM.read(21); //seg3_start = EEPROM.read(22); seg3_end = EEPROM.read(23); activation_rpm1 = EEPROM.read(24); activation_rpm2 = EEPROM.read(25); activation_rpm3 = EEPROM.read(26); activation_rpm4 = EEPROM.read(27); cal = EEPROM.read(28); dimval = EEPROM.read(29); dimsb = EEPROM.read(30); dimmerlogic = EEPROM.read(31);
activation_rpm = ((activation_rpm1 << 0) & 0xFF) + ((activation_rpm2 << 8) & 0xFFFF) + ((activation_rpm3 << 16) & 0xFFFFFF) + ((activation_rpm4 << 24) & 0xFFFFFFFF); shift_rpm = ((shift_rpm1 << 0) & 0xFF) + ((shift_rpm2 << 8) & 0xFFFF) + ((shift_rpm3 << 16) & 0xFFFFFF) + ((shift_rpm4 << 24) & 0xFFFFFFFF);
buildarrays();
}
//This subroutine writes the stored variables to memory void writeEEPROM(){
byte four = (shift_rpm & 0xFF); byte three = ((shift_rpm >> 8) & 0xFF); byte two = ((shift_rpm >> 16) & 0xFF); byte one = ((shift_rpm >> 24) & 0xFF);
byte activation_four = (activation_rpm & 0xFF); byte activation_three = ((activation_rpm >> 8) & 0xFF); byte activation_two = ((activation_rpm >> 16) & 0xFF); byte activation_one = ((activation_rpm >> 24) & 0xFF);
EEPROM.write(0, brightval); EEPROM.write(1, sb); EEPROM.write(2, c1); EEPROM.write(3, c2); EEPROM.write(4, c3); EEPROM.write(5, c4); EEPROM.write(6, c5); EEPROM.write(7, activation_rpm); EEPROM.write(8, pixelanim); //EEPROM.write(9, senseoption); EEPROM.write(10, smoothing); EEPROM.write(11, NUMPIXELS); EEPROM.write(12, rpmscaler); EEPROM.write(13, four); EEPROM.write(14, three); EEPROM.write(15, two); EEPROM.write(16, one); EEPROM.write(17, DEBUG); EEPROM.write(18, seg1_start); EEPROM.write(19, seg1_end); //EEPROM.write(20, seg2_start); EEPROM.write(21, seg2_end); //EEPROM.write(22, seg3_start); EEPROM.write(23, seg3_end); EEPROM.write(24, activation_four); EEPROM.write(25, activation_three); EEPROM.write(26, activation_two); EEPROM.write(27, activation_one); EEPROM.write(28, cal); EEPROM.write(29, dimval); EEPROM.write(30, dimsb); EEPROM.write(31, dimmerlogic); EEPROM.commit(); }
void loadallcolors(){ color1 = load_color(c1); color2 = load_color(c2); color3 = load_color(c3); flclr1 = load_color(c4);
}
void testlights(){ for (int a = 0; a<NUMPIXELS; a++){
switch (rpmtable[a][1]){ case 1: strip.setPixelColor(a,color1); break;
} strip.show(); }
void check_first_run(){
if (shift_rpm == 0){ Serial.println("FIRST RUN! LOADING DEFAULTS");
brightval = 15; dimval = 8; dimsb = 15; dimmerlogic = false; sb = 3; c1 = 79; c2 = 48; c3 = 1; c4 = 255; c5 = 0;
}
}
void build_segments(){
// Resets segmentation variables, sets segments 2 and 4 outside of the range int prev_seg_mover = -1; current_seg_number = 1; seg1_start = 0; seg1_end = 0; seg2_end = NUMPIXELS + 1; seg3_end = NUMPIXELS + 1;
// Based on the animation, we must reconfigure some segmentation variables to known limits
switch(pixelanim){ case 1: seg_mover = 0; break;
if (prev_seg_mover != seg_mover){
prev_seg_mover = seg_mover;
} }
void sensorIsr() { unsigned long now = micros(); interval = now - lastPulseTime; lastPulseTime = now; timeoutCounter = timeoutValue; }
void exitmenu(){ strip.clear(); strip.show(); for(int i=0; i<NUMPIXELS+1; i++) { strip.setPixelColor(i, strip.Color(50, 50, 50)); strip.show(); delay(15); strip.setPixelColor(i, strip.Color(0, 0, 0)); strip.show(); } }
void entermenu(){ //Ascend strip for (int i=0; i<(NUMPIXELS/2)+1; i++){ strip.setPixelColor(i, strip.Color(0, 0, 25)); strip.setPixelColor(NUMPIXELS-i, strip.Color(0, 0, 25)); strip.show(); delay(35); } // Descend Strip for (int i=0; i<(NUMPIXELS/2)+1; i++){ strip.setPixelColor(i, strip.Color(0, 0, 0)); strip.setPixelColor(NUMPIXELS-i, strip.Color(0, 0, 0)); strip.show(); delay(35); } }
void bootanimation(){ int colorwidth; colorwidth = (50/(NUMPIXELS/2)); for (int i = 0; i<(NUMPIXELS/2)+1; i++){ strip.setPixelColor(i,strip.Color((icolorwidth),(icolorwidth),((25(NUMPIXELS/2))-((25(i/2))+1)))); strip.setPixelColor(NUMPIXELS-i,strip.Color((icolorwidth),(icolorwidth),((25(NUMPIXELS/2))-((25(i/2))+1))));
strip.show(); delay(25); strip.setPixelColor(i-1,strip.Color(0,0,0)); strip.setPixelColor(NUMPIXELS-i+1,strip.Color(0,0,0)); strip.show();
}
for (int i = 35; i>0 ; i--){ delay(15); strip.setPixelColor((NUMPIXELS/2),strip.Color(i,i,i)); strip.show(); }
strip.clear(); strip.show(); }
/*****
// MENU SYSTEM void menu(){ prev_menu = 2; //this keeps us in the menu while (menuvar == 1){
// This little bit calls the rotary encoder
int result = rotary_process(); if(DEBUG){if(result!=0){Serial.println(result);}} if (result == 128){rotaryval--;}
else if (result == 64){rotaryval++;}
rotaryval = constrain(rotaryval, 0, 15);
//Poll the rotary encoder button to enter menu items if (digitalRead(button_pin) == LOW){ oled.clear(); delay(250); menu_enter = 1;
}
while (menu_enter == 4){
// display.setColon(false); exitmenu(); } }
break;
} }
//SETUP TO CONFIGURE THE ARDUINO AND GET IT READY FOR FIRST RUN void setup() {
Wire.begin(5, 4); Wire.setClock(400000L); //get stored variables EEPROM.begin(32); getEEPROM(); strip.updateLength(NUMPIXELS); check_first_run();
timeoutCounter = timeoutValue; buildarrays();
strip.begin(); strip.clear(); strip.show(); // Initialize all pixels to 'off' // Uncomment for ELM327 integration >>>>>
SerialBT.setPin("1234"); ELM_PORT.begin("Chippernut", true);
if (!ELM_PORT.connect("OBDII")) { Serial.println("Couldn't connect to OBD scanner - Phase 1"); while(1); }
if (!myELM327.begin(ELM_PORT, true, 2000)) { Serial.println("Couldn't connect to OBD scanner - Phase 2"); while (1); }
Serial.println("Connected to ELM327");
// <<<< Uncomment for ELM327 integration
//ROTARY ENCODER // pinMode(rpmPin, INPUT); pinMode(dimPin, INPUT_PULLUP); pinMode(button_pin, INPUT_PULLUP); pinMode(ROTARY_PIN1, INPUT_PULLUP); pinMode(ROTARY_PIN2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(3), &sensorIsr, RISING); //same as rpm pin
loadallcolors();
if RST_PIN >= 0
oled.begin(&Adafruit128x64, 0x3C, RST_PIN);
else
oled.begin(&Adafruit128x64, 0x3C);
endif
oled.clear(); oled.setFont(chippernut); oled.print("c");
bootanimation(); delay(1000); oled.clear();
if(DEBUG){Serial.println("LOADED.");}
}
void loop() { //Uncomment for analog input.>>>>
// rpm = long(60e7/cal)/(float)interval;
// if (timeoutCounter > 0){ timeoutCounter--;}
// if (timeoutCounter <= 0){rpm = 0;}
// if (((rpm > (rpm_last +(rpm_last.2))) || (rpm < (rpm_last - (rpm_last.2)))) && (rpm_last > 0) && (justfixed < 3)){ // rpm = rpm_last; // justfixed++; // if(DEBUG){ // Serial.print("FIXED! "); // Serial.println(rpm_last);}
// } else { // rpm_last = rpm; // justfixed--; // if (justfixed <= 0){justfixed = 0;} // }
//<<<< Uncomment for analog input
// Uncomment for ELM327 integration >>>> float tempRPM = myELM327.rpm();
if (myELM327.nb_rx_state == ELM_SUCCESS) { rpm = (uint32_t)tempRPM; Serial.print("RPM: "); Serial.println(rpm); } else if (myELM327.nb_rx_state != ELM_GETTING_MSG) myELM327.printError();
// <<<< Uncomment for ELM327 integration
if (smoothing){ total = total - rpmarray[curreading]; rpmarray[curreading] = rpm; total = total + rpmarray[curreading]; curreading = curreading + 1;
if (curreading >= numReadings){
curreading = 0;
}
average = total / numReadings; if(DEBUG){Serial.print("average: "); Serial.println(average);} rpm = average;
}
if (rpm > 0 ){ if(DEBUG){Serial.println(rpm); } if(DEBUG){ oled.set1X(); oled.setFont(chippernutserial); oled.setCursor(78, 0); oled.print("c"); }
} else { rpm = 0; oled.clear();
strip.clear(); strip.show(); }
if (rpm < shift_rpm){ for (a = 0; a<NUMPIXELS; a++){ if (rpm>rpmtable[a][0]){ switch (rpmtable[a][1]){ case 1: strip.setPixelColor(a,color1); break;
} else {
}
strip.show();
} `