Potentiometer (0-1023) to Binary conversion (0-255) printed to 8 LEDs

Potentiometer (0-1023) to Binary conversion (0-255) printed to 8 LEDs

Arduino Uno with 10K potentiometer wired to A0.

I was interested in creating an Analog to Digital Audio Frequency Generator for a science museum exhibit. We thought it would be interesting for visitors to see how you would proportion a potentiometer voltage to digital 0's and 1's and produce audio frequencies of a specific range. I had no luck with any of the internet suggestions that I could find. When I discovered a solution that works I thought I would share the solution and maybe spare others the headaches that I encountered.

The following code worked for me:

void setup() {
  pinMode(4, OUTPUT);  //Speaker Amp for Tone Sounds  (10K Resistor)
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);

  Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(A0);
  int freq = sensorValue;
  sensorValue = map(sensorValue, 0, 1023, 0, 255);  //Map Potentiometer range to 8 bit binary range
  freq = map(freq, 0, 1023, 200, 2000);  //Map Potentiometer range to frequency range
  Serial.print("Decimal = ");
  Serial.print(sensorValue);
  Serial.print("\t Binary = ");
  Serial.println(sensorValue, BIN);

  if (sensorValue >= 0 && sensorValue <= 1023) {
    digitalWrite(5, (sensorValue & 1));
    digitalWrite(6, (sensorValue & 2));
    digitalWrite(7, (sensorValue & 4));
    digitalWrite(8, (sensorValue & 8));
    digitalWrite(9, (sensorValue & 16));
    digitalWrite(10, (sensorValue & 32));
    digitalWrite(11, (sensorValue & 64));
    digitalWrite(12, (sensorValue & 128));
  }

  tone(4, freq); //tone (pin, frequency)
  delay(20);
}

More efficient:

int freq = map(sensorValue, 0, 1023, 200, 2000);  //Map Potentiometer range to frequency range
sensorValue = sensorValue>>2;  //Map Potentiometer range to 8 bit binary range - this is faster and uses less flash.

The map of 0~1023 to 0~255, you're just dividing it by 4 (so most of map() is doing unnecessary steps). And to divide by a power of two, right-shifting that many bits is more efficient than division (there is no hardware division on most Arduino-supported processors, and the compiler usually isn't smart enough to realize that the rightshift is equivalent, so it pulls in the much larger and slower division routine)...

That all said, you may end up wanting to add a bit of hysteresis so that the jitter that occurs when it's between two values doesn't make the leds flicker.

DrAzzy

Thank you for your suggestions, I learn best by examples that are accompanied by insightful explanations.

I searched the forum for details regarding Adding Hysteresis and none of it is sinking in...if you could show me how I could modify my code I will have a concrete example for future reference : )

Wrote this some time ago.
Leo..

// converts the position of a 10k lin(B) pot to a byte (0-255)
// pot connected to A0, 5volt and ground

int rawValue; // raw reading
int oldValue; // for deadband
byte Byte; // final byte
byte oldByte; // for printing

void setup() {
  Serial.begin(9600);
}

void loop() {
  // rawValue = analogRead(A0); // dummy read, if needed
  rawValue = analogRead(A0); // read pot
  if (rawValue < (oldValue - 2) || rawValue > (oldValue + 2)) { // add some deadband
    oldValue = rawValue; // update value
    Byte = oldValue >> 2; // convert 10-bit to 8-bit
    if (oldByte != Byte) { // only print if value changes
      Serial.print("Byte is: ");
      Serial.println(Byte);
      oldByte = Byte; // update value
    }
  }
}

I forgot to mention that I used a 10 turn pot for my application and I didn't notice any jumping of the binary LED's, the transition from 1 to 2 to 3 up to 7, etc. Adding code for hysteresis can't hurt and I will try implementing it so I have a template for future applications but is it necessary for a 10 turn pot?

There is always a spot on the pot that the A/D will hesitate between two values.
That migh or might not be a problem.
A single turn pot gives a rock-solid byte with that sketch.

The code also prints things once, when the value actually changes.
You byte>bits code could also do that if you add it inside that last if() statement.
Leo..

Wawa. Could you show me how my could should be modified because right now I'm so confused about all of the options that posting my guess as to what should be done would not serve anyone well who might have a use for it in the future. The reason why I shared my code was because none of the solutions that I found elsewhere worked and the follow up comments only made things worse... I thought sharing my solution would spare someone my agony. If you show what's right then it will serve everyone much better, Thanks : )

Try to understand the code, so you can do that yourself next time.
Partially tested merged code.
Leo..

// converts the position of a 10k lin(B) pot to a byte (0-255), and then displays the bits with eight LEDs
// pot connected to A0, 5volt and ground

int rawValue; // raw reading
int oldValue; // for deadband
byte Byte; // final byte
byte oldByte; // for printing
unsigned int freq; // tone
unsigned long duration = 3000; // tone duration in milliseconds

void setup() {
  Serial.begin(9600);
  for (int i = 4; i < 13; i++) pinMode(i, OUTPUT); // make pin 4-12 output
}

