Spartan-6 Microboard: 16-bit R-2R DAC! [Part One]

So how do you produce a usable, somewhat analog signal out of a purely digital device? Well it’s actually simple; use a R-2R ladder and a bunch of digital pins. Basically we’re turning a dearth of extremely high speed digital IO pins into one high-resolution analog output. Oh, also necessary for this circuit (go ahead and crack out the protoboard and soldering iron) is 3 matched resistor per bit of resolution; so in our case, 48.

A 16-bit R-2R Ladder Schematic

A 16-bit R-2R Ladder Schematic

Fun! Here’s a diagram. So how’s it work? When we drive our 16 outputs with digital logic, each pin has half the voltage range of its leftwards neighbor — due to it being a stacked  voltage divider. This is exactly how you  convert from binary to decimal; each digit has twice the value of one neighbor, and half that of the other (discounting the Most and Least Significant Bits) so we can  convert 1s and 0s into a wide numeric  range of values.

This is probably confusing: I know how it works, and I just confused myself. For a *much* better explanation, refer to this previous post of mine.

We’ve got a  circuit, we know conceptually how it works, how do we make it do? Make…make it do right? This is where my brain started screeching to a halt. Hell, I must be driving with the E-brake on, because this is actually super easy, and explaining why helps to understand VHDL/Verilog.

Firstly, in programming languages, things happen sequentially: A, then B, then conditionally C, for example. In Hardware Description Languages, things happen simultaneously: A <= a and B <= b and C <= c all happen simultaneously. Secondly, all of our analog values we’d want to output, such as 62101 is actually represented in a variable, described thusly:

wire [15:0] our_var

It’s actual designation in the chip is in the form 0b1111001010010101.
This means all we have to do to convert our digital data to our analog output at full clock speed is this:

always @(*) begin
pin15 <= our_var[15]
pin14 <= our_var[14]
...
pin1 <= our_var[1]
pin0 <= our_var[0]
end

These all update at the same time, and our output is produced thusly. So, I’ve been dismissing the most major disadvantage? Speed. Lets say we want to make a 16b sine wave. Our speed is limited to f_clk/number_of_levels. So FM is out of the question with this particular implementation (I’m not ruling it out completely, let me know if you know more than I do) but it’s the perfect speed for audio applications.

With a 350MHz DCM, and using 16,384 distinct levels, I can generate a f_max of around 21kHz, well above the range of human hearing. So let me work on getting that code finished, and I’ll return tomorrow. I’ve got my wheels pointed towards the curb, and my E-brake on, and I need a break for the night.

Spartan-6 Microboard: FM All-Band CQ Transmitter

Here we go! This time we’re starting something a little bit more advanced. Lets check out the digital clock manager (DCM), which allows us to make custom clocks that run faster or slower than the actual physical clock. So what are we going to do with this? We’re going to make an FM transmitter that can transmit on any amateur radio band* and, of course, the standard FM radio band.

* please note this is totally illegal if you’re not a licensed HAM. So if you get caught, that’s on you.

I got most of this code from hamsterworks. It was a short simple piece of code that would type out S O S on 91MHz. I made it slightly less ridiculous I having a type out CQ (this is used to seek out contacts.) At least that way, my neighbors aren’t taking an axe to their dashboards trying to find a little man screaming for help. My neighbors are weird like that.

I put a ~1M long piece of 22Ga wire in the output pin, and get at least 10M range. No idea what kind of power I’m putting out (microWatts at most) and I fixed the frequency drift by finding the exact frequency given by the DCM.

Since this code had to be modified (only slightly, I won’t lie) I did some of my best commenting; I know that would have helped me. (Mind the scrollbar at the bottom.)

FM_Xmit.VHD

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity fm_xmit is
    Port ( clk : in  STD_LOGIC;
           antenna : out  STD_LOGIC;
	   rst : in STD_LOGIC;
	   sw : in std_logic_vector(3 downto 0)	
	   );
end fm_xmit;

