I have no UARTs left on the ATmega and need to deliver 1 Byte of information from the pi using 1 analog input. I2C is no option either.

I planned using the digital output to request an analog signal from the Pi, but it does not seem to have a DAC.

Is it possible to properly translate/read a PWM signal with the atmegas ADC? Analyzing the PWM the 'usual' way would probably be too slow as I don't trust the pi to keep up with a high PWM frequency.


I should add that this is a rather large robotics project involving communication between 8 MCUs in it's current state and needs to be extended by a computer vision module(=pi), which is not compatible with the existing custom bus

Edit: This also is a real time system which has approximately ~1-2ms left in it's main loop(10ms period). The required data has to be present in time as it alters the robot's behaviour for this loop.

  • 1
    You can use SoftwareSerial to connect to a pi uart; otherwise upi can use a software serial communication using whatever protocol you want. I highly suggest you to avoid using analog signals, since these signals can't transfer reliably one byte... And PWM too is a bit too imprecise. Just remember to voltage translate the 3.3V to 5V (even if you actually could use the 3.3V output to communicate to the arduino, since it should accept voltages as low as 3V...
    – frarugi87
    Apr 21 '16 at 13:30
  • I'm sorry but your question isn't very clear. Do you know about logic level shifters? You could use that to convert 3.3. to 5v. Also you might want to look into adding additional ports to both devices, but you are going to need to use I2C or SPI to do that. Apr 21 '16 at 14:25
  • Yes I do know about level converters, the problem is about generating an analog signal on the pi or using a different method to communicate with given pins. I should add that this is a rather large robotics project involving communication between 8 MCUs in it's current state and needs to be extended by a computer vision module(=pi), which is not compatible with the existing custom bus
    – mystery
    Apr 21 '16 at 14:47
  • While there are various ways to do digital signalling on your remaining pin(s), depending on how locked in to your current setup you are, an approach that might make sense would be to see if you could convert an existing point-to-point serial link to a multi-party serial bus. Basically, read up on RS485 and see if you can do something conceptually similar, without the differential transceivers, but rather using your existing low or high voltage connections simply by software-enabling the output driver of only transmitter at a time and writing some rules for deciding who gets to talk. Apr 21 '16 at 15:24
  • The exisintg i2c interface is used to debug and locked during normal operation to not interfere with already multiply used connections. The second UART is exclusive to robot2robot bluetooth communication. I already thought about hooking up another bt module to that, which was too slow as well
    – mystery
    Apr 21 '16 at 15:44

You can start researching about one wire protocol here to see if can implement it given your situation.

  • I have read about that but a minimum of 1,5ms to transfer 1byte is far too slow (reset + presence + 2x(8bit at 60us))
    – mystery
    Apr 21 '16 at 14:53
  • You really should include your speed requirement in your problem statement. Apr 21 '16 at 15:22
  • In your edit to the question, you are mixing up transmission time with the processor's attention time required to receive the data. They are by no means the same thing, unless you sit in a blocking loop watching the signal change, which would be a rather unwise implementation. 1.5 ms for data transmission sounds like it would actually fit your 10 ms loop time rather nicely. Apr 21 '16 at 15:51
  • It is difficult to accurately ask a question dependant on so many factors. Timers that could be used to modulate the signal are used up. The PD7 pin has a signal change interrupt, whose use could interrupt the main bus, crashing the system.
    – mystery
    Apr 21 '16 at 15:55

The solution was to hook up PA0 to GPIO18 of the pi with an RC-circuit inbetween. GPIO18 features a hardware PWM output, which has to be set to mode 0 (non balanced, mark-space), because the balanced mode could not handle odd pwmRanges for some reason(it is badly documented).

This setup enables the atmega to read the pi's pulsed 0-3,3V output as analog input.

Pin initialization on Pi(using a python library):

import wiringpi2 as wiringpi

wiringpi.pinMode(18, 2)
wiringpi.pwmSetMode(0)    #<- important part

Currently writing the Atmega side

    uint8_t     i = 0;
    uint32_t val  = 0;
    while(i<8)    //average 8 measures
        ADMUX   = 0 & 0x1f;    //select channel 0 (PA0)
        ADMUX |= (1<<5);       //set ADLAR bit ADCH > ADCL
        ADCSRA  = ADCSRA | (1 << ADSC) | (1 << ADIF);
        while (ADCSRA & (1<<ADSC));
        val = val + (ADCH);
    return ((val)>>3);

Note that this reads a 10bit value on the channel and discards the least significant 2bit stored in ADCL as ADLAR is set to speed everything up.

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.