Digital To Analog Converter

I am looking to use a binary switch to control a voltage on A0, then convert this to an integer to access an EEPROM address.

I have attempted to use a TLC7524CN DAC, and LM358, but after reading the datasheet and searching the web, I have had no luck.

I’m not sure if I have missed something, or not understanding the circuit correctly, maybe both!

Please can anyone provide a suitable circuit using this IC?

// read address
sensorValue = analogRead(analogInPin);
//outputValue = map(sensorValue, 0, 1023, 0, 255);
outputValue = map(sensorValue, 0, 1023, 0, 5);

// not sure whether to map to 5 volts or highest address?

analogWrite(analogOutPin, outputValue);

Serial.print("Sensor: ");
Serial.print(sensorValue);
Serial.print("\t");

float voltage = sensorValue * (5.0 / 1023.0);
Serial.print("Voltage: ");
Serial.print(voltage);
Serial.print("\t");
        
Serial.print("Address: ");
Serial.print(outputValue);
Serial.print("\t");
        
byte newData = readEEPROM(outputValue);
Serial.print("Data: ");
Serial.println(newData, HEX);

Hi,
Welcome to the forum, thanks for reading the how to message.
OPs circuit;
401a4a9c71e0ff4644d498ff4a4283fb74ceff28.jpg
The fritzy pic is not particularly helpful.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Do you have a DMM to measure voltages?

Can you post your complete code please?

Thanks… Tom… :slight_smile:
PS, Check that your protoboard does not have broken power bus lines down each side.
Protoboards1.jpg

Use of code tags on the first post - Karma++

Thanks for your reply, I have checked the breaks in the protoboard power lines as they have caught me out before! I now fit all my boards with links!

As requested here is my code and attached schematic.

#include <EEPROM.h>

const int buttonPin = 7;
int buttonState;
int lastButtonState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

const int analogInPin = A0;
const int analogOutPin = 9;

int sensorValue = 0;
int outputValue = 0;

byte readEEPROM(int address) {
  byte data = EEPROM.read(address);
  return data;
}

void printContents() {
  for (int base = 0; base <= 255; base += 16) {
    byte data[16];
    for (int offset = 0; offset <= 15; offset += 1) {
      data[offset] = readEEPROM(base + offset);
    }

    char buf[80];
    sprintf(buf, "%03x:  %02x %02x %02x %02x %02x %02x %02x %02x   %02x %02x %02x %02x %02x %02x %02x %02x",
            base, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
            data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);

    Serial.println(buf);
  }
}

void setup() {
  Serial.begin(115200);

  pinMode(buttonPin, INPUT);
  pinMode(analogOutPin, OUTPUT);

  Serial.println("Reading EEPROM");
  printContents();
}

void loop() {
  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == HIGH) {
        // read address
        sensorValue = analogRead(analogInPin);
 
        outputValue = map(sensorValue, 0, 1023, 0, 16); // highest EEPROM address
       
        analogWrite(analogOutPin, outputValue);

        Serial.print("Sensor: ");
        Serial.print(sensorValue);
        Serial.print("\t");

        float voltage = sensorValue * (5.0 / 1023.0);
        Serial.print("Voltage: ");
        Serial.print(voltage);
        Serial.print("\t");
        
        Serial.print("Address: ");
        Serial.print(outputValue);
        Serial.print("\t");
        
        byte newData = readEEPROM(outputValue);
        Serial.print("Data: ");
        Serial.println(newData, HEX);
      }
    }
  }
  lastButtonState = reading;
}

DAC outputs

Sensor: 747 Voltage: 3.65 Address: 11 Data: 1F
Sensor: 745 Voltage: 3.64 Address: 11 Data: 1F
Sensor: 746 Voltage: 3.65 Address: 11 Data: 1F
Sensor: 746 Voltage: 3.65 Address: 11 Data: 1F
Sensor: 746 Voltage: 3.65 Address: 11 Data: 1F
Sensor: 746 Voltage: 3.65 Address: 11 Data: 1F
Sensor: 746 Voltage: 3.65 Address: 11 Data: 1F
Sensor: 745 Voltage: 3.64 Address: 11 Data: 1F
Sensor: 746 Voltage: 3.65 Address: 11 Data: 1F
Sensor: 746 Voltage: 3.65 Address: 11 Data: 1F

