Portable Function Generator on Arduino




Introduction: Portable Function Generator on Arduino

About: Hi, I have a hobby to build some DIY Audio stuff, simple gadgets, etc. Hope you will find my instructables useful! :)

Function generator is a very useful tool, especially when we are considering testing our circuit's response to a certain signal. In this instructable I'll describe the building sequence of small, easy to use, portable function generator.

Features of the project:

  • Fully digital control: No need for passive analog components.
  • Modular design: Every sub-circuit is a pre-defined easy to use module.
  • Output frequency: Available range from 0Hz to 10MHz.
  • Simple control: Single rotary encoder with built-in push button.
  • Li-ion battery for portable use, with external charging ability.
  • AC and DC coupling for output waveform.
  • LCD Brightness control for energy consumption reduction.
  • Battery charge indicator.
  • Digital amplitude control.
  • Three available waveforms: Sine, triangle and square.

Step 1: The Idea

There are a lot of circuits that require some testing equipment in order to get information about circuit's response to a certain waveform. This project in based on Arduino (Arduino Nano in this case), with 3.7V a Lithium-Ion battery as a power source thus making the device portable. It is known that Arduino Nano board requires 5V as a power supply, so electronic design contains DC-DC boost converter that converts 3.7V battery voltage to 5V required for powering up the Arduino. Thus, this project is easy to build, completely modular, with relatively simple schematic diagram.

Powering the board: Device has a single mini-USB connector that receives 5V from the external power supply, that may be either PC or external USB charger. the circuited designed in a way that when the 5V DC source is connected, Li-ion battery is being charged by TP4056 charger module that is attached to the power supply circuitry (Topic will be expanded further in the following steps).

AD9833: integrated function generator circuit is a central part of the design, controlled via SPI interface with ability to generate square/sine/triangle wave with frequency modulation option. Since AD9833 has no capability to change output signal amplitude, I've used a digital 8-bit potentiometer as a voltage divider at the device output endpoint (Will be described in further steps).

Display: is the basic 16x2 LCD, which is probably the most popular liquid-crystal display among Arduino users. In order to reduce energy consumption, there is an option to adjust LCD backlight via PWM signal from the Arduino pre-defined "analog" pin.

After this brief introduction, we can proceed to the building process.

Step 2: Parts and Instruments

1: Electronic Parts:

1.1: Integrated Modules:

  • Arduino Nano board
  • 1602A - Generic liquid crystal display
  • CJMCU - AD9833 Function generator module
  • TP4056 - Li-ion battery charger module
  • DC-DC Step-Up coverter module: 1.5V-3V to 5V converter

1.2: Integrated Circuits:

  • SRD=05VDC - 5V SPDT relay
  • X9C104P - 8-bit 100KOhm digital potentiometer
  • EC11 - Rotary Encoder with SPST switch
  • 2 x 2N2222A - NPN general purpose BJT

1.3: Passive and unclassified parts:

  • 2 x 0.1uF -Ceramic capacitors
  • 2 x 100uF - Electrolytic capacitors
  • 2 x 10uF - Electrolytic capacitors
  • 3 x 10KOhm Resistors
  • 2 x 1.3KOhm Resistors
  • 1 x 1N4007 Rectifier diode
  • 1 x SPDT Toggle switch

1.4: Connectors:

  • 3 x 4-pin JST 2.54mm pitch connectors
  • 3 x 2-pin JST 2.54mm pitch connectors
  • 1 x RCA Receptacle connector

2: Mechanical Parts:

  • 1 x 12.5cm x 8cm x 3.2cm Plastic enclosure
  • 6 x KA-2mm pulling screws
  • 4 x KA-8mm drilling screws
  • 1 x Encoder knob (Cap)
  • 1 x 8cm x 5cm Prototype board

3. Instruments and Software:

  • Soldering station/iron
  • Electrical screwdriver
  • Grinding files of numerous sizes
  • Sharp knife
  • Drill bits
  • Screwdriver bits
  • Hot glue gun
  • Mini-USB cable
  • Arduino IDE
  • Caliper/ruler

