rafu
Published © GPL3+

V2 View direct Resistors values in accodance tthe color code

Shows to visually impaired or ignoring the resistors colour code, lazy techs etc..., either the exact value or value in E12 or E24 series

BeginnerWork in progress3,118
V2 View direct Resistors values in accodance tthe color code

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
Resistor 47.5 ohm
Resistor 47.5 ohm
×1
Resistor 1k ohm
Resistor 1k ohm
×1
Resistor 10k ohm
Resistor 10k ohm
×1
Resistor 100k ohm
Resistor 100k ohm
×1
Resistor 1M ohm
Resistor 1M ohm
×1
Trimmer Potentiometer, 1 kohm
Trimmer Potentiometer, 1 kohm
×1
SSD1306 I2C OLED graphic display
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

PDF schematic

Code

ohm_meter.ino

Arduino
/*********************************************************************************************************************
    A direct reading ohm meter, values extracted from the 24 resistors serie

    Raphal Ollier (France)
    V1.1 - Software upgrades
    V1.2 - Add servo to lock resistor during measure, and switch to control it
    V1.3 - Switch and servo implemented
    v1.4 - Misc. Soft. Improvements
    v1.5 - Timed closing and end contact implemented 

    Largely inspired (and partly copied) from the work of Federico Vivaldi : Sorting resistors the lazy way
    https://create.arduino.cc/projecthub/federico-vivaldi/sorting-resistors-the-lazy-way-ceb557?ref=platform&ref_id=424_trending___&offset=7


 *********************************************************************************************************************/

// External libraries
#include <Servo.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Constantes
#define BatDispWidth    20             // Display battery width
#define BatDispHeight   7              // Display battery height
#define BatDispPosX     105            // Display battery position
#define BatDispPosY     0

#define ServoCmd        9           // Data output for PWM
#define SwitchInput     8           // Data input for switch
#define ServoEnd        10          // Data input for end contact


// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define ServoOpen       120         // 180 max. quasiment 1 par unit         
#define ServoClosed     0
int ServoVal = ServoOpen / 2;         // variable for servo pos
int SwCount = 3;         // counter init for switch debounce
int VCount = SwCount;    // counter variable for switch debounce
int ActiveKey = 1;       // variable key active
boolean Opened = true;   // variable for door state

// Srie de rsistances par 24
int SerieVal[] =        {10, 11, 12, 13, 15, 16, 18, 20, 22, 24, 27, 30,
                         33, 36, 39, 43, 47, 51, 56, 62, 68, 75, 82, 91, 100
                        };



int DelayConv = 10;    // time allocated to A/D conversion
int MeasuresNbr = 10;   // number of conversions and divider

int MinRaw = 300;       // original value 350
int MaxRaw = 820;       // original value 800

int R1 = 100;           // Base resistors
int R2 = 1000;
int R3 = 10000;
long R4 = 100000;
long R5 = 1000000;
long Rn;                // Base resistor used for conversion

int D2 = 2;             // Data Bus
int D3 = 3;
int D4 = 4;
int D5 = 5;
int D6 = 6;

int ValBrut = 0;

int StrLength = 0;      //chain length

String ValueStr = "000" ;
String SuffixStr = " Mo";

float Raw = 0;          // Raw read value
float Ru = 0;           // Unknown resistor value

int AnalogRead = A0;    // Analog port for reading
Servo Trappe;
void setup() {
  // ******************  Adafruit address test routine **************************
  Serial.begin(9600);
  // Serial.println (display.begin(SSD1306_SWITCHCAPVCC, 0x3C));

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  // ****************** Draw rectangles at the beginning of the program *********
  Rectangles();
  Trappe.attach(ServoCmd);
  GoOpen();
  delay(1000);                       // Time for servo to arrive
  pinMode(SwitchInput, INPUT);
  pinMode(ServoEnd, INPUT);
}