When using a potentiometer on A0
The Serial outputs:

Sensor: 0 Voltage: 0.00 Address: 0 Data: 7E
Sensor: 84 Voltage: 0.41 Address: 1 Data: 30
Sensor: 153 Voltage: 0.75 Address: 2 Data: 6D
Sensor: 221 Voltage: 1.08 Address: 3 Data: 79
Sensor: 293 Voltage: 1.43 Address: 4 Data: 33
Sensor: 360 Voltage: 1.76 Address: 5 Data: 5B
Sensor: 440 Voltage: 2.15 Address: 6 Data: 5F
Sensor: 494 Voltage: 2.41 Address: 7 Data: 70
Sensor: 560 Voltage: 2.74 Address: 8 Data: 7F
Sensor: 606 Voltage: 2.96 Address: 9 Data: 7B
Sensor: 657 Voltage: 3.21 Address: 10 Data: 77
Sensor: 706 Voltage: 3.45 Address: 11 Data: 1F
Sensor: 783 Voltage: 3.83 Address: 12 Data: 4E
Sensor: 848 Voltage: 4.14 Address: 13 Data: 3D
Sensor: 933 Voltage: 4.56 Address: 14 Data: 4F
Sensor: 1001 Voltage: 4.89 Address: 15 Data: 47

Which is perfect!

vinceherman:
Use of code tags on the first post - Karma++

Thanks, back at ya!

Hi,
Check that the DIP Switches are making contact to the protoboard, check that you can see switched inputs to the DAC change as you change switch positions.

Hard wire in ALL zeros, then ALL 1’s and see if you get a change in output, particularly at the DAC output, not the LM358.

Quite a while ago here on the forum we had a problem with an input multiplexer that was erratic in operation, the code was suspect, but when I built the circuit the code performed perfectly. BUT I was using jumpers instead of DIP switches, I put in a DIP switch and found the legs were not long enough to make proper contact with the protoboard strips.

Tom… :slight_smile:

The DB0 to DB7 inputs on the TLC7524 are floating, I suspect. You have no pull-down resistors and I don't see anything in the data sheet to indicate the chip has internal pull-downs.

Why are you using the DAC in this way? An experiment for your curiosity? It would be much simpler to use a pcf8574 to read your switches. That would need two Arduino pins, A4 & A5, which are the i2c bus pins, but the i2c bus can communicate with many devices using only those two pins, and connect to many types of sensor or provide many more inputs inputs and/or outputs. The pcf8574 has internal pull-up resistors, so no external resistors needed to read your switches.

Thanks for those suggestions, I have now added pull down resistors to the DAC inputs.
I'm using the TLC7524 as that is what is in stock and seemed to do what I wanted. This will be an add on for a larger project that will log a timestamp to the EEPROM and use these switches to select the address to read the data.

I've hooked the switches to LEDs and they are lighting as expected.

From pin 1 on the DAC
All Zeros

Sensor: 100	Voltage: 0.49	Address: 1	Data: 30

All Ones

Sensor: 820	Voltage: 4.01	Address: 12	Data: 4E

Read using the switches from 0 to 9

Sensor: 37	Voltage: 0.18	Address: 0	Data: 7E
Sensor: 12	Voltage: 0.06	Address: 0	Data: 7E
Sensor: 24	Voltage: 0.12	Address: 0	Data: 7E
Sensor: 26	Voltage: 0.13	Address: 0	Data: 7E
Sensor: 47	Voltage: 0.23	Address: 0	Data: 7E
Sensor: 36	Voltage: 0.18	Address: 0	Data: 7E
Sensor: 48	Voltage: 0.23	Address: 0	Data: 7E
Sensor: 52	Voltage: 0.25	Address: 0	Data: 7E
Sensor: 93	Voltage: 0.45	Address: 1	Data: 30
Sensor: 61	Voltage: 0.30	Address: 0	Data: 7E