Step 3: Schematics Explanation

In order to make it easier to understand the schematic diagram, description is divided in sub-circuits while every sub-circuit has responsibility for each design block:

1. Arduino Nano Circuit:

Arduino Nano module acts as a "Main Brain" for our device. It controls all the peripheral modules on device, in both digital and analog operating modes. Since this module has its own mini-USB input connector, it will be used both as a power supply input and programming interface input. Because of that, J1 - the mini-USB connector is detached from schematic symbol of Arduino Nano (U4).

There is an option for using dedicated analog pins (A0..A5) as general purpose I/O, so some of the pins are used as digital output, communicating with LCD and AC/DC coupling select of the device's output. Analog pins A6 and A7 are dedicated analog input pins and only can be used as an ADC inputs, because of Arduino Nano microcontroller ATMEGA328P TQFP package, as it was defined in the datasheet. Notice that battery voltage line VBAT is attached to the analog input pin A7, because we need to get its value in order to determine low battery state of Li-ion battery voltage.

2. Power Supply:

Power supply circuit is based upon powering the whole device via Li-ion battery 3.7V converted to a 5V. SW1 is a SPST toggle switch that controls power flow on the whole circuit. As it can be seen from the schematics, when external power supply is connected via micro-USB connector of the Arduino Nano module, battery is being charged through TP4056 module. Make sure that bypass capacitors of several values are present on the circuit, since there is a DC-DC boost converter switching noise on ground and 5V potentials of the whole circuit.

3. AD9833 and Output:

This sub-circuit provides appropriate output waveform, defined by AD9833 module (U1). Since there is only single power supply on device (5V), there is need to attach coupling select circuit to the output cascade. C1 capacitor is connected in series to the amplitude selection stage, and can be silenced via driving current on the relay inductor, thus making output signal traced straight to the output stage. C1 has value of 10uF, it is sufficient for the waveform even of low frequencies to pass through capacitor without being distorted, only affected by DC removal. Q1 is used as simple BJT switch used to drive current through relay's inductor. Make sure that diode is connected in a reverse allocation to the relay inductor, in order to avoid voltage spikes that can damage the device circuits.

Last but not least stage is an amplitude select. U6 is 8-bit digital potentiometer IC, that acts as voltage divider for a given output waveform. X9C104P is a 100KOhm digital potentiometer with very simple wiper position adjustment: 3-pin digital inputs for adjusting increment/decrement wiper position.

4. LCD:

16x2 Liquid crystal display is graphical interface between user and the device' circuitry. In order to reduce energy consumption, LCD backlight cathode pin is connected to Q2 BJT connected as switch, controlled by PWM signal driven by Arduino analogWrite ability (Will be described in Arduino code step).

5. Encoder:

Encoder circuit is a control interface, defining whole device operation. U9 consists of encoder and a SPST switch, so there is no need to add additional buttons to the project. Encoder and switch pins should be pulled up by an external 10KOhm resistors, but it can also be defined via code. It is recommended to add 0.1uF capacitors in parallel to the encoder A and B pins in order to avoid bouncing on these input lines.

6. JST Connectors:

All the external parts of the device are connected via JST connectors, thus making it much more convenient to assemble the device, with an additional feature of reducing place for mistakes during the building process. Mapping the connectors is done this way:

  • J3, J4: LCD
  • J5: Encoder
  • J6: Battery
  • J7: SPST toggle switch
  • J8: RCA output connector

Step 4: Soldering

Because of this project' modular design, soldering step becomes simple:

A. Main board soldering:

1. First of all, there is need to crop the prototype board to the size of desired enclosure dimensions.

2. Soldering The Arduino Nano module and testing its initial operation.

3. Soldering power supply circuit and checking all the voltage values conform the device requirements.

4. Soldering AD9833 module with all the peripheral circuits.

