Introduction: Interfacing Electronic Circuits to Arduinos

Interfacing Electronic Circuits to Arduino

In this instructable I use an example of interfacing an Arduino to an ARINC 429 transceiver in order to demonstrate the general process of interfacing an Arduino to electronic circuits so you can use these techniques on your own designs.

An ARINC 429 bus is the most common data bus used on aircraft for computer to computer communications. The ARINC 429 bus operates at one of two speeds, called low speed and high speed, which are 12.5 kbps and 100 kbps respectively. The bus operates over two wires (and a ground). Each piece of data is sent in a 32 bit word.  Generally the first 8 bits, called the label, are used to identify the data contained within the ARINC word. Bits 9 and 10 often define the Source/Destination Indicator, but sometimes they contain data or are an extension of the label.  Data is contained in bits 11-29 and can contain binary twos compliment, binary coded decimal, and/or a set of discrete bits.  Bits 30 and 31 contain the Sign Status Matrix, and its values can indicate Normal operation, Failure Warn, No Computed Data, and Functional Test.  Finally bit 32 is the Parity bit and is set so that the 32 bit word has ODD parity.

Avionics equipment manufacturers, aircraft manufacturers, and avionics equipment service centers have specialized test equipment to read these ARINC 429 data buses. I've wanted to own and use my own test equipment so I developed the Arinc429eReader. While this could be an instructable on its own merit, I suppose the audience interested in such a device would be small. I will therefore present a more generally applicable instructable on the process of interfacing an Arduino to other electronic circuits.


Step 1: Deciding to Do the Project

Step 1a: Solved Already?
First make sure someone hasn't already solved your problem. Go on Google and search.

In my example I found several companies that make ARINC 429 to USB converters but they are rather expensive, $1500 US dollars or more. There had to be a better solution. I found an ARINC 429 transceiver in a 40 pin DIP at a reasonable price. I wrote to the company and they sent me some free samples. Although the transceivers contain both a transmitter and two receivers, I only needed the receivers (at least for now!) so this chip looked good.


Step 1b: Can I do it?
The next step is to determine if you have the skills (and the determination) to see the project through. To determine this I obtained the ARINC 429 transceiver chips' specification and reviewed it.

In my example I saw the chip requires only 5v power and no 'exotic' analog signals.
It also requires a 1 MHz clock to time its operations. I thought that I could maybe use the Arduino's clock or use a 1 MHz clock chip.
It also requires 11 input/output signals in addition to a 16 pin data bus. This is too many pins for the Arduino UNO but is easy for the Arduino Mega.

See Figure 1 attached.

What about software skills? Well, I've done quite a bit of coding for other processors before and I can look through how other library code is written as examples of how others solved similar problems. The open source nature of Arduino is perfect for my needs here.


Step 1c: Should I do it?
The next step is to determine if the project should be done. It will cost money and time. I usually error on the side of trying new things for the experience if nothing else. Asking others for their opinion is often NOT recommended. Remember that most of the people we remember a great people all had contemporaries telling them they were wrong.

I assume that you are ready, willing and able to proceed with your project! Lets get to it!

Step 2: Read the Chip Data Sheet

Step 2: Read the Chip Data Sheet
Get the chip data sheet for your chip and read all of it.

In my case the chip I found is the DEI1016 and its specification can be found here:
www.deiaz.com/data-sheets/DS-MW-01016-01-E.pdf

See the PDF file attached.

Let’s take a look at the timing diagrams. They can be intimidating at first but I am sure you can learn how to read them if you don't know already.

Here is the timing diagram for the Reset and Initialization Sequence. I've added a few annotations to help you learn how to read the timing diagrams:

See timing diagram with annotations attached.


When the line is high, that means it is at 5 volts, and when low, it is ground, just like the Arduino's digitalWrite HIGH and LOW.

Now let’s add in the values for all those time measurements in the timing diagram:

See timing diagram with times attached.

The time between the MR pin going HIGH and the LDCW pin going low isn't specified, so let’s assume it isn't critical.

Now let’s translate this into words:
Set MR LOW and hold it there for at least 200 ns.
Set MR HIGH.
Set LDCW LOW.
Set the data bus to its correct values and hold them there for at least 110 ns.
Set LDCW HIGH.