Added a 5k pull down resistor to pin 2

Sensor: 43	Voltage: 0.21	Address: 0	Data: 7E
Sensor: 170	Voltage: 0.83	Address: 2	Data: 6D
Sensor: 234	Voltage: 1.14	Address: 3	Data: 79
Sensor: 182	Voltage: 0.89	Address: 2	Data: 6D
Sensor: 283	Voltage: 1.38	Address: 4	Data: 33
Sensor: 227	Voltage: 1.11	Address: 3	Data: 79
Sensor: 253	Voltage: 1.24	Address: 3	Data: 79
Sensor: 202	Voltage: 0.99	Address: 3	Data: 79
Sensor: 334	Voltage: 1.63	Address: 5	Data: 5B
Sensor: 263	Voltage: 1.29	Address: 4	Data: 33

This seems to be behaving as expected, but not perfect

I don't really know what test you are performing and what results you were expecting from the above.

But going from digital to analog and back to digital again is not a solution that many design engineers would choose.

If you tell us what other buses you are using (i2c, spi), how many Arduino pins you can afford and what other chips you have in stock, perhaps we can suggest something simpler, more reliable and keeping in the digital domain.

My Arduino pins are full! I have an RFID reader using SPI, a PIR sensor, an LCD and a 74HC595 controlling LEDs!

The only pins I have left are A1, A2, D2 and D3 which are being used for this.

So the reason I am going from digital to analog back to digital again is I have to. I know the internal ADC will work - using a potentiometer, but I can't get this external DAC to work.

I've also tried using an R-2R Ladder like this attached to the switch rather than Arduino, which works well

I get

Value: 000 	 Voltage: 0.00 	 Address: 000 	 Data: 0x7E
Value: 098 	 Voltage: 0.47 	 Address: 001 	 Data: 0x30
Value: 179 	 Voltage: 0.87 	 Address: 002 	 Data: 0x6D
Value: 261 	 Voltage: 1.27 	 Address: 004 	 Data: 0x33
Value: 317 	 Voltage: 1.54 	 Address: 004 	 Data: 0x33
Value: 400 	 Voltage: 1.95 	 Address: 006 	 Data: 0x5F
Value: 461 	 Voltage: 2.25 	 Address: 007 	 Data: 0x70
Value: 532 	 Voltage: 2.60 	 Address: 008 	 Data: 0x7F
Value: 539 	 Voltage: 2.63 	 Address: 008 	 Data: 0x7F
Value: 618 	 Voltage: 3.02 	 Address: 009 	 Data: 0x7B

Although address 3 to 7, except 4, read too high?

As I change the switch I expect to see the voltage change and the Arduino use it's ADC to convert it to an integer I can use to access the EEPROM addresses. It would be nice to use a DAC IC for ease.

Hi,
I have looked at published circuits to do what you are doing and each circuit uses an Opamp that is + and - supplies.

This may be due to the fact that an Opamp tries to maintain VIRTUAL gnds at its inputs.

That is how an opamp circuit works, a single ended supply may not in this case be able to give the Opamp the output needed to apply to the DAC circuit to accomplish this biasing.

My 5cents worth.... Tom.. :slight_smile:

My Arduino pins are full! I have an RFID reader using SPI, a PIR sensor, an LCD and a 74HC595 controlling LEDs!

Then the solution is easy. Get a 74hc165 or other parallel-in serial-out shift register. Wire that up to the SPI bus along with the RFID.

Another suggestion to save more pins would be to connect the 74hc595 driving the leds to the SPI pins and another 74hc595 to the SPI pins to send data to the lcd.

LCD using 74hc595.

An I2C port expander (PaulRB, post#5) seemed an easy solution.
Leo..