5. Soldering all the JST connectors.

B. External components:

1. Soldering JST male connector' wires to the LCD pins in EXACT order as there were planned on the main board.

2. Soldering JST Male connector' wires to the encoder similarly to the previous step

3. Soldering toggle switch to the JST wires.

4. Soldering JST wires to the battery (If it is needed at all. Some of the Li-ion batteries available on eBay are pre-soldered with their own JST connector).

Step 5: Enclosure and Assembly

After all the soldering is done, we can proceed to device assembly sequence:

1. Think over device external parts placement: In my case, I preferred to place encoder below LCD, when toggle switch and RCA connector are placed on separate sides of the enclosure box.

2. Preparing LCD frame: Decide where LCD will be located on the device, make sure that it will be placed in right direction, it happened to me several times that after I finished all the cutting process, LCD was inverted vertically, speaking of which is sad, because there is need to re-arrange the LCD frame.

After frame is selected, drill several holes on the perimeter of the whole frame. Remove all the unwanted plastic cuts with grinding file.

Insert the LCD from the inside and locate the screw points on the enclosure. Drill holes with an appropriate diameter drill bits. Insert pulled screws and fasten nuts on the inner side of front panel.

3. Encoder: has only single rotary part on the package. Drill the area according to the encoder rotary attachment diameter. Insert it from the inside, fasten it with a hot glue gun. Place a cap on the rotary attachment.

4. Toggle switch: decide on dimensions of the toggle switch swing, so it can may be pulled down or up freely. If you have screw points on the toggle switch, drill the appropriate areas on the enclosure, Otherwise you can fasten it with a hot glue gun.

5. RCA output connector: Drill appropriate diameter hole for the RCA output connector on the side-bottom side of the enclosure. Fasten it with the hot glue gun.

6. Main board and battery: Place Li-ion battery on the bottom side of the enclosure. Battery can be fastened with a hot glue gun. Main board should be drilled in four places for 4 screws on each main board corner. Make sure that Arduino mini-USB input is as closer as possible to the boundary of enclosure (We will have to use it for charging and programming purposes).

7. Mini-USB: cut off the desired area for Arduino Nano micro-USB with a grinding file, thus making it possible to connect external power supply/PC to the device when it is assembled completely.

8. Final: Connect all the JST connectors, attach both parts of the enclosure with a four 8mm screws on each corner of the enclosure.

Step 6: The Arduino Code

Attached code is the complete device code that is needed for complete device operation. All the needed explanation is attached at the comment sections inside the code.

Step 7: Final Testing

We have our device ready to be used. mini-USB connector acts both as programmer input and external charger input, so device is capable of being programmed when is completely assembled.

Hope, you'll find this instructable useful,

Thanks for reading! ;)

3 People Made This Project!


  • Back to School: Student Design Challenge

    Back to School: Student Design Challenge
  • Cheese Challenge

    Cheese Challenge
  • Microcontroller Contest

    Microcontroller Contest



Question 7 months ago

Hello. Thanks for this project. I want to build this. I want these outputs:
voltage: 15-35V
ampere: 0.2-2.5A
frequency: 100Hz - 2000Hz

If I add transistor + voltage regulator with a 12V battery to this circuit can I achieve this?


11 months ago

Hi, great project thanks for sharing. I'm looking at building a dual channel one that needs to be able to generate a signwave at 10V peak to peak with a +7VDC offset, the signwaves need to be sync'd to 90 degrees. any ideas how I'd modify your project?


Reply 11 months ago

You can see my second function generator instructable: It contains dual channel amplifier circuits and customizable biasing as well. Here it is pretty tough to redefine the AD9833 operation. There is an option for AD9834 (See the second instructable).


Reply 11 months ago

Hi do you have a link? I couldn't see the dual channel mentioned in your projects.


1 year ago

Nice project. Where did you get the enclosure? Can't seem to find it. Thanks


2 years ago