// ****************** Main loop ***********************************************
void loop() {
  ActiveKey = digitalRead(SwitchInput);
  if (ActiveKey == 0) {             // key on
    if (VCount == 1) {
      if (Opened == true) {   // test if opened
        GoClose();
        VCount--;
      }      else {
        GoOpen();
        VCount--;
      }
    } else {            // VCount<>1
      if (VCount != 0) {            // VCount<>0
        VCount--;
      }
    }
  } else {
    VCount = SwCount;               // reinit counter
  }

  pinMode(D2, OUTPUT);              // original setup, REF 1M
  pinMode(D3, INPUT);
  pinMode(D4, INPUT);
  pinMode(D5, INPUT);
  pinMode(D6, INPUT);

  digitalWrite(D2, HIGH);
  Reading_analog_in();
  Rn = R5;

  if (Raw < MinRaw || Raw > MaxRaw) {           // REF 100k
    digitalWrite(D2, LOW);
    pinMode(D2, INPUT);
    pinMode(D3, OUTPUT);
    digitalWrite(D3, HIGH);
    Reading_analog_in();
    Rn = R4;

    if (Raw < MinRaw || Raw > MaxRaw) {         // REF 10k
      digitalWrite(D3, LOW);
      pinMode(D3, INPUT);
      pinMode(D4, OUTPUT);
      digitalWrite(D4, HIGH);
      Reading_analog_in();
      Rn = R3;

      if (Raw < MinRaw || Raw > MaxRaw) {       // REF 1k
        digitalWrite(D4, LOW);
        pinMode(D4, INPUT);
        pinMode(D5, OUTPUT);
        digitalWrite(D5, HIGH);
        Reading_analog_in();
        Rn = R2;

        if (Raw < MinRaw || Raw > MaxRaw) {     // REF 100 impossible to decrease
          digitalWrite(D5, LOW);
          pinMode(D5, INPUT);
          pinMode(D6, OUTPUT);
          digitalWrite(D6, HIGH);
          Reading_analog_in();
          Rn = R1;
        }
      }
    }
  }
  if (Raw > 1020) {     // Raw value out of window
    Ru = 11000000;      // to display ">10 Mo"
  } else {
    Ru = ((Raw * Rn) / (1024 - Raw)); // Calculation for resistor to find but lower than 10Mo
  }

  // ****************** Display assignments & calculation ***********************

  // NEEDS IMPROVEMENTS !!

  StrLength = String(Ru, 0).length();

  if (StrLength > 7) {
    ValueStr = ">10";
    SuffixStr = " Mo";
  } else {
    if (StrLength > 6) {
      /*    ValueStr = "<10";             // not used, only to debug
          SuffixStr = " Mo";*/
      Ru = Ru / 100000;
      Plusproche();               // call to comparison routine

      ValueStr = String(SerieVal[ValBrut] / 10);
      SuffixStr = " Mo";
      if (ValBrut == 24 ) {
        ValueStr = ("10");
        SuffixStr = " Mo";
      }
    }  else {
      if (StrLength > 5) {
        Ru = Ru / 10000;
        Plusproche();               // call to comparison routine
        ValueStr = String(SerieVal[ValBrut]);
        SuffixStr = "0 ko";
        if (ValBrut == 24) {
          ValueStr = ("1");
          SuffixStr = " Mo";
        }
      } else {
        if (StrLength > 4) {
          Ru = Ru / 1000;
          Plusproche();             // call to comparison routine
          ValueStr = String(SerieVal[ValBrut]);
          SuffixStr = " ko";
        } else {
          if (StrLength > 3) {
            Ru = Ru / 100;
            Plusproche();           // call to comparison routine
            ValueStr = String(SerieVal[ValBrut]).substring(0, 1) + "." + String(SerieVal[ValBrut]).substring(1, 2);
            SuffixStr = " ko";
          } else {
            if (StrLength > 2) {
              Ru = (Ru / 10);
              Plusproche();         // call to comparison routine
              ValueStr = String(SerieVal[ValBrut]);
              SuffixStr = "0 ohm";
              if (ValBrut == 24) {
                ValueStr = ("1");
                SuffixStr = " ko";
              }
            } else {
              Plusproche();         // call to comparison routine
              ValueStr = String(SerieVal[ValBrut]);
              if (ValBrut == -1) {
                ValueStr = ("< 10");
              }
              SuffixStr = " ohm";
            }
          }
        }
      }
    }
  }
  DisplayOled();                    // call display routine
  // impression();                  // call to debug infos
}

void Plusproche() {
  for (int i = 0; i < 25; i++) {    // scan into the 24 normalized values
    int SerieDifference = (Ru - SerieVal[i]);   // dif between R and normalized
    if (SerieDifference == 0) {                 // exact norm value
      ValBrut = i;
      break;
    }
    if (SerieDifference < 0) {                  // next norm value
      int old = (Ru - SerieVal[i - 1]);
      if (old - abs( SerieDifference) < 0) {    // test n with n-1
        ValBrut = (i - 1);
      } else {
        ValBrut = (i);
      }
      break;
    }
  }
}

void GoClose() {
  ServoVal = (ServoOpen / 2);      // semi fermeture de la trappe
  while (digitalRead(ServoEnd) && (ServoVal > ServoClosed)) {
    ServoVal--;
    Trappe.write (ServoVal);
    Serial.println(ServoVal);
    delay(10);
  }
  Trappe.write (ServoVal-5);
  Serial.println(ServoVal);
  Opened = false;
}
void GoOpen() {
  Trappe.write (ServoOpen);         // ouverture de la trappe
  Opened = true;
}
void Reading_analog_in () {
  delay(DelayConv);                             // delay for conversion
  Raw = 0;                                      // init Raw ValueStr
  for (int x = 0; x < MeasuresNbr; x++) {
    Raw += analogRead(AnalogRead);
  }
  Raw = Raw / MeasuresNbr;                      // average value
}

void DisplayOled() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.print("S24");

  // *************** display battery status **************
  display.setCursor(60, 0);
  display.print("Battery ");
  display.drawRect(BatDispPosX, BatDispPosY, BatDispWidth, BatDispHeight, WHITE);
  display.fillRect(BatDispPosX, BatDispPosY, BatDispWidth * 0.5, BatDispHeight, WHITE); // battery at 50%

  // *************** display resistor value **************
  display.setCursor(0, 12);
  display.setTextSize(3);
  display.print(ValueStr);
  display.print(SuffixStr);
  display.display();                // needed to reinit drawings
}

void Rectangles() {                 // routine which draws in and out rectangles, purely cosmetic !
  display.clearDisplay();
  for (int i = 0; i < 16; i++) {
    display.drawRect(i, i, (SCREEN_WIDTH - 1) - 2 * i, (SCREEN_HEIGHT - 1) - 2 * i, WHITE);
    display.display();
    delay(100);
    display.drawRect(i, i, (SCREEN_WIDTH - 1) - 2 * i, (SCREEN_HEIGHT - 1) - 2 * i, BLACK);
  }
  for (int i = 15; i > 0; i--) {
    display.drawRect(i, i, (SCREEN_WIDTH - 1) - 2 * i, (SCREEN_HEIGHT - 1) - 2 * i, WHITE);
    display.display();
    delay(100);
    display.drawRect(i, i, (SCREEN_WIDTH - 1) - 2 * i, (SCREEN_HEIGHT - 1) - 2 * i, BLACK);
  }
}

void impression() {                 // routine to print debug values, not necessary
  Serial.print("Raw : ");
  Serial.println(Raw);
  Serial.print("Rn : ");
  Serial.println(Rn);
  Serial.print("ValBrut : ");
  Serial.println(ValBrut);
  Serial.print("Ru aprs = ");
  Serial.println(Ru);
  Serial.print ("Valeur et Suffixe : ");
  Serial.print(ValueStr);
  Serial.println(SuffixStr);
  Serial.println (StrLength);
  Serial.println (" ");
}

Credits

rafu

rafu

1 project • 2 followers
Retired, former engineer in stage lighting equipment

Comments