architecture Behavioral of fm_xmit is
   component fast_clock
   port ( CLK_IN1  : in  std_logic; --These are the signals from our Digital Clock Manager
          CLK_OUT1 : out std_logic; --Make sure the names are the exact same (not case sensitive)
	  RESET    : in std_logic   --Or this won't work at all
   );
   end component;

   signal clk320            : std_logic;
   signal shift_ctr         : unsigned (4 downto 0) := (others => '0');
   signal phase_accumulator : unsigned (31 downto 0) := (others => '0');
   signal beep_counter      : unsigned (19 downto 0):= (others => '0'); -- gives a 305Hz beep signal
   signal message           : std_logic_vector(33 downto 0) := "1110101110100001110111010111000000"; --gives CQ in morse

	signal band_160m			: std_logic_vector (3 downto 0) := "1111"; --These are the 
	signal band_80m				: std_logic_vector (3 downto 0) := "1110"; --positions of 
	signal band_60m				: std_logic_vector (3 downto 0) := "1101"; --the 4 onboard
	signal band_40m				: std_logic_vector (3 downto 0) := "1100"; --dip switches,
	signal band_30m				: std_logic_vector (3 downto 0) := "1011"; --giving us a
	signal band_20m				: std_logic_vector (3 downto 0) := "1010"; --binary band 
	signal band_17m				: std_logic_vector (3 downto 0) := "1001"; --select.
	signal band_15m				: std_logic_vector (3 downto 0) := "1000";
	signal band_12m				: std_logic_vector (3 downto 0) := "0111";
	signal band_10m				: std_logic_vector (3 downto 0) := "0110";
	signal band_6m				: std_logic_vector (3 downto 0) := "0101";
	signal band_2m				: std_logic_vector (3 downto 0) := "0100";
	signal band_1_25m			: std_logic_vector (3 downto 0) := "0011";
	signal band_fm				: std_logic_vector (3 downto 0) := "0000";
	shared VARIABLE upper_side_signal: 	INTEGER; --these variables allow us to calculate
	shared VARIABLE lower_side_signal: 	INTEGER; --our clock divider ratio from the base 
	shared VARIABLE current_freq: 		INTEGER; --320MHZ (319996800Hz) to get our square
	shared VARIABLE center_signal: 		INTEGER; --wave period right

begin

clock320 : fast_clock PORT MAP(
clk_in1 => CLK,
clk_out1 => CLK320,
reset => rst
);

   antenna <= std_logic(phase_accumulator(31));

   process(clk320, sw)
   begin
	IF    (sw = band_160m) 		THEN 	current_freq := 1810000; --these are the standard morse
	ELSIF (sw = band_80m) 		THEN 	current_freq := 3560000; --calling frequencies in the USA
	ELSIF (sw = band_60m) 		THEN 	current_freq := 5403500; --modify them to whatever you like
	ELSIF (sw = band_40m) 		THEN 	current_freq := 7040000; --in Hz.
	ELSIF (sw = band_30m) 		THEN	current_freq := 10106000;
	ELSIF (sw = band_20m) 		THEN 	current_freq := 14060000;
	ELSIF (sw = band_17m) 		THEN 	current_freq := 18080000;
	ELSIF (sw = band_15m) 		THEN 	current_freq := 21060000;
	ELSIF (sw = band_12m) 		THEN 	current_freq := 24910000;
	ELSIF (sw = band_10m) 		THEN 	current_freq := 28060000;
	ELSIF (sw = band_6m) 		THEN 	current_freq := 50090000;
	ELSIF (sw = band_2m) 		THEN 	current_freq := 144100000;
	ELSIF (sw = band_1_25m) 	THEN 	current_freq := 222100000;
	ELSIF (sw = band_fm) 		THEN 	current_freq := 100100000; --100.1 MHz, open freq here
	ELSE         
    current_freq := 91000000;
	END IF;

	upper_side_signal := (current_freq/319996800*(2**32)) + 75000; --This exact clock frequency fixes
	lower_side_signal := (current_freq/319996800*(2**32)) - 75000; --the 'drift' shown in the video
	center_signal := (current_freq/31996800*(2**32));

      if rising_edge(clk320) then
         if beep_counter = x"FFFFF" then
            if shift_ctr = "00000" then
               message <= message(0) & message(33 downto 1);
            end if;
            shift_ctr <= shift_ctr + 1;
         end if;      

         if message(0) = '1' then
            if beep_counter(19) = '1' then
               phase_accumulator <= phase_accumulator + upper_side_signal; --+75kHz signal               
            else
               phase_accumulator <= phase_accumulator + lower_side_signal; -- -75kHz signal
            end if;
         else 
            phase_accumulator <= phase_accumulator + center_signal; -- center frequency signal
         end if;

         beep_counter <= beep_counter+1;
      end if;
   end process;
