Olimex Support Forum

Microcontrollers => ESP8266 => Topic started by: abarrow on November 03, 2017, 06:47:04 PM

Title: I2C Adafruit Display with ESP8266-EVB and Arduino IDE
Post by: abarrow on November 03, 2017, 06:47:04 PM
Has anyone got this working? I tried code that worked on another ESP8266 development board, and then just tried the example code from Adafruit. I can't get it to work.

If you did, which pins did you use for power and SCD/SCL?
Title: Re: I2C Adafruit Display with ESP8266-EVB and Arduino IDE
Post by: abarrow on November 04, 2017, 07:37:12 PM
To answer my own question...

I just ran an I2C port scanning program on my esp8266-dev that I got from this address
https://github.com/jainrk/i2c_port_address_scanner/tree/master/i2c_port_address_scanner

Nothing detected. I guess I have a bad ESP, or perhaps I have a firmware problem.
Title: Re: I2C Adafruit Display with ESP8266-EVB and Arduino IDE
Post by: LubOlimex on November 06, 2017, 01:45:19 PM
I don't think it is hardware problem with the ESP8266-EVB, more likely either improper hardware connections, insufficient powering or improper code.

Did you try the other way around? Using our I2C examples as a basis - we have published an library with examples for ESP8266 boards and I2C temperature sensor MOD-TC-MK2. This archive:

https://www.olimex.com/Products/Modules/Sensors/MOD-TC-MK2-31855/resources/ESP8266-EVB-MOD_TC_MK2.zip

The page of the sensor is here: https://www.olimex.com/Products/Modules/Sensors/MOD-TC-MK2-31855/open-source-hardware

Best regards,
Lub/OLIMEX
Title: Re: I2C Adafruit Display with ESP8266-EVB and Arduino IDE
Post by: abarrow on November 06, 2017, 04:17:55 PM
Okay, I'll have another look. This is code that was working for a year on an ESP-12E dev board - I wanted to move it to the ESP8266-EVB to gain access to the integrated relay and smaller form factor.

Code is here:

/* Sailboat Race Timer for Arduino
   Activates a relay for an electric horn during a stardard ISAF 5 minute start sequence.
   Also providing audio and visual alerts to users regarding upcoming flag actions

   Will operate in 6 Min, 5 Min, or 5 Min Cycle mode.

   This code is in the Public Domain, and covered by the General Public License.

   Andy Barrow

   Modified for use with the OLMEX ESP8266-EVB (some GPIOs changed)
*/

#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#include <Bounce2.h>

Adafruit_7segment matrix = Adafruit_7segment();

//Pin assignments for the Olmex ESP8266
#define GPIO0     0
#define GPIO1     1
#define GPIO2     2
#define GPIO3     3
#define GPIO4     4
#define GPIO5     5   //Relay-LED
#define GPIO6     6   //DON'T USE
#define GPIO7     7   //DON'T USE
#define GPIO8     8   //DON'T USE
#define GPIO9     9   //DON'T USE
#define GPIO10    10  //DON'T USE
#define GPIO11    11  //DON'T USE
#define GPIO12    12
#define GPIO13    13
#define GPIO14    14
#define GPIO15    15
#define GPIO16    16

static const uint8_t TRUE = 1;
static const uint8_t FALSE = 0;

// Buttons, Relay and Tone output
const int START_BUTTON = GPIO12;    // Start Button
const int MODE_BUTTON = GPIO15;     // Mode Button
const int RELAY = GPIO5;            // Relay
const int TONE_PIN = GPIO13;        // Tone Pin - this will go to an amp

// Instantiate a Bounce objects
// Bounce only seems to work for a single button. The other button uses a different process.
Bounce start_debounce = Bounce();

// Mode Button
int buttonState;              // the current reading from the input pin
int lastButtonState = HIGH;   // the previous reading from the input pin

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

// This is the state we are in during the sequence
// State is one of:
// 0: Ready (Holding, no action)
// 1: One Minute to Class Up
// 2: Class Flag Up
// 3: Prep Signal Up
// 4: One Minute to Start (Prep Down)
// 5: Start (Class Down)

int state = 0;