Let’s do the same thing for the Read operation:

See Figure 8 attached.

It is very interesting how they chose to indicate the relative timings... OE1 can be LOW 0 ns after DR1 goes LOW but 20 ns after SEL goes LOW.

Also note that there appears to be no timing provided for the Word 2 to become valid. I think this is really trying to say that Tdoedr being 200 ns is how long it takes for Word 2 to be valid and NOT when OE1 must be raised to HIGH. I'll try this logic out and see if my assumptions are correct.

Let’s translate this into words:

The DEI1016 chip sets DR1 LOW to indicate data has been received on Receiver 1.
Set SEL to LOW and wait for 20 ns.
Set OE1 to LOW.
Wait 200 ns for the chip to set the data pins. Read the data pins.
Set OE1 to HIGH and wait for 20 ns.
Set SEL to HIGH and wait for 30 ns.
Set OE1 to LOW.
Wait 200 ns for the chip to set the data pins. Read the data pins.
Set OE1 to HIGH.

Now that we have some understanding of how the pins need to be set to initialize the chip and to receive data, let’s turn these routines into Code.

 

Step 3: Converting the Waveforms Into Code

Step 3: Converting Timing Diagrams into Code
The Arduino development environment shields the user from a lot of the messy code details. This is good when you are just starting out and want to blink an LED. When we want to interface with other electronic circuits, however, we need to interface more directly with the microprocessor.

First let’s discuss how to efficiently read in the 16 pins in the data bus. Since I’m using the Arduino Mega because it has a lot of IO pins, I can use Port A and Port C to be my 16 bit data bus. Port A and Port C are pins 22 – 37 on the Arduino Mega. The data bus is bidirectional, meaning that sometimes the pins are used as outputs and other times as inputs so we need to set the pin modes quickly as well as reading/writing to the pins themselves. The SLOW way to use these pins would be as follows:
pinMode(22,INPUT);
pinMode(23,INPUT);
pinMode(24,INPUT);

pinMode(37,INPUT);
bit1 = digitalRead(22);
bit2 = digitalRead(23);
bit3 = digitalRead(24);

Bit16 = digitalRead(37);

At this rate we’d lose data as we’d be reading the data slower than the data is being received. We need to speed this up by directly interfacing with the Arduino microprocessor.

The Arduino microprocessor is like the engine inside the Porsche. Most times a driver of a car really only needs to understand how to make the car stop and go and doesn’t need to fully understand the internal workings of the car’s engine. A race car driver, however, needs to understand the limits and capabilities of the engine to push it to win the race. Likewise we need to understand the details of the ATMEL AVR which is the Arduino’s engine to interface it with other electronic circuits.

To understand the Arduino microcontroller we read the AVR datasheet. The Arduino Mega uses the ATMEGA1280 which can be found here: www.atmel.com/dyn/resources/prod_documents/doc2549.pdf

Yes, this is 444 pages of detailed information which can be daunting at first look. You will find on pages 100 and 101 that you can set all of the pins on port A and port C with a single write to the PORTA address and PORTC address. We can also read from these ports but we do this not by reading from the PORTA and PORTC addresses but from the PINA and PINC addresses. Likewise we can set the pin modes for all of the pins in the port at once by writing to DDRA and DDRC addresses, a ‘1’ sets the pin to output and ‘0’ to input.

Now we can set the pins to inputs and read them much more quickly using these commands:
DDRA = 0x00;
DDRC = 0x00;
Byte1 = PINA;
Byte2 = PINC;

And to write to the port pins:
DDRA = 0xFF;
DDRC = 0xFF;
PORTA = Byte1;
PORTC = Byte2;

Now that we can efficiently read and write the bus pins, we need to look at how to efficiently read and write the other normal pins. In my example project I used Arduino pins 2 – 12 to control the 11 non-bus control signals going between the DEI1016 and the Arduino. If we want to write efficient code for these pins also (and we do) we need to avoid the digitalWrite and digitalRead routines which are slow because they do things like checking to see that the pins are set to the correct modes, etc. To write very quickly again we can write directly to the hardware pins avoiding the Arduino overhead. The include file avrio.h includes the avrio_WritePin and avrio_ReadPin functions that perform fast reads and writes. I took a clue from the glcd library and defined my own fastWrite routine which is #defined to avrio_WritePin to make the code more readable. If you wish you can review how the glcd library solves their fast writes, although you will have to traverse the few layers of indirection.

