Вариантов много: UART, SPI, i2c...
Если питание AVR 3 вольта, то можно кидать тем же UART - не надо будет даже уровни согласовывать. Это самое простое и очевидное решение.
Я в данный момент решал буквально ту же задачу: несколько значений АЦП в диапазоне 0-5В и цифровых TTL сигналов считывает AVR с питанием 5 вольт. А ESP8266, питаемый от 3 вольт, забирает эти данные с AVR по i2c. Удобство тут в том, что если мастером является ESP8266, а AVR - слэйвом, то подтяжку шины к 3 вольтам обеспечивает мастер. 3-х вольт хватает AVR для чтения логической 1, а подтянуть шину на 0 он может в любом случае. Соответственно, не надо согласовывать уровни.
Для эксперимента вполне подойдет среда Arduino с библиотекой Wire с ее примерами мастера-слэйва по 10 строчек. Первый прототип на AVR отдавал данные в ESP с прошивкой Макса, данные с ESP забирались через GET. Второй вариант уже работает с собственной прошивкой ESP на базе того же Arduino IDE для ESP8266 и той же Wire. Примеры обмена - стандартные для Wire. Главное - не забывать, что ESP8266 должен быть мастером и тянуть шину именно к 3 вольтам, а не AVR - к 5-ти. Поскольку в задаче надо передавать данные от ESP, то мастер для него выглядит вполне логичным. Для обратной передачи вполне можно задействовать еще одну линию с эмуляцией прерываний от AVR в ESP, но опять же не забывая включать pullup со стороны ESP к 3-м вольтам.
PS. Неплохая статья по i2c тут:
dsscircuits.com/articles/arduino-i2c-slave-guide
Такое устройство AVR прекрасно обнаруживается i2c сканнером прошивки Максима.