void loop() {
  // rawValue = analogRead(A0); // dummy read, if needed
  rawValue = analogRead(A0); // read pot
  if (rawValue < (oldValue - 2) || rawValue > (oldValue + 2)) { // add some deadband
    oldValue = rawValue; // update value
    Byte = oldValue >> 2; // convert 10-bit to 8-bit
    if (oldByte != Byte) { // only print if value changes
      Serial.print("Byte value: ");
      Serial.print(Byte);
      Serial.print("  ");
      Serial.print("BIN: ");
      Serial.println(Byte, BIN);
      digitalWrite(5, (Byte & 1));
      digitalWrite(6, (Byte & 2));
      digitalWrite(7, (Byte & 4));
      digitalWrite(8, (Byte & 8));
      digitalWrite(9, (Byte & 16));
      digitalWrite(10, (Byte & 32));
      digitalWrite(11, (Byte & 64));
      digitalWrite(12, (Byte & 128));
      freq = map(Byte, 0, 255, 200, 2000);
      Serial.print("Tone frequency: ");
      Serial.print(freq);
      Serial.println(" Herz\n");
      tone(4, freq, duration); // tone (pin, frequency, duration)
      oldByte = Byte; // update value
    }
  }
}

i have done the same thing. Did you mean like

ssgr, Your bar graph code works well but it does not solve the problem that we were addressing.

Wawa's code is really an excellent solution, it effectively addresses potentiometer anomalies, it's efficient and the output is engaging to observe. Wawa nailed it : )

The code could be shrunk considerably with the use of an array and a for() loop.

dlwiener:
Potentiometer (0-1023) to Binary conversion (0-255) printed to 8 LEDs

Arduino Uno with 10K potentiometer wired to A0.

I was interested in creating an Analog to Digital Audio Frequency Generator for a science museum exhibit. We thought it would be interesting for visitors to see how you would proportion a potentiometer voltage to digital 0's and 1's and produce audio frequencies of a specific range. I had no luck with any of the internet suggestions that I could find. When I discovered a solution that works I thought I would share the solution and maybe spare others the headaches that I encountered.

The following code worked for me:

void setup() {

pinMode(4, OUTPUT);  //Speaker Amp for Tone Sounds  (10K Resistor)
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);

Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(A0);
  int freq = sensorValue;
  sensorValue = map(sensorValue, 0, 1023, 0, 255);  //Map Potentiometer range to 8 bit binary range
  freq = map(freq, 0, 1023, 200, 2000);  //Map Potentiometer range to frequency range
  Serial.print("Decimal = ");
  Serial.print(sensorValue);
  Serial.print("\t Binary = ");
  Serial.println(sensorValue, BIN);

if (sensorValue >= 0 && sensorValue <= 1023) {
    digitalWrite(5, (sensorValue & 1));
    digitalWrite(6, (sensorValue & 2));
    digitalWrite(7, (sensorValue & 4));
    digitalWrite(8, (sensorValue & 8));
    digitalWrite(9, (sensorValue & 16));
    digitalWrite(10, (sensorValue & 32));
    digitalWrite(11, (sensorValue & 64));
    digitalWrite(12, (sensorValue & 128));
  }

tone(4, freq); //tone (pin, frequency)
  delay(20);
}

dlwiener:
Potentiometer (0-1023) to Binary conversion (0-255) printed to 8 LEDs

Arduino Uno with 10K potentiometer wired to A0.

I was interested in creating an Analog to Digital Audio Frequency Generator for a science museum exhibit. We thought it would be interesting for visitors to see how you would proportion a potentiometer voltage to digital 0's and 1's and produce audio frequencies of a specific range. I had no luck with any of the internet suggestions that I could find. When I discovered a solution that works I thought I would share the solution and maybe spare others the headaches that I encountered.

The following code worked for me:

void setup() {

pinMode(4, OUTPUT);  //Speaker Amp for Tone Sounds  (10K Resistor)
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);

Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(A0);
  int freq = sensorValue;
  sensorValue = map(sensorValue, 0, 1023, 0, 255);  //Map Potentiometer range to 8 bit binary range
  freq = map(freq, 0, 1023, 200, 2000);  //Map Potentiometer range to frequency range
  Serial.print("Decimal = ");
  Serial.print(sensorValue);
  Serial.print("\t Binary = ");
  Serial.println(sensorValue, BIN);

if (sensorValue >= 0 && sensorValue <= 1023) {
    digitalWrite(5, (sensorValue & 1));
    digitalWrite(6, (sensorValue & 2));
    digitalWrite(7, (sensorValue & 4));
    digitalWrite(8, (sensorValue & 8));
    digitalWrite(9, (sensorValue & 16));
    digitalWrite(10, (sensorValue & 32));
    digitalWrite(11, (sensorValue & 64));
    digitalWrite(12, (sensorValue & 128));
  }

tone(4, freq); //tone (pin, frequency)
  delay(20);
}

What if a pushbutton would turn the led binary code into two's complement? What changes there would be in the code?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.