One last bit of difficulty we have in translating the timing diagrams into code – just how do we delay for the specified number of nanoseconds? How long is a nanosecond? Question: How long does it take for you to slip on a peel and fall? Answer: A bananosecond. Sorry for the bad pun. The Arduino has a delay(milliseconds) and delayMicroseconds() but does not have a delayNanoseconds() function. When working at a high level language such as C, we have less knowledge of how much time a microcontroller will take to execute our commands. This gets really tricky as the processors become more complex and have instruction pipelines with L1 and L2 memory caches, etc. In our Arduino case it is not too difficult as we can use the ability of the C language to include inline assembly code. By using assembly we can count the instructions and know how many clock cycles (typically 1/16000000 of a second) an operation takes. By using ‘inline’ assembly, our instructions do not get implemented as subroutines and therefore do not take longer to process with the jumping to the subroutine and pushing and popping data off the stack. The disadvantage of inline assembly is that the compiled object code gets longer, but this is acceptable since we aren’t doing a lot of these nanosecond delays.

Again I steal the solution inside the glcd library. There they include the delay.h file which contains the _delay_cycles function. I then define this function as the more readable DelayNanoseconds as follows:

// Hans Heinrichs delay cycle routine:
#define DelayNanoseconds(__ns) _delay_cycles( (double)(F_CPU)*((double)__ns)/1.0e9 + 0.5 )

You will notice that there is double floating point math going on in here which is usually avoided because it is very time consuming and we want very small delays. This routine uses the floating point math routines to automatically adjust to the microcontroller’s clock frequency to insert the right amount of assembly code inline with the C code and the best part is that the floating point calculations are performed when you compile and are not executed by the Arduino at runtime! This method can result in a single-instruction ‘NOP’ being inserted as a busy delay.

Step 4: Generating a 1 MHz Clock Signal

1 MHz Clock Signal
According to the data sheet I need to supply the DEI1016 chip with a 1 MHz clock signal.

The Arduino uses 16 MHz oscillator, one would think one might be able to use a divide-by-16 counter to generate a 1 MHz clock signal form the Arduino's 16 MHz clock. When I tried to do this the circuit fouled the Arduino's oscillator. Maybe I could have used very short wires into a buffer chip but in the end it was simpler to just add a 1 MHz clock chip.

Here is the information for Jameco's 1 MHz Clock:

Step 5: Transmission Troubles


Transmission Troubles
In order to test my receivers, I used the loopback capability of the DEI1016 chip. In this mode anything transmitted is wrapped back to both receivers, receiver 1 receives the same data transmitted while receiver 2 receives the negative of the transmitted data.

Lets take another look at the timing diagram for loading the transmitter:

See Figure 9:

You will notice that the data sheet authors did not show much detail in the timing of Word 2. Here we have to assume that the timings of word 2 in relation to LD2 are just like Word 1 and LD1.

So, once again to turn this into words:

Set LD1 to LOW and wait for 20 ns.
Set the data bus pins to the data you want to transmit and wait for 110 ns.
Set LD1 to HIGH.
Set LD2 to LOW and wait for 20 ns.
Set the data bus pins to the data you want to transmit and wait for 110 ns.
Set LD2 to HIGH.

I enabled the loopback mode by initiating a reset and initialization sequence described above and this time enabling the loopback mode. I then within a loop transmitted a test word and received the results from both receivers. This worked correctly only the first time but would not send multiple test words. So, what was I doing wrong? A quick review of the DEI 1016 data sheet showed me what I forgot:

See Transmission data sheet excert.

So, there it is, I need to enable the transmitter by setting ENTX to HIGH when I want to transmit and to hold it LOW while I'm loading the data into the transmitter. The words of the data sheet described this but the timing diagram did not. OK, so I proved again that reading the whole data sheet is a good idea ;-)


Step 6: Finishing the Project


To finish my project I transferred the design from the working breadboard to an Arduino Mega perfboard shield. I also added a few LEDs connected to output pins via 220 ohm resistors. These LEDs will indicate if the receivers are getting any data, the receiver's speed setting, and if the loopback mode is initiated. I created a simple protocol over the serial io port #1 (pins 1 and 2).
The Arduino sets the receiver's speed to Hi or Low speed if “R” or “r” is received, respectively.
The Arduino sets the transmitter's speed to Hi or Low speed if “T” or “t” is received, respectively.
The Arduino sets the loopback mode on or off if “L” or “l” is received, respectively.

I hope that after reading this instructable about my experiences you may want to try to interface your Arduino to new and interesting electronic circuits and share them here!

Note:  You can download a version of AVRIO that can be used with this code from:
* http://www.opensource.billsworld.billandterrie.com/avr/avrio

Note: Be sure you understand the license for and meet the conditions of including AVRIO.h in your design!

Comments

author
ncormia (author)2011-11-27

Thanks for a great start to working with ARINC 429! You saved me weeks!

I discovered that the PINC bit order is the reverse of the PINA bit order on the Mega board. I'm working with the Arduino Mega 2560 instead of the 1280 but, based on a look at the eagle files for the arduinos, I think the same problem is true for both. This impacts the bit ordering for b4 and b2 in the example above. Before trying to parse the ARINC data you will probably want to invert the wires for D15..D8.

This may impact how the high-byte of the control word is handled but so far I've had no problems at high-speed. I have yet to get lo-speed ARINC or Tx working but will post any useful fixes when I do. Oh, I plan to make an ARINC 429 shield for the mega boards if anyone is interested.

author
maewert (author)ncormia2011-11-27

I'm pleased to have helped you. By all means post your shield when you're finishd! My friend and I have been thinking of interfacing this with a 3.2 inch LCD screen for a handheld reading device. We'll update this if we progress as well.

Best Wishes

author
paulware (author)2011-04-28

Awesome...
You have broken this down very clearly and I am anxious to try and build one soon. You definately showed me things I wasn't aware of (writing more than one digital pin at a time, and datasheet basics).
thanks

author
DeviganR (author)2016-09-16

Will this work for Arinc 568.

author
maewert (author)DeviganR2016-09-20

Sorry to have missed your question until now. I have no direct knowledge of ARINC 568 (It isn't even available at the ARINC store. Is it very old?). Many of the ARINC standards describe the protocols that are sent over ARINC 429 data bus. If so, then yes. If Arinc 568 is a different data bus then no, it wouldn't.

Best Wishes.

author
DeviganR (author)maewert2016-09-21

thanks

author
shoepuke (author)2016-02-15

Could something like this be used to convert analog NAV output from a radio into ARINC-429 output?

author
maewert (author)shoepuke2016-03-05

Hi Shoepuke,

If you needed to transmit ARINC 429 then you would have to add an ARINC 429 line driver to your circuit. The Chip made by the same guys as the transceiver requires + and - 15 volt power supply but doesn't look too difficult.

Best Wishes

author
duane.fowler.71 (author)2015-02-02

I am very interested in making this reader. I need to read Throttle Lever Angles to set encoder and switches on Citation Excel corporate airframes. Excellent Instructable! What would you be able to send/publish related to the wiring/shield?

Thanks,

Duane

author
maewert (author)duane.fowler.712015-02-02

I did not create a schematic, however, the following figure shows what pins need to be connected to the Arduino MEGA:

a429.png
author
ValikhanT (author)maewert2016-01-06

Idk if this thread is still alive, but i need a help.

According to the last figure where it's show how DEI pins are connected to Arduino mega pins, you connected 34, 33 DEI's pins to 11 and 10 pins of Arduino while they're not digital IOs and you can't control them in order to send data. So, is it right and i'm horribly confused?

Secondly, you created a simple protocol over the serial io port #1 (pins 1 and 2) while at the same time you use pin 2 for /OE2 input(DEI's pin 10). Is something wrong with it?

Best Wishes,

Valikhan))

author
maewert (author)ValikhanT2016-01-06