This may have worked in the past, but not as of 9/1/20. IDE compiling show a plethany of errors.


Reply 1 year ago

Hi cgin59,
I've compiled it right now, and got no error (I am using Sublime Text and Platformio). Have you added the right libraries?


Reply 1 year ago

i'm really hoping this still works just bought all the parts. Came to compile it and said it was missing the MD_AD9833.h library, installed and now it says "error compiling board for Arduino nano"

i'm hoping i'm just missing a library and some one will point me the right direction to get running.

update: took the exact same code copied it in to the arduino web editor compiled and uploaded first time. not built the circuit yet hoping i can mod the code to I2C LCD


2 years ago

Is there a way to make this do sawtooth up and sawtooth down waveforms? Is there code I can add or is it already there and I just don't see it. Of course I'm not real proficient at C++ programming so it might be. I just want to make sure before I build it. Thanks


Reply 2 years ago

I guess it's rather difficoult to generate some specific waweforms just with "software", maybe..?? don't know. So it goes more to on "conventional" tech's because them MCU's like ATMEGA don't have a built in D/A converter, (they do have this A/D converters).


2 years ago

Gee.. You did a great job with your 'ible, ( I know, I'we done some?, even pupblished).
Hope getting more of You'r doing's


2 years ago

Hi again
I said "output intensity" but meant "Amplitude"


2 years ago

Hi everyone
Built this and it works well,the output at very low signal is not that good
so I got rid of the digital pot. I put the output of the AD device into an
op amp configured for a x10 gain and now it's brilliant !
The problem I have now is to try and work out how to get rid of the
"output intensity" from the screen. I'm totally new to programming,
and at the moment haven't got a clue.
Can anyone help?


2 years ago on Step 2

Hi. Thank you for sharing the design - never would have crossed my mind to make a function generator otherwise. Couple of comments/observations if I may.

I had to add a 20k pot to the display to make it actually show me anything - pot across 5V and ground, wiper to pin 3, VO. This sets the display 'contrast'.

I'm having some issues with the basic functions. Sine & Trianlge outputs just don't work - nothing. Square wave works perfectly. Confused by that one!! AC/DC switching, brightness, output level, all work as they should, as does frequency selection. All displays look as they should.

As regards setting output frequencies, could I suggest/request a change to that? Add some more steps to the setting mode - allow adjustment in steps of 1Hz, 10Hz, 100Hz, 1kHz, 10kHz, 100kHz and 1MHz I'll try(!) and see if I can figure out how to do that myself - I'm not a programmer so it'll be a challenge! Not done any programming since doing some assembly code work on a Texas TMS7782 many years ago.

Re the previous comment about confusion over the 5V line - seems clear that the 5V referred to on the LiOn charger is external 5V from the charger, not the internal 5V rail. Could label it as say USB_5V for clarity??

Best regards


Question 3 years ago on Introduction

I'm confusing on your diagram.
The battery is connected to a DC Boost that generates the 5V necessary for the components.
But this same 5V is connected to the input of the TP4056 that is the battery loader.
So as soon as the SW1 switch is closed you have a loop : the battery generates 5V that is used to load the battery


Answer 3 years ago

Its not actually doing that. the dc/dc buck converter is using its input side from the battery to the circuit. the battery charger is using its output side to the charger. they dont accept inputs in this direction from either device so the buck converter claims power but the charger just lights an LED indicating 5v present


Reply 2 years ago

I don't understand your answer. The circuit is simple :
5V is connected to the input to the battery charger - The battery charger output is connected to the battery and the DC Boost input - the DC boost output generates the 5V for the components and is connected to the input of the battery charger.
So you have a loop.
I'm sure of that because I made the test just with a dc/dc buck converter, a TP4056, and a battery and there is a 200 mA loop


Question 3 years ago

Hi! Very cool project!
Can you generate an ac signal with it? (Meaning producing negative voltages)

Thanks in advance


3 years ago

используйте версию arduino 1.5.8 BETA