end Behavioral;

Pins.UCF

NET "clk" LOC = C10;
NET "antenna" LOC = F15;
NET "rst" LOC = V4;
NET "sw[0]" LOC = B3 | PULLDOWN;
NET "sw[1]" LOC = A3 | PULLDOWN;
NET "sw[2]" LOC = B4 | PULLDOWN;
NET "sw[3]" LOC = A4 | PULLDOWN;

Teaser: Spartan-6 LX9 Microboard

Sparta-6 LX9 Microboard from AVNET and Xilinx

Sparta-6 LX9 Microboard from AVNET and Xilinx

This is teasing you as much as it is me. This is the Microboard. it’s an FPGA development board with onboard ram, 10/100 ethernet, and USB (among the various blinky switchy things all development boards must have) for the low, low cost of around $90.

Or if you know someone like Vlad a bit cheaper. Thanks for the donation!

For my first project, I’m looking at a simple FM (re)transmitter.  I want to make a local area delay filter. Think about it.

Mojo Spartan-6 FPGA Boards!

Mojo Back

Mojo Spartan-6 FPGA Boards!

I’m not gonna lie, super excited for this project. I’ve been wanting to get started with FPGAs for a while now, but the price was too high. Not to mention, you have to learn a new language, or two (VHDL and Verilog, you had better learn both eventually.)

Spartan-6 Chip; ATMega16u4 Far Right

The Mojo board simplifies it, or will attempt to. Coming in at only $74.99, the price is quite right; and the creators aim to step you through tutorials as they roll out the project. Now, compared to most FPGA development boards, it doesn’t have many bells and whistles: no Ethernet, VGA, HDMI, USB Host, high speed RAM, or much really. It gets by with just a reset button and 8 leds, if you really want it, you can just wire it up (except the high speed ram, that requires additional engineering, shipping from Krypton; that involves Superman — don’t even bother.)

Anyway…was saying…excited!

Check out this list of premade modules (called cores) while we wait, and spam the hell out of them till they sell you one — you won’t regret it!

Concept 3 built and the site going Live!!

We need this, check it out.

Concept 3 built and the site going Live!!.

MQ3 (or MQ303a) Alcohol Sensor Arduino Guide

This little device is wonderful, for parties at least. Accuracy wise, it’s not much more than a toy (without some opamps for signal amplification and filtering) but I digress. Just plugged right straight into an Arduino will be plenty of fun, assuming you read the datasheet.


To wire this properly, check out this diagram, which will get further explanation after the break.
Continue reading

Preparing for FREE DAY

It’s that time of the year again, to rape Sparkfun’s servers trying to get free shit. Instead of the situation last year, where you earned your loot by answering multiple choice questions (I got 4 ATtinys! FO’ FREE) it’s all chance. Will you or won’t you win a $100 gift card? Only the universe knows.

BUT YOU CAN GET FREE SHIT

There are many ways to get free components, microcontrollers, top-of-the-line ICs, and so on and so forth. Read on, dear brother, read on.
Continue reading

IR remote control reverse engineering

If you’re anything like me, or the vast majority of Americans, you are surrounded by IR devices at home, at work, and pretty much everywhere you go. A great number of these devices (round 90%, its kind of the standard) use the 38 kHz SonyIR protocol, but knowing just that doesn’t help much. Especially if you lack a proper oscilloscope, like me. Plus, hell, your remote might be in that mysterious 10 percent. In order to figure out the actual encoding, you need to be able to plot the signals while you fiddle with the remote, and then make a chart relating the independent variable (the fiddling) to the depedent variable, the bursts of 0s and 1s that inevitably ensue.

