1

I have a device programmable via an 8 bit digital parallel bus. I would like an Arduino to translate from a parallel 4 bit output of an existing device to 8 bit by intentionally reducing the resuloution. Unfortunately, I can't just use the most significant bits as I want to change the step size. The idea is to use an Arduino that ready the 4 digital input bits and then computs the necessary 8 bit output which it output to the 8 bit bus. However, this need to be as fast as 1 us. Is this possible with an Arduino? If so which board would you recommend? I guess I can't use the digitalWrite command as this will be too slow though. Any suggestions?

1 Answer 1

3

You can do this with an Uno, provided it has nothing else to do. I would program it low-level, skipping the Arduino core since, as you said, digitalWrite() would be too slow for this application.

Here is my proposed approach: read the 4-bit input from one port, use a look-up table to translate it to an 8-bit output, and write that output to another port. I would use PORTD (pins 0–7) for the output, as it is the only full 8-bit port on the Uno, then the first bits of PORTB (pins 8–11) for the input:

/* Translation look-up table (dummy example). */
const uint8_t lut[16] = {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
};

int main() {
    DDRB = 0x00;  // set port B as input
    DDRD = 0xff;  // set port D as output
    for (;;) {
        uint8_t input = PINB & 0x0f;  // grab the lowest 4 bits
        PORTD = lut[input];  // set the output
    }
}

I compiled and disassembled this code to count the CPU cycles: the main loop takes 10 cycles per iteration. Given that the Uno is clocked at 16 MHz, this is one update of the output every 0.625 µs.

Edit: This is a straightforward approach. At the cost of some extra complexity, it could be optimized down to 7 cycles per iteration (0.438 µs), or even 6 cycles (0.375 µs) in assembly.

3
  • nice answer ... upvote for the effort
    – jsotola
    Mar 4, 2023 at 22:01
  • Thank you very much for the detailed answer and testing. One further question out of curiosity: Does this mean that if I go for an Arduino Zero, it will be (48 MHz / 16 MHz) 3x faster and for a Due (84 MHz / 16 MHz) 5x faster?
    – P. Egli
    Mar 5, 2023 at 15:14
  • 2
    @P.Egli: Re: “if I go for an Arduino Zero [...]”: No. These Arduinos use an ARM architecture, which is completely different from the AVR architecture of the Uno. The code above may not be trivially ported to them. AVR is simple enough that you can count the CPU cycles simply by looking at an assembly listing. I doubt the ARM cores of the Zero and the Due are at this level of simplicity. Mar 5, 2023 at 16:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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