FPGA project for encoding/decoding multi channel RC servo data

Objective: ======== I want to start learning FPGA by experimenting with them. (I do have experience in digital electronics, microcontrollers and programming. But I do not have FPGA experince.) What I want to use FPGA for is as follows;

PPM/PCM Decoding: ================ I want to use FPGA to decode PPM and/or PCM signals from a 8-16 channels RC (radio control) transmitters. This is equivalent to measuring pulse widths of 8 pulses in a repeating pattern as shown in the following liks *

formatting link
*
formatting link

I want to be able to measure servo data in 10 bits resolution and send channel data via an RS232 port similar to one shown in the following links *

formatting link
*
formatting link
*
formatting link

Driving multi-channel RC servo motors : ============================ I also want to use the FPGA to read in multi-channel servo motors from a serial RS232 port and control multi channel (8-16 RC servo motors) similar to one shown in the following links *

formatting link
*
formatting link
*
formatting link
*
formatting link

Questions: ======= Can you advise me * A "low cost" FPGA development board * Free or "low cost" software development tools * Example FPGA code for above mentioned projects (PPM/PCM decoding and driving multi-channel RC servo motors)

Thank you.

FPGA Newbee

Reply to
<Newbee>
Loading thread data ...

formatting link

Avnet has fairly low cost boards, less than $200 a couple of years ago. If you need something even lower cost try a web search.

Xilinx gives away their "Web pack" tools which are quite good. I'll bet that Altera does also. You could also check the Xilinx and Altera web sites for boards, but the last time I checked (two-three years ago) Xilinx just pointed you to various 3rd-party vendors.

PPM decoding is easy, PCM decoding will take extensive reverse engineering, and varies from one manufacturer to the next. I would suggest you stick to PPM.

I can't point you to code, but PPM code is _so_ easy that if you can't figure it out you should probably stay away from FPGA work entirely. I suggest you start by encoding a servo pulse, go from there to measuring a pulse width, then tackle sensing the frame sync in a PPM train. You may find that getting the RS-232 to work is the hardest part, but once you have it, you'll just need to put pieces together.

--
Tim Wescott
Wescott Design Services
 Click to see the full signature
Reply to
Tim Wescott

I did that. with an Altera FPGA. We wanted

14 bit resolution on the pulse.
formatting link
formatting link
formatting link
The hardware is a bit outdated and too expensive. An AVR does the stuffing and the communication. You basically need one counter for the repetition, 20ms, and a set of counters for the pulsewidth. Try the schematic approach.

Rene

--
Ing.Buero R.Tschaggelar - http://www.ibrtses.com
& commercial newsgroups - http://www.talkto.net
Reply to
Rene Tschaggelar

PCM data formats are manufacturer specific and not published anywhere that I have seen. PPM is easily done as it is relatively standard. I have done it with a simple piece of code in a microcontroller using a single timer capture input. I have also done it with RTL for much the same reason that you are interested.

This is most easily done with a single timer channel on a microcontroller driving an external 8 bit serial in parallel out shift register and a bit of firmware.

The reason I mentioned using the microcontroller is mostly as a disclaimer, so nobody would point and laugh at the huge use of resources for so simple of a problem. That said, here is a copy of the verilog I wrote a few years ago for measuring the pulse widths of up to 8 channels, to 12 bit resolution. It was designed to be a microcontroller peripheral for an 8 bit micro. I have similar code for the output function if you are interested, email me (after de-munging the address). This is not in the shiniest verilog style, but here it is:

/****************************************************************************** * * Inport * This is an RC system interface. Input data is a composite * pulse train. * 8.0 mHz input clock rate. * Negative active reset. * * The values of the pulse widths may be read as unsigned 12 bit numbers * 8 bits at a time via the CPU bus interface. * * * Written by Bob Harbour 1/97 * *****************************************************************************/ `timescale 1ns/1ns

module Inport (PulseIn, Data, Busy, Addr, nCS, nWE, nRst, Clk);

input PulseIn; // Pulse train in inout [7:0] Data; // CPU data bus output Busy; // Indicates Pulse is in Sync area input [3:0] Addr; // CPU address lines input nCS; // CPU chip select input nWE; // CPU write enable input nRst; // reset input input Clk; // clock input

wire PulseIn; wire [7:0] Data; wire [3:0] Addr; wire nCS, nWE, nRst, Clk;

// // Instantiate CPU interface. // nCS Addr nWE register // H XXXX X none // X XXXX L none // L 0000 H Chan1 Latch read Hi Byte // L 0001 H Chan1 Latch read Lo Byte // L 0010 H Chan2 Latch read Hi Byte // L 0011 H Chan2 Latch read Lo Byte // L 0100 H Chan3 Latch read Hi Byte // L 0101 H Chan3 Latch read Lo Byte // L 0110 H Chan4 Latch read Hi Byte // L 0111 H Chan4 Latch read Lo Byte // L 1000 H Chan5 Latch read Hi Byte // L 1001 H Chan5 Latch read Lo Byte // L 1010 H Chan6 Latch read Hi Byte // L 1011 H Chan6 Latch read Lo Byte // L 1100 H Chan7 Latch read Hi Byte // L 1101 H Chan7 Latch read Lo Byte // L 1110 H Chan8 Latch read Hi Byte // L 1111 H Chan8 Latch read Lo Byte //

reg [11:0] Latch1, Latch2, Latch3, Latch4, Latch5, Latch6, Latch7, Latch8; wire ReadEn; reg [7:0] readback;

assign ReadEn = ~nCS & nWE;

always @(Latch1 or Latch2 or Latch3 or Latch4 or Latch5 or Latch6 or Latch7 or Latch8 or Addr) case (Addr) 4'b0000: readback = {4'h0,Latch1[11:8]}; 4'b0001: readback = Latch1[7:0]; 4'b0010: readback = {4'h0,Latch2[11:8]}; 4'b0011: readback = Latch2[7:0]; 4'b0100: readback = {4'h0,Latch3[11:8]}; 4'b0101: readback = Latch3[7:0]; 4'b0110: readback = {4'h0,Latch4[11:8]}; 4'b0111: readback = Latch4[7:0]; 4'b1000: readback = {4'h0,Latch5[11:8]}; 4'b1001: readback = Latch5[7:0]; 4'b1010: readback = {4'h0,Latch6[11:8]}; 4'b1011: readback = Latch6[7:0]; 4'b1100: readback = {4'h0,Latch7[11:8]}; 4'b1101: readback = Latch7[7:0]; 4'b1110: readback = {4'h0,Latch8[11:8]}; 4'b1111: readback = Latch8[7:0]; endcase

assign Data = ReadEn ? readback : 8'bz;

// // Generate a 500Khz clock period wide pulse // reg [2:0] ClockDiv; reg DelClockDiv2; wire [2:0] NxtClockDiv; wire Clk1Mhz;

assign NxtClockDiv = ClockDiv +1;

always @(posedge Clk or negedge nRst) if (!nRst) begin ClockDiv

Reply to
Bob

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.