IR pulses for various button presses on someone else's oscilloscope :-\ man browser up

Trandi has done precisely that, in his reverse engineering a remote controller from a toy chinook to operate his land based Rover and has devised an excellent technique for visualizing the data transmissions from the remote with just an attiny and a IR photodetector IC from radio$hack. Now if you, like me, find your local radio$hack overpriced and understocked, over on the arduino forums its been discovered the same resolution can be had with a plain IR phototransistor and optionally a cheap opamp like the lm741 (or also I hypothesize with a TL082 dual biFET (perhaps wired as a fourth order Butterworth high-pass?) and a IRled. Likely it’d work best reverse biased, reducing the slow response time typical of using an led as a photodiode, at the expense of increased noise. What’s the point? Never had one. And that just burns you up inside!) provided you modify your timings a bit.

A remote much like this one was harmed. Severely.
Continue reading

Arduino on the attiny in 15 minutes

It’s actually fairly easy, you must do precisely this. First, you will need to download the one of the files listed below, depending on which model attiny you’d like to use (I’d suggest installing them all, so it will be easy to change between microprocessors as the situation warrants.) For the example case, I will be using the attiny85, so, I will refer to the attiny45_85.zip file.

First, make sure the Arduino program is *not* currently running, if so, shut it down. Open your arduino folder (arduino_022, or whatever you’ve named it) and create a folder inside your sketchbook folder called hardware (if it does not already exist.) Extract the zip file, and copy the folder within to your newly created hardware folder. The arduino IDE is now prepared to program your attiny. If you have a stand alone ISP, skip down to the ‘my first ardutiny program’ below. Otherwise, you need to configure your arduino (or compatable) to program your bare attiny.

Fortunately, the arduino IDE comes with a sketch built in to handle this task. Connect your arduino, start up the IDE, and select the ‘Arduino ISP’ sketch from the examples menu. Upload the sketch to the arduino, and now were ready to wire this bad boy up.

image

The picture above shows my setup. Basically, you need to connect the attiny to power and ground, connect three of its pins (5, 6, and 7) to three of your arduino’s pins (11, 12, and 13) respectively. Connect the attiny pin 1 to the arduino’s pin 10; this will allow your attiny to be automatically reset as you program the microcontroller. *If you’re using a teensy or other ‘arduino-compatable’ your pins will be different. If you can’t work it out, feel free to contact me in the comments.*

ardutiny programming
Now, were ready to program. Select ‘attiny85 (w/ Arduino as ISP)’, open up the blink sketch from the examples, and hit program (likely some errors will pop up, ignore these, and carry on). Take a LED, and connect it as shown above, and watch it light up!

This allows the attiny to support the best arduino functions such as digitalWrite(), digitalRead(), analogRead(), analogWrite() this is our PWM! More on this in tomorrow’s article. It also is hip with the time based functionality, such as millis() and pulseIn() another very useful function to be covered this week!

Give your thanks to these folks, if they’re still listening, MIT HLT Lab, and Alessandro Saporretti. Questions, comments and hopefully plenty of b**ching in the comments below, por favor.

files
attiny84
attiny45/85.zip
the avr motherlode

Homebrew Amateur Radio Superguide

image

So this book has been apparently been riding the internets for a few years, but it’s new to me, and a very interesting read. It is at least if you have interest in radio tech, like myself. It starts out with a quite comprehensive overview of radio history (which in itself explains many concepts of the art) and eventually gets into the juicy, technical details — this man knows his stuff. The pdf is called Crystal Sets to Side band, by Frank Harris, K0IYE. You can find it here. I recommend downloading the whole book, and sharing it with any hams you think might be interested, as this is on of the best books on the subject I’ve found, as it wasn’t easily extracted from the noise on the internet.

Create a free website or blog at WordPress.com.

%d bloggers like this: