Part 4 of : 7-digit seven segment display using ESP-12F IOT module through 32-bit serial-in parallel-out shift register module

Modules required

Reference blogs

ESP-12F IOT module programmer circuit and explanation : http://www.haberocean.com/2019/05/esp-12f-iot-module-programmer-circuit/

32-bit serial-in parallel-out shift register module using ESP-12F IOT module : http://www.haberocean.com/2019/05/32-bit-shift-register-module-using-esp-12f-iot-module/

Control the outputs of ESP-12F IOT module from android app : http://www.haberocean.com/2019/06/part-3-of-control-the-outputs-of-esp-12f-iot-module-from-an-android-app/

Video demonstration

Upload the following program to your ESP-12F IOT module.

//Pin connected to ST_CP (12) of 74HC595
int latchPin = 4;
//Pin connected to SH_CP (11) of 74HC595
int clockPin = 12;
////Pin connected to DS (14) of 74HC595
int dataPin = 13;

int numDigitArray[7]  = {0, 0, 0, 0, 0, 0, 0};
int dotPointArray[7]  = {0, 0, 0, 0, 0, 0, 0};

void displayValueAndDigit(byte value, byte digit, byte dp, byte NDY) {
    digitalWrite(latchPin, 1);
    customDelay();
    shiftOut(dataPin, clockPin, value);
    shiftOut(dataPin, clockPin, digit);
    shiftOut(dataPin, clockPin, dp);
    shiftOut(dataPin, clockPin, 0x00);
    digitalWrite(latchPin, 0);
    customDelay();
}

void displayNumberInDigit(int numberToDisplayInDigit, int digitNumber, byte dotPointHex) {
  byte numberHex, digitNumberHex;
  
  switch(numberToDisplayInDigit)
  {
    case 0:
      numberHex = 0x00; 
      break;
    case 1:
      numberHex = 0x01;
      break;
    case 2:
      numberHex = 0x02;
      break;
    case 3:
      numberHex = 0x03;
      break;
    case 4:
      numberHex = 0x04; 
      break;
    case 5:
      numberHex = 0x05;
      break;
    case 6:
      numberHex = 0x06;
      break;
    case 7:
      numberHex = 0x07;
      break;
    case 8:
      numberHex = 0x08;
      break;
    case 9:
      numberHex = 0x09;
      break;
    case 15:
      numberHex = 0x0F;
      break;
    default:
      numberHex = 0x00;
      break;
  }

  switch(digitNumber) {
    case 0:
      digitNumberHex = 0xBF;
      break;
    case 1:
      digitNumberHex = 0xDF;
      break;
    case 2:
      digitNumberHex = 0xEF;
      break;
    case 3:
      digitNumberHex = 0xF7;
      break;
    case 4:
      digitNumberHex = 0xFB;
      break;
    case 5:
      digitNumberHex = 0xFD;
      break;
    case 6:
      digitNumberHex = 0xFE;
      break;
    default:
      digitNumberHex = 0x00;
      break;
  }

  displayValueAndDigit(numberHex, digitNumberHex, dotPointHex, 0x00);
  displayValueAndDigit(numberHex, 0xFF, dotPointHex, 0x00);
}

int decPartProcess(double decPart) {
  
  int i = 0;
  double decPartMult10, decPartMult100, tempFractionalPart;
  int dotPointPosition;
  int decPartArray[] = {0, 0};
  int decPartToInt = int(decPart * 100);

  //  decPart      decPartToInt
  //  .0           0
  //  .05          5
  //  .5           50
  //  .58          58

  decPartMult10 = decPart * 10;
  decPartArray[0] = (int) decPartMult10;
  tempFractionalPart = decPartMult10 - decPartArray[0]; 
  
  decPartMult100 = tempFractionalPart * 10;
  decPartArray[1] = (int) decPartMult100;
  tempFractionalPart = decPartMult100 - decPartArray[1];

  //  decPartArray[0]     decPartArray[1]   
  //  0                   0
  //  0                   5
  //  5                   0
  //  5                   5

  if(decPartArray[0] == 0 && decPartArray[1] == 0) {
    dotPointArray[0] = 0;
    dotPointArray[1] = 0;
    dotPointArray[2] = 0;
    dotPointArray[3] = 0;
    dotPointArray[4] = 0;
    dotPointArray[5] = 0;
    dotPointArray[6] = 0; 
    
    dotPointPosition = 6;
    
  } else if(decPartArray[0] == 0 && decPartArray[1] > 0) {
    dotPointArray[0] = 0;
    dotPointArray[1] = 0;
    dotPointArray[2] = 0;
    dotPointArray[3] = 0;
    dotPointArray[4] = 1;
    dotPointArray[5] = 0;
    dotPointArray[6] = 0;    

    numDigitArray[5] = decPartArray[0];
    numDigitArray[6] = decPartArray[1];
    dotPointPosition = 4;
         
  } else if(decPartArray[0] > 0 && decPartArray[1] == 0) {
    dotPointArray[0] = 0;
    dotPointArray[1] = 0;
    dotPointArray[2] = 0;
    dotPointArray[3] = 0;
    dotPointArray[4] = 0;
    dotPointArray[5] = 1;
    dotPointArray[6] = 0;   

    numDigitArray[6] = decPartArray[0];
    dotPointPosition = 5;
    
  } else if(decPartArray[0] > 0 && decPartArray[1] > 0) {
    dotPointArray[0] = 0;
    dotPointArray[1] = 0;
    dotPointArray[2] = 0;
    dotPointArray[3] = 0;
    dotPointArray[4] = 1;
    dotPointArray[5] = 0;
    dotPointArray[6] = 0;    

    numDigitArray[5] = decPartArray[0];
    numDigitArray[6] = decPartArray[1];
    dotPointPosition = 4;
  }

  for(i = 0; i< 7;i++) {
    Serial.print(numDigitArray[i]);
  }

  Serial.print(" ");
  Serial.print(dotPointPosition);
  
  Serial.println("");

  return(dotPointPosition);
}

