Monday, July 25, 2016

Software Receiver Design Tutorials Progress

S O F T W A R E   R E C E I V E R   D E S I G N   N O T E S / T U T O R I A L


Abstract
This page contains links to all of my tutorials. I don't want to call them pure tutorials, because I don't baby the reader through the process I went through, rather, I'm trying to document the process I experienced in learning and implementing a software radio system in hope that I help somebody who is in my position, curious about this somewhat advanced topic and has tried hunting for the information, but have opened Pandora's box of questions after reading them. Sometimes they are wrong. But hopefully, my material will reinforce other things learnt from other people's material and I want to capture the difficulties that I encountered, because a polished paper has inherently eliminated that.
  • Motivation for Software PLL
    • Discusses the problems and questions that arose from me trying to learn about software PLLs from other people's websites. Me learning about Software PLLs ultimately led to me to learning about software receivers.
  • Tutorial 0 - Pulse Amplitude Modulation
    • The code that I wrote to turn a 'string' into a sequence of discrete [-3, -1, 1, 3] pulses. 
  • Software Receiver Design Textbook

Sunday, July 24, 2016

Nasty Python Code

~/Documents/Python/SoftwareReceiverDesign/pam_generator.py.html
import numpy as np
import itertools

def letters2pam(s):
        return list(itertools.chain(*[[int(pair[0] + pair[1],2)*2-3 for pair in np.reshape(list('{:08b}'.format(ord(c))),(4,2))]  for c in s]))


Saturday, July 16, 2016

M O D E L I N G    T H E    P E A K   D E T E C T O R

How do we account for the behavior of the peak detector the Z-transform? My idea is to inject a sinusoid at increasing amplitudes and plot the average output values against the input amplitudes.

The input frequency was 1 kHz. 
 

It's almost linear, the slop is a little less than 1.

What about its frequency response?

The input amplitude is 1 for all the sinusoids tested.

Great, I think I'm just going to assume a gain of 1, and flat frequency response.
However, it takes some time for an input sinusoid's amplitude to appear at the output. And for this, I think I will just use Z^(-D), where D is the number of samples you must wait for the sinusoid's amplitude to appear at the output, which depends on its frequency and sampling rate. [Edit] I actually just didn't bother with taking this into account. I'm just going to cross my fingers.

~M O D E L L I N G   T H E   S Y S T E M   I N   M A T L A B~

With the gain/behavior of the process in mind, lets turn our attention to the digital control system. Before we start writing code, we should use math and analyze the stability of the system. 

Using Matlab, I simulated the step response of the system that I showed earlier. It's steady state response was off by half! Which meant, that I needed an integrator.


In the following, I will show the loop responding to a unit step input. Each plot depicts a loop with a specific gain setting.
~K = 0.5~

~K = 1~

~K = 1.5~


THE IMPLEMENTATION, DIFFERENCES BETWEEN THEORETICAL BEHAVIOR AND ACTUAL SIMULATION

 I didn't expect the program to behave the way it did. But hey, that is engineering. I ended up having to iteratively tune the loop gain and peak detector time constant. Initially, with all of the values discussed above, with the loop gain equalling 0.5, 1.0, 1.5, made the loop unstable, this was due to the peak detector's delay. Above, I said I would deal with it when I got to the implementation. Well, the delay mattered in the end. I had to tune the loop gain down to 0.1, and make the peak detector's time constant smaller. (If I were to use a peak detector circuit as an analogue, I made lowered the resistor's resistance so that it can drain the capacitor faster. This way, the loop reacts faster to changes made to the input sinusoid's amplitude).

Time for pictures, and then maybe code.
Input sinusoid frequency = 1 kHz
Reference amplitude = 10








Monday, July 4, 2016

Simulating a Peak Detector in the Sampled Domain


D I G I T A L   P E A K   D E T E C T O R

I'm using this blog as documentation for myself and as a resource for other people who want to accomplish similar or the same thing as I am trying to do, which is to make a software PLL all in code, that synchronizes to a digital input signal.

