0

I have the following digital potentiometer: DS1803-100 which, according to the datasheet, can be controlled using a two-wire serial interface. I have managed to get it working using Wire, however I can't seem to get it working using only digitalWrite (link to code). Can somebody tell me why? For reference, 0x50 is the address + r/!w bit, 0xA9 is the command (write to pot 0 in my case) and the next 0xA9 is the value to write. I know there's something wrong with the code, however I cannot figure out what. Thank you in advance!

EDIT: Here is the code

int PIN_SCK = 12;
int PIN_SDA = 11;

const int delayvalue = 10;

void setup(){
    digitalWrite(PIN_SCK, 1); // I can first declare the state
    digitalWrite(PIN_SDA, 1);
    pinMode(PIN_SCK, OUTPUT); // then turn them on
    pinMode(PIN_SDA, OUTPUT);

    delay(1000);

    digitalWrite(PIN_SDA, 0); // start bit

    shift_out(PIN_SDA, PIN_SCK, 0x50);
    shift_out(PIN_SDA, PIN_SCK, 0xA9);
    shift_out(PIN_SDA, PIN_SCK, 0xA9);

    digitalWrite(PIN_SDA, 1); // stop bit

}

void loop(){

}
// uint8_t is the same as 8 bits aka one byte
void shift_out(uint8_t datapin, uint8_t clockpin, uint8_t val){
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        digitalWrite(datapin, !!(val & (1 << (7 - i))));
        delay(1);
        digitalWrite(clockpin, 0);
        delay(delayvalue);
        digitalWrite(clockpin, 1);
        delay(delayvalue);
    }

    digitalWrite(datapin, 0); // to enable stop bit
    delay(100); // wait fro aknowledgement

}
  • What code would that be? Feel free to post the code here. – Nick Gammon Jul 16 '15 at 10:13
  • All right, edited the code in. – Calin Jul 16 '15 at 10:26
1

I2C is a lot more complex than just shifting bytes out.

See: I2C - Two-Wire Peripheral Interface - for Arduino

Your code does not seem to take any of that into account.

Why do you not want to use the Wire library? The hardware on the chip (what chip do you have?) supports it. Why ignore that and try to do it yourself?

  • I have no problem using the wire library, however I was wondering why that code didn't work in the first place, since in my mind it should have worked. And yeah, I already ended up using Wire on my Arduino Pro Mini. Thanks for the info! :) – Calin Jul 16 '15 at 10:34
  • I am really curious on what I did wrong in my code. Did I not take into account the acknowledge bit, I just waited 100 ms for the slave to send this bit and than carried on, or what did I do? – Calin Jul 16 '15 at 10:42
  • 1
    Well I managed to make it work, I'll post the answer a bit later. – Calin Jul 16 '15 at 10:49
1

Well, short answer: It was the acknowledge bit, I forgot to send a clock pulse in order to receive it (duh! my device generates the clock for the attached potentiometer, I was waiting for the device to "send" me a bit, I needed to "request" the bit on a rising edge of the clock).

Long answer: the code looks like this now:

int PIN_SCK = 12;
int PIN_SDA = 11;

const int delayvalue = 10;

void setup(){
    digitalWrite(PIN_SCK, 1); // I can first declare the state
    digitalWrite(PIN_SDA, 1);
    pinMode(PIN_SCK, OUTPUT); // then turn them on
    pinMode(PIN_SDA, OUTPUT);

    delay(1000);

    digitalWrite(PIN_SDA, 0); // start bit
    delay(10);
    digitalWrite(PIN_SCK, 0);
    delay(10);

    shift_out(PIN_SDA, PIN_SCK, 0x50);
    shift_out(PIN_SDA, PIN_SCK, 0xA9);
    shift_out(PIN_SDA, PIN_SCK, 0xA9);

    digitalWrite(PIN_SDA, 1); // stop bit

}

void loop(){

}
// uint8_t is the same as 8 bits aka one byte
void shift_out(uint8_t datapin, uint8_t clockpin, uint8_t val){
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        digitalWrite(datapin, !!(val & (1 << (7 - i))));
        delay(1);
        digitalWrite(clockpin, 1);
        delay(delayvalue);
        digitalWrite(clockpin, 0);
        delay(delayvalue);
    }

    digitalWrite(datapin, 0); // to enable stop bit
    delay(10);

    // Here I handle the AKNOWLEDGE signal which happens after
    // each byte sent. Be it address, command or value
    digitalWrite(clockpin, 1);
    delay(10);
    digitalWrite(clockpin, 0);
    delay(10);

}

So basically I followed and reproduced the signals in this timing diagram faithfully with one small exception: I did not generate a rising edge when I expected the acknowledge bit (basically the diagram but with SCK being 0 right below the acknowledge bits).

Hope this helps somebody!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.