// other flag related variables
unsigned long remainingFlagTime = 0;   // Used for countdown beeps and flashes
unsigned long remainingGoTime = 0;     // For counter to be used in the future
unsigned long startTime = 0;           // time we started counting down
unsigned long classUpTime = 0;         // time to class up
unsigned long prepUpTime = 0;          // time to prep up
unsigned long prepDownTime = 0;        // time to prep down
unsigned long goTime = 0;              // time to start
unsigned int remainingFlagDisp = 0;    // time to display
short int clockRunning = FALSE;        // is the timer running?

// delay before a cancel is allowed (ms)
unsigned long resetDelay = 3000;        // don't allow immediate cancellation, wait a few seconds

// matrix to hold beep times and a variable to hold the index
const unsigned long beepMatrix[2][19] = {
  { 50, 40, 30, 20, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }, //Seconds in the countdown
  {  4,  4,  4,  4,  1,  1,  1,  1,  1,  2, 2, 2, 2, 2, 3, 3, 3, 3, 3 }  //Number of beeps (4 = one long beep)
};
int beepIndex = -1; // initialize the matrix index

// Countdown Mode
short int countMode = 1;

// Functions

// Print what state we are in (for debugging)
void StatePrint(int state)
{
  Serial.print("Now in state: ");
  Serial.println(state);
}

// Short and Long Horn
void shorthorn()
{
  digitalWrite(RELAY, HIGH);
  if (digitalRead(RELAY)==HIGH)
  {
  Serial.print("Relay is high");
  Serial.print(" ");
  }
  Serial.println("Short Horn");
  delay(600);
  digitalWrite(RELAY, LOW);
}
void longhorn()
{
  digitalWrite(RELAY, HIGH);
  Serial.println("Long Horn");
  delay(1200);
  digitalWrite(RELAY, LOW);
}

//stuff to print on the display
//print rEdy
void printready()
{
  matrix.writeDigitRaw(0, B01010000);
  matrix.writeDigitRaw(1, B01111001);
  matrix.drawColon(false);
  matrix.writeDigitRaw(3, B01011110);
  matrix.writeDigitRaw(4, B01101110);
  matrix.writeDisplay();
}

//print P in the first position
void print_P()
{
  matrix.writeDigitRaw(0, B01110011);
  matrix.writeDisplay();
}
//print C in the first position
void print_C()
{
  matrix.writeDigitRaw(0, B00111001);
  matrix.writeDisplay();
}
//print U in the second position
void print_u()
{
  matrix.writeDigitRaw(1, B00111110);
  matrix.writeDisplay();
}
//print u in the second position
void print_d()
{
  matrix.writeDigitRaw(1, B01011110);
  matrix.writeDisplay();
}
//print 6'
void print_6min()
{
  matrix.clear();
  matrix.drawColon(false);
  matrix.writeDigitNum(0, 6);
  matrix.writeDigitRaw(1, B00100000);
  matrix.writeDisplay();
}
//print 5'
void print_5min()
{
  matrix.clear();
  matrix.drawColon(false);
  matrix.writeDigitNum(0, 5);
  matrix.writeDigitRaw(1, B00100000);
  matrix.writeDisplay();
}
//print 5'r
void print_5minrep()
{
  matrix.clear();
  matrix.drawColon(false);
  matrix.writeDigitNum(0, 5);
  matrix.writeDigitRaw(1, B00100000);
  matrix.writeDigitRaw(3, B01010000);
  matrix.writeDisplay();
}
void printcount(int timecount)
{
  int x = 0;
  remainingFlagDisp = timecount / 1000;
  int s = remainingFlagDisp % 60;
  remainingFlagDisp = (remainingFlagDisp - s) / 60;
  int m = remainingFlagDisp % 60;
  x = s + (m * 100);
  if (x > 99)
  {
    matrix.writeDigitNum(1, (x / 100) % 10, false);
  }
  matrix.drawColon(true);
  matrix.writeDigitNum(3, (x / 10) % 10, false);
  matrix.writeDigitNum(4, x % 10, false);
  matrix.writeDisplay();
}

// This function checks the countdown to see if we need to alert to a flag change
int minuteCountDown(unsigned long remainingTime, int beepMatrixIndex)
{
  unsigned long beepSeconds = beepMatrix[0][beepMatrixIndex]; //Get the countdown seconds we are looking for
  unsigned long beepCounter = beepMatrix[1][beepMatrixIndex]; //Get the number of beeps

  beepSeconds = beepSeconds * 1000ul;   //convert to milliseconds
  if (remainingTime >= beepSeconds)     //not there yet
    return beepMatrixIndex;             //return index given when called
  else {                                //beep
    beep(beepCounter);
    beepMatrixIndex++;                  //increment index
    return beepMatrixIndex;             //return incremented index
  }
}

// This function provides sounds during the last 50 seconds to any flag
void beep(int beepCount)
{
  const int toneFreq = 1000;
  const int shortToneLength = 100;
  const int longToneLength = 700;
  const int toneDelay = 200;

  switch (beepCount) {                  //number of beeps
    case 1:
      Serial.println("1 Beep");
      tone(TONE_PIN, toneFreq, shortToneLength);
      delay(shortToneLength);
      break;
    case 2:
      Serial.println("2 Beeps");
      tone(TONE_PIN, toneFreq, shortToneLength);
      delay(toneDelay);
      tone(TONE_PIN, toneFreq, shortToneLength);
      break;
    case 3:
      Serial.println("3 Beeps");
      tone(TONE_PIN, toneFreq, shortToneLength);
      delay(toneDelay);
      tone(TONE_PIN, toneFreq, shortToneLength);
      delay(toneDelay);
      tone(TONE_PIN, toneFreq, shortToneLength);
      break;
    case 4:
      Serial.println("long beep");            // Index 4 is a long beep, not 4 beeps
      tone(TONE_PIN, toneFreq, longToneLength);
      delay(longToneLength);
      break;
    default:
      return;
  }
}
void resetCounter()
{
  state = 0;
  remainingFlagTime = 0;
  remainingGoTime = 0;
  startTime = 0;
  classUpTime = 0;
  prepUpTime = 0;
  prepDownTime = 0;
  goTime = 0;
  remainingFlagDisp = 0;
  return;
}

void modeBeeps(int modeBeepCount) {
  switch (modeBeepCount) {
    case 1: {
        Serial.println("Countmode = 1");        // Go around back to mode 1
        beep(1);
        print_6min();                           // print "6'"
        break;
      }
    case 2: {
        Serial.println("Countmode = 2");        // switch to mode 2
        beep(2);
        print_5min();                           // print "5'"
        break;
      }
    case 3: {
        Serial.println("Countmode = 3");        // switch to mode 3
        beep(3);
        print_5minrep();                        // print "5'r
        break;
      }
    default:
      break;
  }
}

// Set everything up

void setup() {
  // Set up serial so I can see whats happening for debug
  Serial.begin(57600);
  while (!Serial) {
    ;
  }
  Serial.println("Serial Port Ready");

  // Setup start button with an internal pull-up :
  pinMode(START_BUTTON, INPUT_PULLUP);
  // After setting up the button, setup the Bounce instance :
  start_debounce.attach(START_BUTTON);
  start_debounce.interval(100);         // debounce interval in ms

  // Set GPIOs to correct states
  pinMode(RELAY, OUTPUT);               // Relay
  digitalWrite(RELAY, LOW);             // Make sure it starts out in a low state
  pinMode(START_BUTTON, INPUT);         // Start Button
  matrix.begin(0x70);                   // Prepare the display
  printready();                         // Print "rEdy" on display
  StatePrint(state);

  pinMode(MODE_BUTTON, INPUT_PULLUP);

}

void loop() {
  // Update the Bounce instance for the start button
  start_debounce.update();

  // Get the start button
  int startButton = start_debounce.read();

  // Start the sequence
  if ((startButton == LOW) && (state == 0)) {
    Serial.println("Start button press");
    Serial.print("countMode = ");
    Serial.println(countMode);
    startTime = 0;
    switch (countMode) {
      case 1:
        state = 1;                        //Start in 6 minute mode (1 min delay to Class up)
        clockRunning = TRUE;
        break;
      case 2:
        state = 2;;                       //Start in 5 minute mode (immediate Class up)
        clockRunning = TRUE;
        break;
      case 3:
        state = 2;                        //Start in 5 minute cycle mode (immediate Class up)
        clockRunning = TRUE;
        break;
      default:
        state = 0;
        clockRunning = FALSE;
        return;
    }
  }
  // Set the mode
  // Not sure why, but couldn't get a second instance of BOUNCE to work on this button. So
  // we do it manually
  int reading = digitalRead(MODE_BUTTON);

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == LOW) {
        countMode++;
        Serial.println(countMode);
        if (countMode == 4) {
          countMode = 1;
        }
        modeBeeps(countMode);
      }
    }
  }
  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonState = reading;


  switch (state) {
    case 0:
      break;
    case 1:                                     // Button was pushed - One minute to start class up
      {
        if (startTime == 0) {                   // just started counting down, initialize
          startTime = millis();
          // calculate times
          classUpTime = startTime + 60000ul;     // class flag up
          prepUpTime = startTime + 120000ul;     // prep flag up
          prepDownTime = startTime + 300000ul;   // prep flag down
          goTime = startTime + 360000ul;         // start signal (go)
          beepIndex = 0;                         // array index for the minute countdown
          StatePrint(state);
          shorthorn();                            // this horn indicates AP coming down
        } else if (classUpTime >= millis()) {     //waiting for the flag
          remainingFlagTime = classUpTime - millis();
          remainingGoTime = goTime - millis();
          printcount(remainingFlagTime);
          print_C();
          print_u();
          if (beepIndex < 20)
            beepIndex = minuteCountDown(remainingFlagTime, beepIndex);
        } else {
          state = 2;
          shorthorn();
          StatePrint(state);
          beepIndex = 0;
        }
        break;
      }
    case 2:                                       // We are in the first minute
      {
        if (startTime == 0) {                     // just started counting down, initialize
          startTime = millis();                   // We're doing this again because we might be beginning timing from this point for modes 2 and 3
          // calculate times
          classUpTime = startTime;                // class flag up (this is actually unnecessary)
          prepUpTime = startTime + 60000ul;       // prep flag up
          prepDownTime = startTime + 240000ul;    // prep flag down
          goTime = startTime + 300000ul;          // start signal (go)
          beepIndex = 0;                          // array index for the minute countdown
          StatePrint(state);
          shorthorn();
        } else if (prepUpTime >= millis()) {       // waiting for the flag
          remainingFlagTime = prepUpTime - millis();
          printcount(remainingFlagTime);
          print_P();
          print_u();
          remainingGoTime = goTime - millis();
          if (beepIndex < 20)
            beepIndex = minuteCountDown(remainingFlagTime, beepIndex);
        } else {
          // Prep Flag Up
          state = 3;
          shorthorn();
          StatePrint(state);
          beepIndex = 0;
          remainingFlagTime = 60000;
        }
        break;
      }
    case 3:                                       //We are in prep
      {
        if (prepDownTime >= millis()) {           //waiting for the flag
          remainingFlagTime = prepDownTime - millis();
          remainingGoTime = goTime - millis();
          printcount(remainingFlagTime);
          print_P();
          //this prevents the minutes character being overwritten before the last minute
          if (remainingFlagTime <= 60000)
          {
            print_d();
          }
          if (beepIndex < 20)
            beepIndex = minuteCountDown(remainingFlagTime, beepIndex);
        } else {
          // Prep Flag Down - enter final minute
          state = 4;
          longhorn();
          StatePrint(state);
          beepIndex = 0;
          remainingFlagTime = 60000;                //60 seconds to start
        }
        break;
      }
    case 4:                                         //We are in last minute
      {
        if (goTime >= millis()) {                   //waiting for the flag
          remainingFlagTime = goTime - millis();
          remainingGoTime = goTime - millis();
          printcount(remainingFlagTime);
          print_C();
          print_d();
          if (beepIndex < 20)
            beepIndex = minuteCountDown(remainingFlagTime, beepIndex);
        } else {
          // Class Flag Down (start)
          if (countMode != 3)                      //we don't want to beep the horn twice when we start the next sequence
            shorthorn();
          state = 5;
          StatePrint(state);
          beepIndex = 0;
        }
        break;
      }
    case 5:                                       //We have started
      {
        unsigned long currentMillis = millis();
        // If we are in Mode 3, reset to state 2, set startTime to 0, then recycle
        if (countMode == 3) {
          state = 2;
          startTime = 0;
          return;
        } else {
          matrix.clear();
          printcount(currentMillis - goTime);
        }
        break;
      }
    default:
      return;
  }

}