In an effort to jot down things quickly, and because I'm lazy, I'm going to cut to the chase. I'm trying to build an auto gain digital control system to equalize an input signal to the PLL I have yet to build. As you can imagine, if input [carrier] were a sampled audio signal or data from a SDR, it could have any amplitude.

I don't know if any of my ideas will work, but I'm jotting them down as I go. I'm not coming back.

~Q U E S T I O N S   T H A T   I   A S K E D   M Y S E L F~

I asked the following questions to myself:
  • What is the process you are trying to control?
    • The input power.
  • What is the process's input and output?
    • input = its volume, output = output power.
  • What is your reference?
    • The desired output power.
Quick Sketch of AGC system:

~I M P L E M E N T I N G   T H E   P R O C E S S / P L A N T~

Now I will talk about my approach to the Process/Plant.
The input to the process is the volume, which results in an output power. Volume is easy, I just multiply the input sample by a gain factor. Output power/amplitude? In circuits, I would use a peak detector with RC tank attached. 


The diode is simulated with an if statement in code. If the input voltage is greater than the output voltage, the output voltage becomes the input voltage. Otherwise, let the difference equation do its thing, which is exponentially decay. 

The following is the resistor capacitor parallel tank derivation.

 I'd love to be a better teacher right now and baby you through the MATLAB code but here it is:


Sick. This is a good warmup for the big PLL. 
peak_detector

Thursday, June 27, 2013

Part 2: Wrapping Up the Cable Release Project


PREV: PART 1
READ FROM BEGINNING: PART 0 

P A R T 2,   W R A P P I N G   U P

It's time to wrap up this project. Another plus from using the ?auxilary flash?  case to house my project is that it has it's own battery compartment. It takes 4 AA batteries to make 6 volts. I've been thinking about this for a while, and the servo runs just fine off 6 - 4 volts. However, my precious processor doesn't (2.7 - 5.5).  

Can't use a 7805 voltage regulator as it needs at least 7v to output 5v. 
Too lazy to buy a low drop out regulator.

I've decided that I want to use a Diode to drop the tiny's supply voltage.

For those that don't know what a diode is, it's a component that only lets current flow in one direction. And in addition to only letting current flow in one direction, there must be a constant voltage drop across it. (Something that has to do with electrons jumping the electron band gap for ya'll with a chem 101 background). Another interesting fact is that with a diode, voltage and current are independent to each other.. they do not follow ohms law. So by putting a diode in front of my processor, I drop the voltage by about 0.7v (almost all diodes have this voltage drop). What's going to keep me up at night is the inefficiency of this, because the diode consumes power by V * I = watts consumed.

P I C T U R E S

Lets face it, people wanna see the good stuff first

































Whew! You made it to part 2. You deserve my source code: 
Git Hub

Some things to mention about my code:
  • There's an example of how to get servo control running on a 4313 chip at 8MHz 
    • The servo code is messy, I do not use Timer1 to its full potential, you can potentially have two servos running at once, I didn't write that code, but it should be easy.
    • I tried to "inherit" the Timer1 fast PWM code that I wrote since the servo uses fast PWM, so you'll see that I over write register that I had just written to in another file.
  • I don't think the delay functions work properly, you are better off using the <util/delay.h> ones. 


Wednesday, June 26, 2013

Part 1 Software: Automatic Camera Cable Release with an ATTINY 4313


Prev: Part 0
Next: Part 2
P A R T 1,   S O F T W A R E   D E T A I L S

I know reading can be boring, so here's the end result of the user interface I was trying to achieve, read more about how the menu user interface works below. 

video

The necessary logic components this project requires are:
  • Timer tick for the countdown - this will be interrupt driven in the background by the 8 bit timer on the 4313. 
  • Servo control - will be driven by fast pwm on the 16 bit timer for extra precision
  • User interface
    • Buttons UP, DOWN, SELECT all of which will use interrupts
    • Menu logic
I wanted the menu to be as extendible as possible, the code should be slick and work in blocks. I'd like to approach this problem like I would in Java but in C. 

I settled on having a main menu:

typedef struct {
   uint8_t len;
   MenuItem menuItems[];
}Menu;

A Menu has items in it, that makes sense, and it has a length, which is necessary of iterating through each of the individual menuItems..
Then you've got a Menu Item:

typedef struct {
   char name[17];
   void (*action)(void);
}MenuItem;

The key to this I thought was to only allow menuItems to be flexible in the struct. And make each MenuItem a strict static size. 

Digression about structs:

The interesting thing about a struct that has an array in it with an unknown size like:
typedef struct {
   uint8_t len;
   MenuItem menuItems[];
}Menu;
Is that the compiler will actually leave this as a variable size.. That is until you instantiate it, then it has to be a fixed array. 

An also interesting aspect about the structs is that:
typedef struct {
   uint8_t len;
   MenuItem * menuItems;
}Menu;
Isn't the same thing as above. The compiler will actually (it seemed) only reserve space in the struct for the size of a pointer, not continuous block of menuItems. You'll just have to find out for yourself when you do it!

end Digression

So, we've got this flexible Menu with a bunch of menu items. 
I thought it was a cool idea to say that each MenuItem has a name, 17 chars long (16 character lcd + '\0') and that each has an action method

So in my main loop, all the code does is iterrate through a the list of menuItems. Each menuItem has a name so the code will print that to LCD. And when the user hits select, the code calls the 

menuItem[cursor]->action();  

R E A L I S T I C   S U D O   C O D E

void setTimer() { stuff }
void setHoldtime(){ stuff }
void start(){ stuff }

//Instantiation 
Menu menu = 
{5, 
   { 
   {">SET TIMER      ", &setTimer},
   {">SET HOLD TIME  ", &setHoldTime},
   {">START          ", &start},
   {">TEST           ", &test},
   {">RESET          ", &reset}
   }
};

You just call the action like this:

   (*menu.menuItems[cursor].action)();

cursor is being adjusted in the background by the user and appropriate logic to prevent cursor from going out of bounds because of menu.len 

When it comes to displaying things not selected by the cursor, I just advance the pointer of the menuItem name string by 1, this way only the index of cursor will skip over the '>'

//puts takes a char *
puts( menu.menuItems[anything but cursor index].name + 1 );

D E M O

video

Part 0: Automatic Camera Cable Release with an ATTINY 4313

Prev: Part 2
Next: Part 1


P A R T   0,   G E T T I N G   T H E   H A R D W A R E   U P   

A N D   R U N N I N G


My buddy wanted me to build a timer controlled cable release cable for his old school camera. 
Here's a cable release:
image

The left most part screws into a camera:
image

and the operator presses down on the trigger to take a picture. 
Anyways, he wanted a timer-based-device that uses a cable release to take a picture. The user should be able to set a count down time for when the cable release triggers. 

I N G R E D I E N T S 
  • Using an Atmel Tiny 4313 as the controller. I have a pretty good code library that I've built up, I'd rather not waste my time reading another datasheet. 
  • A 2 X 16 LCD junk character display. The good thing about these are that they all have a common interface. I actually didn't write the code to control it, I used a generic library: Generic 2x16 LCD Driver 4-bit mode
  • Parallax Servo from Radio Shack.
CREDIT: I got a couple of ideas from this hackaday post: Handya

One of the main ideas I got from Handya's post was using a hot shoe (something that mounts on top of the camera to hold my device. I thought about it, chewed on the idea and settled on: 


An ?auxiliary flasher? device from my parent's camera cabinet. They won't be missing this baby. I figured I'd be giving it a new life. 



C O N S T R U C T I O N 


The first step I took was getting my 2x16 LCD code working. Again, I got the code from here: Generic 2x16 LCD Driver 4-bit mode

C O N F I G U R I N G   T H E    L C D   C O D E

It was written to be generic. In 4-bit mode, you need 4 data lines, a register select RS line, and a LCD enable E line. Write on the LCD should always be pulled low.

So you ultimately have six GPIO pins, the original library used

#define LCD_RS    PORTD.2    // Register select
#define LCD_EN    PORTD.3    // Enable
#define LCD_D4    PORTD.4    // Data bits
#define LCD_D5    PORTD.5    // Data bits
#define LCD_D6    PORTD.6    // Data bits
#define LCD_D7    PORTD.7    // Data bits

#define    LCD_STROBE    ((LCD_EN = 1),(LCD_EN=0))

To drive each individual pin, the code does something like this:
//drive LCD_RS high
LCD_RS = 1;
//low
LCD_RS = 0;

It's kind of like a PIC. But I'm using the avr-gcc library, which doesn't have fancy structs. So to implement this interface I had to go:

typedef struct {
   uint8_t bit0 : 1;
   uint8_t bit1 : 1;
   uint8_t bit2 : 1;
   uint8_t bit3 : 1;
   uint8_t bit4 : 1;
   uint8_t bit5 : 1;
   uint8_t bit6 : 1;
   uint8_t bit7 : 1;
} PortBits;

volatile PortBits * PORTBbits = (PortBits*) &PORTB;
volatile PortBits * PORTDbits = (PortBits*) &PORTD;

#define LCD_RS PORTDbits->bit6    // Register select
#define LCD_EN PORTBbits->bit0    // Enable
#define LCD_D4 PORTBbits->bit1    // Data bits
#define LCD_D5 PORTBbits->bit2    // Data bits
#define LCD_D6 PORTBbits->bit5    // Data bits

#define LCD_D7 PORTBbits->bit6    // Data bits

#define    LCD_STROBE    LCD_EN = 1; _delay_ms(2); LCD_EN=0

TRANSLATION: I had to make a new type, that used bit fields to separate each of the 8 bits. This allows me to set each individual bit simply by going:

PortBits port;
port.bit0 = 1;
port.bit1 = 1;

But this code above won't actually write to PORTA, or B or C. 
Since every single pointer is simply an address to a location in RAM, I simply made a pointer of the type PortBits to the address of PORTB: 

Newbies {

   PortBits * port = &PORTB;
   unsigned char * port2 = &PORTB;

   //but since the compiler will complain, I have to override it by casting:
   PortBits * port = (PortBits*) &PORTB;

port == port2, pointers simply point to addresses in RAM, all pointers are also the same size (I actually don't confidently know... it must depend on the max address of the memory?). The difference between port and port2 is how the compiler will ALLOW you to handle the pointer once it is dereferenced. Therefore, making a pointer of the type PortBits will allow me to handle the byte at location &PORTB with bit fields 

   PortBits * PORTBbits = (PortBits*) &PORTB;

  //will set PB0 high, get it?
   PORTBbits->bit0 = 1;
}

CODE ERRATA: Initially my display wasn't working. I basically lucked out guessing and said: 

#define    LCD_STROBE    LCD_EN = 1; _delay_ms(2);  LCD_EN=0

I would recommend playing around with the delay value, maybe even taking it out if your display isn't working. 
4313 running at 8MHz 

Conclusion: I bread boarded my LCD module and got a simple hello world message running.  


S E R V O

Now for the tricky part. I mean, I'm an EE/software guy, generally mechanical engineering is a tougher game to play. But this is the BOMB solution I came up with it's fricken rock solid and I didn't use any epoxy. 

I used brass hinges to mount the servo. I basically walked into a hardware store and felt my way around. I let the parts speak to me! 



And for this next part of actually mounting the cable release I have to thank Handya's post that gave me the idea of bending the shutter release trigger head like so:


Do you see it coming together??



I'd like to thank my console modding days at benheck forums for giving me the skillz to drill holes larger than the biggest drill bit I have!

H A R D W A R E   P R E - D E V E L O P M E N T

Note the tactile button on bottom left (part of user interface)

Coming up next, coding the user interface!
Part 1