The pin identification is confusing, I admit. In the arduino IDE, it defined Digital Pin numbers (like the ones used in calls to pinmode()). These pion numbers map to the actual processor chip pin numbers. The attached image which I stole from the internet shows the mapping. In step 6, the pin numbers 2-13 refer to the digital pin numbers (used with pinMode, digitalRead, digitalWrite). The higher pin numbers refer to the actual 1280 chip pin numbers. sorry I mixed the meaning on the same figure.

Send me a mesage if this still isnt clear.

Best Wishes.

Mark

arduino-mega-1280-pin-mapping-770.jpg
author
ValikhanT (author)maewert2016-01-07

Thanks for quick reply, now it's easier to understand but i still didn't understand one thing.

What actual processor chip pin numbers do you use for serial io port #1?

author
duane.fowler.71 (author)maewert2015-02-03

Thanks for the clarification. Now to find a chip....
Best, Duane

author
Avia767 (author)duane.fowler.712015-02-14

There is a Holtic A429 chip on ebay ref HI-8586, it features Rx only at reasonable price $19.

I wonder if we can use it, the DEI1016 is hard to find.

author
maewert (author)Avia7672015-02-16

The Holt chip on Ebay you referred (HI-8586) to is a line driver. Holt is well known for Arinc 429 chips and does offer some very interesting chips. The HI-3598 looks very interesting as it uses an SPI interface instead of parallel, which may open up using Arduinos with less pins. I'll have to investigate using these if they are easily obtained.

Thanks!

author
Avia767 (author)maewert2015-03-04

Hi again,

Although the HI-3598 is designed for 8 A429 receive buses, I would go for the 3585 which is available online and features 1 Rx and 1 Tx ??

Any plan for interfacing the chip with an Arduino MEGA 2560 ?

author
maewert (author)Avia7672015-04-01

I have no plans on interfacing the Holt chips to the Arduinos. I'm sure it could be done, however, I am reluctant to work with surface mount parts... but it would be nice!

Best Wishes

author
reuted (author)2015-10-23

This is a very interesting idea. I am currently using RTX systems devices to read Arinc 429 data. If anybody has completed reading ARINC 429 data with a holt chip?

author
FabienS (author)2014-12-31

It seems this chip always put the parity bit as zero in read mode.

In your example, in loopback mode, if you send 0x78563412, you receive exactly the same thing.

But if you send 0x78564312, you receive 0x78564212: parity bit is set to zero but it was send set as 1.

Weird, isn't it?

author
FabienS (author)FabienS2014-12-31

My bad:

- transmitter corrects the parity to odd

- receiver has "0" for parity bit (logic "0" indicates the received word has an odd number of 1's)

author
maewert (author)FabienS2014-12-31

You are correct that the transmitter corrects the parity. I believe there is a mode to send even parity in the odd event you wish to.

author
FabienS (author)2014-09-18

Thanks for this very well explained instructable! I did not expect to be this simple to follow :)

By the way, what are the following instructions used for?

r1_activity_off_time = millis() + 50; // add 50 millis

[…]

if (r1_activity) if (r1_activity_off_time < millis())

At 100 kbps, it takes less than 1 ms to send a 32 bits arinc data. So I do not really understand this 'activity_off_time'.

author
maewert (author)FabienS2014-09-20

FabienS,

Thanks for the kind words.

The activity code merely blinks the LED on or off at 50ms intervals in order to show the LED flickering the receive activity. If I had changed the state of the LED on reception the LED would just appear dim since as you pointed out the received words can come in very fast at high speed rates. The code is rather confusing I admit.

Best Wishes

author
goldenshuttle (author)2014-05-18

Great tutorial..many thanks

author
chizz (author)2013-11-11

Thanks, I'll try again!

author
chizz (author)2013-11-10

Sorry to drive you back to this, but I'm practically there, except for the following.
Pin 8 (SEL) on the DE1016 goes to pin 4 on the chip. Now afaik that pin (PE2/AIN0/XCK0) is not led out to an arduino mega board pin.

what am i missing?

with regards, and thanks for past favours

Chizz

author
maewert (author)chizz2013-11-10

Chizz, When I say PIN 4 of the Arduino MEGA, I' referring to the Arduino Mega board and not Pin 4 of the arduino mega chip (ATmega1280). See here: http://arduino.cc/en/Main/ArduinoBoardMega
The arduino IDE lets you access pins 0-13 as digital pins, these are the one's I'm speaking of. Take a look at my include files and you will see:
/* Inputs from the ARINC UART */
int a429DR1_pin = 6;
int a429DR2_pin = 5;
int a429TXR_pin = 9;

/* Outputs to the ARINC UART */
int a429SEL_pin = 4;
int a429OE1_pin = 3;
int a429OE2_pin = 2;
int a429LD1_pin = 8;
int a429LD2_pin = 7;
int a429ENTX_pin = 10;
int a429LDCW_pin = 11;
int a429MR_pin = 12;
int a429DBCEN_pin = 13;


This tells you how I wired up the board to the arinc chip.
Best Wishes,

author
chizz (author)chizz2013-11-10

come to check it, similar issues with pins 8,9,10,11 on the de1016 chip

author
chizz (author)2013-08-29

You couldn't possibly copy me the final code you got working? I suspect it would be a good jumping off point for my project.

and oblige
Chizz

author
maewert (author)chizz2013-08-29

All of the final code is included in Step 6 except the AVRIO (but I provided a path to it).
Best Wishes.

author
chizz (author)2013-08-25

Are those arduino mega pin numbers the chip pins (my mega has i/o pins that only go up to 53!)

author
maewert (author)chizz2013-08-25

Hello. I'm sorry I did not indicate the pins numbers are the 'physical pin numbers'. The following graphic shows the mapping between the physical and the 'IDE' pins: http://forum.arduino.cc/index.php?PHPSESSID=b0e2fe8d5f09a2f88f1bd7009cdc71d5&/topic,146511.0.html
They are the PORT A and PORT C pins.
I hope I cleared this up.
Thanks,
Mark

author
solarwater (author)2013-04-10

I enjoyed this tutorial and asked for a sample from the manufacturer for a test circuit. I want to pull label 206 from ARINC data (airspeed) and have that output a pitch trim motor speed control (PWM) that varies with airspeed. In our experimental aircraft the typical one-speed trim is too fast at cruise and too slow at landing. This seems a nice way to try the circuit without interrupting the pitot static system.

author
maewert (author)solarwater2013-04-10

Great. The local distributor gave me two samples (the DIP version) which I used to create this tutorial. I think I payed them back with the plugging of their chip here. :-) I had begun working a variation using a teensy ++ 2.0 instead of a full arduino mega. The teensy ++ 2.0 has more pins and looks like it would work instead of the more expensive and larger mega, but SW changes would also need to be made. I have NO experience interfacing with a pitch trim system so I wish you well there! Let me know how it goes!
Best Wishes

author
ncormia (author)2011-12-06

Lo-Speed works fine too. Not sure what I was doing wrong before but it definitely would not have worked before the upper-word bit order was reversed. I've had to take a side-trip into RS-232 in order to complete the other part of my project but I'm getting back to the ARINC side to de-construct the final few GAMA labels.

I think now that its running 12.5khz (lo speed) there should be enough cycles to do the other fun stuff.  Like that LCD screen you're thinking of.  I was just going to build a quick PC-side app to parse the serial data output so I could use it as an aviation data format snooper.

The final Franken-Verter Mega-Shield will (hopefully) have :
* 2 ARINC-429 line level inputs
* 1 ARINC TTL level output (add a driver if you want to use it)
* 2 bi-directional line level RS-232 in/outs tied to the serial 1/2 on the mega board

author
maewert (author)ncormia2011-12-06

Cool. I'm also thinking again about adding the transmitter and building two of them connected via ethernet. I could then combine two labs across town via the internet.
Glad the lo speed is now working ;-)

About This Instructable

30,135views

47favorites

License:

Bio: I'm an aerospace engineer by trade but am interested in astronomy, robotics, CNC machines, Arduinos, you name it.
More by maewert:Color Changing Crystal Staff for CosplayAdvent Calendar BoxInternet Island
Add instructable to: