I am attempting to create a program for the atmega328P which will enable the aux input of a Toyota Corolla stereo. In order to do this, I'm bitbanging AVC LAN. Nearly all of my research comes from this site: https://github.com/halleysfifthinc/Toyota-AVC-LAN

In this example, Frigon has wired his Atmega8 in a peculiar way. Instead of connecting the + terminal directly to a single pin of his Atmega8, he's connected it to a pulldown resistor, resisted it to the - terminal (presumably for bus termination) and a digital pin as well as an analog pin. The - terminal has been given similar strange treatment.

In his function ReadBits(), he waits for a physical 1, then sets a timer and waits for a physical 0 to measure the length of the pulse. But when he does this, he uses the equivalent of

while ( bit_is_clear( ACSR, ACO ) );

That's completely Greek to me. Does this have something to do with something called in Internal Analog Comparator?

I attempted to create something similar using

while( digitalRead( 2 ) );

but I'm reading static as well as honest-to-goodness pulses. I assume that, anyways, because I'm getting pulses of length 2-7 ticks when many are closer to 20-40 ticks (measured using TCNT0 with no custom prescaler).

So... what exactly is he doing with ACSR and ACO? Why is his + and - terminals connected to more than one pin? Why are his diodes there?


Following Edgar's advice, I've reworked my schematic and code to closely match Frigon's work. Below is my code:

#include <avr/wdt.h>

#define fwVer       "v0.1"
#define fwDt        __DATE__
#define DATAPIN     2

#define DATAIN_PIN              ACSR
#define DATAIN                  ACO

#define INPUT_IS_SET            ( bit_is_set( DATAIN_PIN, DATAIN ) )
#define INPUT_IS_CLEAR          ( bit_is_clear( DATAIN_PIN, DATAIN ) )
//===================================================================================WHAT DOES THIS MEAN

byte data[255];

void setup() {


  digitalWrite(3,HIGH); //"leave the pins tri-stated" according to Frigon

  //two second watchdog
  wdt_enable( WDTO_2S );

  Serial.println("Firmware "+String(fwVer)+", compiled on "+fwDt);

void LedOff() {
  digitalWrite(LED_BUILTIN, LOW);
void LedOn() {
  digitalWrite(LED_BUILTIN, HIGH);

void loop() { 
  if (INPUT_IS_CLEAR) LedOff();
  else LedOn();

Schematic: https://imgur.com/a/PIkad (mistake on the schematic - I connected 5v to vcc and ground to ground) If it matters, I'm powering the head unit and the arduino from the 12v and 5v rails of an ATX power supply. They both take the same ground.

My code should theoretically only turn on my led whenever the head unit broadcasts bits, but it's just sort of erratically blipping on and off or fading gently at random. I've triple checked my wiring (breadboard if that matters). Why is this happening? Is there something about bit_is_clear(ACSR,ACO) that I don't understand?

  • 3
    Oh dear, the Wayback Machine. Sympathetic to your problem as I am, your question already refers to a link-dead site which is why you are using the Wayback Machine. Who knows how long that will last? Please post (edit your question) to include the schematics you are talking about, and the code. As it is you are saying "some link-dead site has a schematic and some code, how does it work?". Even if we answer, how useful will the answer be if the Wayback Machine goes down? – Nick Gammon Jan 26 '18 at 7:35
  • Done. Didn't think about the wayback machine dying out. – Bo Thompson Jan 27 '18 at 4:25
  • No, you haven't included the schematic nor the code in the question. If you dump it to your disk, then edit the question and include it, then the question will stand whether or not the Wayback Machine goes down, or any other site (excepting this one, of course, but then the question won't exist either). – Nick Gammon Jan 27 '18 at 6:06
  • The code is large and separated into multiple files. I'm not trying to make this post impossibly large. – Bo Thompson Jan 27 '18 at 6:58
  • About your recent edit: 1. “leave the pins tri-stated” means they should be set as inputs. 2. The analog comparator compares the potentials of the pins AIN0 (digital 6 on the Uno, not A0) and AIN1 (digital 7). Frigon has these pins connected to the AVC bus, whereas on your schematic they are left floating, so they only pick up noise. – Edgar Bonet Jan 27 '18 at 15:12

Does [bit_is_clear(ACSR, ACO)] have something to do with something called in Internal Analog Comparator?

Exactly. ACSR is the “Analog Comparator Control and Status Register”. ACO, the “Analog Comparator Output” is one bit of this register. The ATmega328P has the same comparator, with the same register and bit names as the ATmega8. C.f. the datasheet. You should be able to use this part of the code as is.

Frigon has wired his Atmega8 in a peculiar way. [...]

It seems to me that is termination is intended to ensure that, in the “floating level”, the line AVC− is at a potential higher than AVC+. In the “driving level”, the opposite should be true, with a difference of at least 120 mV.

I attempted to create something similar using while(digitalRead(2)) ;

It's not surprising that it doesn't work. This is a differential bus. The information is carried by the potential difference between AVC+ and AVC−, not by the potential of a single wire. A difference higher than 120 mV should be interpreted and a high state. Your digital input instead reads a single wire and compares its potential to ground. The thresholds to switch between LOW and HIGH are typically around 2.1 and 2.6 V, with some hysteresis. This is far from being compatible with the signaling of the bus.

I recommend you follow Frigon's steps and use the analog comparator just as he does. The comparator will tell you which of AVC+ or AVC− has a higher potential, and it will not be bothered by the low level of the differential signaling.

  • Thank you. I'll revise my approach and give that a shot. I deviated from the original work because I didn't understand it (and I really hate doing something without understanding it). To that end, is there anywhere I can read about the ACSR and ACO registers (and the comparator) in greater detail? Besides the 328P datasheet of course... That's a little too dense for me to work with... – Bo Thompson Jan 27 '18 at 4:16
  • If you narrow down your view of the datasheet to the page that mentions that register it isn't too bad. However I do find the explanation there rather obscure: "Bit 5 – ACO: Analog Comparator Output - The output of the Analog Comparator is synchronized and then directly connected to ACO. The synchronization introduces a delay of 1 - 2 clock cycles." – Nick Gammon Jan 27 '18 at 4:40
  • Edited original post with a followup on my issue after taking Edgar's advice. – Bo Thompson Jan 27 '18 at 6:52

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.