void intPartProcess(long int intPart, int dotPointPosition, byte sign) {
  //  intPart     dotPointPosition
  //  846         4
  int i = 0;  
  int quotient;
  int tempDotPointPosition = dotPointPosition;
  long int tempIntPart = intPart;

  for(i=0;i<=dotPointPosition;i++) {
    numDigitArray[i] = 15;
  }

  if(tempIntPart == 0) {
    numDigitArray[tempDotPointPosition] = 0;
  }
  
  while(tempIntPart > 0) {
    numDigitArray[tempDotPointPosition] = tempIntPart % 10;
    tempIntPart /= 10;
    tempDotPointPosition--;  
    if(tempDotPointPosition < 0) {
      break;
    }
  }

  if(sign == 0x80) {
    numDigitArray[0] = 15;
  }
}

void customDelay() {
  delayMicroseconds(10);
}

void displayNumber(int dotPointPosition, byte sign) {
  int i;
  byte dotPointHex, dotAndSign;
  
  switch(dotPointPosition) {
    case 0:
      dotPointHex = 0x40;
      break;
    case 1:
      dotPointHex = 0x20;
      break;
    case 2:
      dotPointHex = 0x10;
      break;
    case 3:
      dotPointHex = 0x08;
      break;
    case 4:
      dotPointHex = 0x04;
      break;
    case 5:
      dotPointHex = 0x02;
      break;
    case 6:
      dotPointHex = 0x00;
      break;
    default:
      dotPointHex = 0x00;         
      break;
  }

  dotAndSign = dotPointHex | sign;
  
  for(i=0;i<7;i++) {
    displayNumberInDigit(numDigitArray[i], i, dotAndSign);
  }
  
  /*
  for(int i=0;i<7;i++) {
    Serial.print(numDigitArray[i]);
    Serial.print(" ");
  }
  Serial.println(" ");

  */
}

void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  
  Serial.begin(9600);
}

void loop() {
  byte sign = 0x00;

  //long double numberToDisplay = 646465466.5;
  long double numberToDisplay= random(-99999, 999999) / 15.0;
  
  if(numberToDisplay < 0.0) {
    numberToDisplay*=-1;
    sign = 0x80;
  }
  
  long int intPart = (int) numberToDisplay;
  float decPart = numberToDisplay - intPart;
  int dotPointPosition, i;

  dotPointPosition = decPartProcess(decPart);
  intPartProcess(intPart, dotPointPosition, sign);

  displayNumber(dotPointPosition, sign);

  delay(300);
}

// the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  // This shifts 8 bits out MSB first,
  //on the rising edge of the clock,
  //clock idles low

  //internal function setup
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  //clear everything out just in case to
  //prepare shift register for bit shifting
  digitalWrite(myDataPin, 1);
  customDelay();
  digitalWrite(myClockPin, 1);
  customDelay();

  //for each bit in the byte myDataOut
  //NOTICE THAT WE ARE COUNTING DOWN in our for loop
  //This means that %00000001 or "1" will go through such
  //that it will be pin Q0 that lights.
  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 1);
    customDelay();
    //if the value passed to myDataOut and a bitmask result
    // true then... so if we are at i=6 and our value is
    // %11010100 it would the code compares it to %01000000
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1<<i) ) {
      pinState= 0;
    }
    else { 
      pinState= 1;
    }

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    customDelay();
    //register shifts bits on upstroke of clock pin  
    digitalWrite(myClockPin, 0);
    customDelay();
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 1);
    customDelay();
  }

  //stop shifting
  digitalWrite(myClockPin, 1);
  customDelay();
}

Published by

Leave a Reply

X