I need a list of where I am with all my projects. So here it is
CONCEPT - 2015
1. DDS & RTC shield. Si5351 DDS, outputs G0 (CLK0), G1 (CLK1) & 74AC74 for I/Q outputs. Eagle SCH & BRD files OK, PCBs made
2. SDR RX shield. FST3251 QSD & TLV6424 Amp. 40m input filter. I/Q inputs from DDS & RTC shield. Eagle SCH & BRD files OK, PCBs made.
BASIC - 2016/7
3. VFO-Simple shield. A 40m Varicap tuned VFO for Intermediate students to build. Eagle SCH & BRD OK, PCBs in production.
4. DCRX shield. NE602/SA612 mixer & LM386 Amp. 40m input filter, input from DDS & RTC. Eagle SCG & BRD OK, PCBs made.
5. DCRX_WIDE shield. NE602/SA612 mixer & LM386 Amp. Wide band 50R input matching. Use external BPF for each band. Eagle SCH & BRD OK. PCBs not made, as PCB above can be used.
6. QRP_RIG_BASIC shield. Complete Rig RX & TX. FST3251 QSD & QSE, SSM2135 for audio ccts. Wide band input, use BPF for band selection. Eagle SCH & BRD OK. PCB in production.
7. RF_METER shield. Input 40dB attenuator, AD8307. Output 20MHz LPF ERA-2SM buffer. Eagle SCH & BRD OK, PCB made
8. RETURN_LOSS shield. Antenna analyser bridge, circuit under development. Proto done, software shaky
9. WSPR_PA. No design done, may use commercial 2W wide band amp driven by DDS & RTC via BPF, need LPF on output? Could use for QRP_RIG if arrange TX/RX switching...
10. BPF_BASIC shield. Design done for 40, 30 & 20m BPF, 2KHZ BW Chev. Eagle SCH &BRD OK. PCB in production. Tested, doesn't work abandoned Replaced by 3xLPF shield
Future
External PA 20-50W to be defined, stand alone with internal PSU & LPFs, maybe Antenna auto tuning?
Friday, 23 December 2016
BASIC Tech Group - MyNews 12 - All my hardware shieldprojects update
BASIC Tech Group - MyNews 11 - Final BPF, QRP_RIG & RF METER PCBs
Well I've taken the plunge, or in other words ordered my Christmas present! I have ordered the PCBs for three of my projects. Yes three!
The BPF-Basic - note: this abandoned as doesn't work...
This is a set of three Band Pass Filters for 40, 30 & 20m bands. Intended for use both for the front end for the QRP_RIG TXRX, the DCRX Direct Conversion RX, or any other input/output that needs a BPF on one of the bands.
The QRP_RIG-Basic a single board TXRX
This has been on of my long term aims, to build a single board Arduino shield which is an SDR based TX and RX able to work over a wide band of frequencies - is it a broadband design, the working frequency is determined by the DDS input and BPF on the input/output.
An RF METER-Basic - schematic updated, see later blog
A sensitive RF Meter with RF output also from the DDS via a LPF and buffer amplifier
This is one of the most useful measurement tools for an amateur shack, able to measure RF inputs, to 50R impedance, from -60dBm to more than +20dBm. And an RF source at around 1-10mW programmable by the Arduino from 100kHz to 20MHz.
Let's hope these work first time as the PCB costs are going up as the UK Pound falls - they come from Eurocircuits in Belgium, one fo the few PCB makers that accept Eagle "BRD" file inputs.
Wednesday, 21 December 2016
BASIC Tech Group - MyNews 10 - ADF4351 project, LPFs, RF Meter update
Wow! Says Gordon (G4EBF) who is building a 35MHz - 4.4GHz VFO based on the ADF4351, to program this he is learning about the Arduino. Today he says he he has got the Arduino IDE installed on his PC, has configured it, and has loaded his first program to Blink and LED. Well done, that's the way everyone starts with the Arduino, and that's what we did at BARS during the Concept SDR project last year.
I have received a set of LPFs from LanguageSpy and have put the values of the components into LTSpice to see what they yield.
And this is the response in LTSpice for the 20m filter:
Quite a nice response and sharp cut off, with a little bit of ripple in the passband.
I have decided to order their 17m filter and use this in my RFMETER design to filter the Si5351 DDS output and remove higher harmonics. The RFMETER design is now complete.
I will be ordering the PCBs (10) very soon.
Tuesday, 20 December 2016
BASIC Tech Group - MyNews 9 - New WSPR sketch 40m
Finished the coding of a new WSPR sketch, based on the WsprMessage.h library written by John Newcombe and used and published by M0XPD.
I built this into a library module that can be included in the Arduino sketch. This sketch uses the LCD display routines of my previous WSPR program, but is simplified as it has a fixed repeat interval for transmission of 2sec and a fixed frequency of 7040.1kHz (the previous sketch allowed a Rotary Encoder input to change the frequency and the repeat interval - an upgrade would be easy to do to implement these features).
Photo shows the 2 shield stack on top of the Arduino UNO, the DDS and a LPF shield
As usual there is an option to define the LCD I2C address as some displays use 0x27 while others use 0x3F.
The system timing is provide by an RTC (DS3231) module on the Si5351 DDS shield. This can be set by a separate Arduino sketch (at the bottom below) to the correct time, which must be good to 1second.
The code to transmit is also hard coded into the sketch, in my case it is currently "M6KWH IO92 20". The WsprMessage.h library encodes this into 162 elements of value 0, 1, 2 or 3 in the array WSPR_Message{ ].
The WSPR system has a 4 level FSK modulation, with frequencies spaced by 1.4548Hz! This is trick to do, and what this sketch does is to define a frequency shift for each element in an array delta[ ]. The data is the frequency shift of each element to the nearest cHz (0.01Hz) as this is the resolution that can be generated by the Si5351 and the si5351.h library. All frequencies are defined for this library in cHz. So, for example, the variable WSPRFreq = 7040.1kHz is 704010000cHz. All frequency variables are uint64_t size.
The newer LiquidCrystal_I2C.h library is used (from HobbyComponents.com) which has a different set of calls, in particular the initialisation is done with lcd.begin(), not the previous library call lcd.init(). And the new si5351.h library is also used which changed some of the calls to program the SI5351 chip. If you are going to use this code, make sure you Google and use the new version of the libraries.
I have put a Zip file of all these libraries here.
Download the code for WSPR and for RTC time setting
WSPR_40M-Basic
RTCSET-Basic
BASIC Tech Group - MyNews 8 - Update LPF, QRP_RIG & BPFs
A few progress reports on the Arduino projects:
1 - LPFs ordered from languageSpy web site for 40, 30 & 20. Maybe incorporated into the buffer amplifier using an ERA-2+ MMIC, on the antenna bridge and/or RF Meter shield designs...
2 - PCB design for the QRP-RIG i done, awaiting checking carefully..
3 - Band pass filters designed for BPF shield, 40, 30 & 20m, 2MHz BW Chev 0.1dB ripple.
More news coming when QRP-RIG & RF METER PCBs finalised and ordered.
Slides of current BASIC Arduino projects is here.
Monday, 12 December 2016
BASIC Tech Group - MyNews 7 - Harmonics from Si5351 DDS?
Using a Si5351 module from Adafruit (Kanga) as a VFO for my Direct conversion RX and for my WSPR TX.
The WSPR TX is transmitting on 7040.1kHz with the "M6KWH IO92 20" message..
I have the RX connected to my Macbook via a Startech A/D convertor running at 48kHz sample rate. The on the Macbook I ran two programs, Argo.exe a Windows program running un Wine emulator, and WSPR program native to the Mac.
These are what the two prgrams show when the RX is tuned to 7038.6kHz.
and
What you can see here is that a lot of harmonics or side lobes are being received. I don't know if these are being transmitted by the WSPR TX or if they are spurious reception by the RX. What I get on the WSPR readout is two IDs, one at the nominal 7040.1 frequency (at 100 on the scale) and another which is 100Hz above. These two and others can be seen on the Argo screen.
I have tried all sorts of software changes but not found the cause...
Monday, 28 November 2016
BASIC Tech Group - MyNews 6 - WSPR reception using DCRX
Wonderful day today for WSPR reception on 40m, mainly from PA & DL.
This is again using the set up of Arduino UNO, Concept DDS, and DCRX receiver. With a squatty small vertical indoor aerial.
SDRTX abandoned - now to be a QRP TXRX RIG
I have re-thought the SDRTX and decided to try for a more ambitious full QRP rig, a single board (shield) with an SDR RX and SDR TX on it, output around 10mW. This will be topped off with a three band BPF shield to work on 40, 30 & 20m.
Components researched and found for this are the FST3253 for the Mixers, and the SSM2135 dual op-amp for the audio side. This device is a new find for me and is a kind of super op-amp with very high output drive capability needed for the TX driver (4 channels into 50R loads).
Schematic later and PCB layout when ready. WIll probably breadboard the TX first as not yet got one running...
Decided also to move across to SMA connectors, these are much lighter but can handle up to 20W! and plentifull low cost cables are on eBay (SMA-SMA, SMA-BNC, SMA-PL59...).
Saturday, 12 November 2016
BASIC Tech Group - MyNews 5 - Arduino Sketches & libraries
New initiative
At the Banbury Amateur Radio Society we are starting a group to play with technology for Amateur Radio, we call it the BASIC Tech Group.
The aim is to bring together people interested in building equipment and tools for Amateur Radio, and cooperating to get them done. I will post things of possible interest here.
First here are some interesting Arduino Sketches:
Sketches
CAP-Basic - a capacitance measurement sketch
FREQ-Basic - a frequency measurement sketch, needs an external divide by 10, CMOS 4017
I2CSCAN - a popular public program to scan the I2C bus (Arduino UNO pins A4 SDA and A5 SCL) and report any I2C addresses found
RFMETER - using an external circuit of a 20dB attenuator feeding an AD8307 IC, input on pin A0, with Arduino AREF connected to 3.3V
RTCSET-Basic - this allows you to set the date/time on the DS3231 IC on our DDS Arduino Shield.
SDR_40M-Basic - generates 40m I/Q signals from our DDS Arduino Shield to drive a Tayloe style detector
VFO-Basic - a general purpose VFO with output from 10kHz to 250MHz based on our DDS Arduino Shield using the Si5351 synthesiser. The output gives about 1Vrms into 100R load
VFO-Basic-4 - a version of the above that uses a 4 line 20x4 display, the top line showing date & time from the DDS Shield RTC.
libraries
You will need some Arduino BASIC-libraries to run these sketches, a whole bunch of libraries I have collected is here. Take care using the new LiquidCrystal_I2C library, HobbyComponents have posted a changed: the "init" routine, it is now called "begin".
The hardware projects have been posted before on this blog.
Tuesday, 8 November 2016
BASIC Tech Group - MyNews 4 - SDR TX
SDR TX - ALL STOP!!! The PCB for this is wrong. I made a stupid number of mistakes when building the TDA7266D device library for Eagle and got the pin numbering wrong!! Project abandoned, see News 6 for replacement QRP RIG
The long awaited design for the SDTTX_BASIC simple SDR 40m transmitter has got to the PCB order stage. I am still not sure of the design, having seen others using a DRV135 (balanced line driver) audio stage...
This follows a careful check of the schematic and of the board layout. See below.
Software
Two pieces of software are used for the SDRTX. One running on the Arduino which is the same as that used for the SDR RX. This generates the IQ modulation signals at 4 x freq and drives the IQ modulator FST3253 chip.
The FST3253 chip is also fed with the four audio phases 0, 90, 180 & 270 degrees.
The audio is generated by the HDSDR.exe program running on my Macbook under the Wine emulator, and output via a Startech DAC. Anyone wanting to do this MUST download and install the file "ExtIO_SRlite.dll" too (see HDSDR page, download under "Softrock Lite v0.12"), put it in the HDSDR folder to enable the HDSDR program to enter Transmit mode (SPACE bar, use RETURN key to send morse code in CW mode).
Code
// My_SDR_40M // for 40m, with TX/RX control and bandplan display // Si5351 I2C bus // SDA = A4 // SCL = A5 // LCD I2C bus // SDA = A4 // SCL = A5 // ADDR 0x27 or 3F // rotary encoder pins // DT = 2 // CLK = 3 // SW = 4 // I2C, Si5351, LCD and rotary Encoder libraries #include "Wire.h" #include "si5351.h" #include "LiquidCrystal_I2C.h" #include "Rotary.h" // LCD #define LCDADDR 0x27 #define LCDCOLS 16 #define LCDROWS 2 // rotary Encoder pins 2 & 3 (DT & CLK), step change pin 4 (SW) #define DT 2 #define CLK 3 #define SW 4 // Rx & Tx signals #define RX 13 #define TX 12 #define KEY 8 // number of band plans #define PLANS 12 // dds object Si5351 dds; // LCD object LiquidCrystal_I2C lcd(LCDADDR, LCDCOLS, LCDROWS); // rotary Encoder object Rotary rot = Rotary(DT, CLK); // define plan structure typedef struct { uint32_t lower; uint32_t upper; char alloc[30]; } plan; // band plan array contents cHz/cHz/Text plan bp[PLANS] = { {700000000, 700100000, "CW QRSS 7000.7 "}, {700100000, 703990000, "CW QRP 7030 "}, {703990000, 704690000, "NB WSPR 7040 "}, {704600000, 704990000, "NB Auto "}, {704990000, 705290000, "ALL Auto "}, {705290000, 705990000, "ALL Digital "}, {705990000, 706990000, "ALL "}, {706990000, 707990000, "ALL HELL 7077 "}, {707990000, 709990000, "ALL SSB QRP 7090"}, {709990000, 712990000, "ALL EMGCY 7110 "}, {712990000, 717490000, "ALL SSB CON 7165"}, {717490000, 720010000, "ALL DX INTNL "}, }; uint32_t freq = 700000000; // cHz, start frequency uint32_t step = 10000; // cHz, init 100Hz step void setup() { // init LCD & backlight on lcd.init(); lcd.backlight(); // init dds si5351 module, "0" = default 25MHz XTAL dds.init(SI5351_CRYSTAL_LOAD_8PF, 0); // set 8mA output drive (max possible) dds.drive_strength(SI5351_CLK2, SI5351_DRIVE_8MA); // can insert Si5351 calibration here if required // enable SDR output CLK2, disable CLK0 & 1 dds.output_enable(SI5351_CLK0, 0); dds.output_enable(SI5351_CLK1, 0); dds.output_enable(SI5351_CLK2, 1); // encoder, button, RX, TX, band and KEY pins pinMode(DT, INPUT_PULLUP); pinMode(CLK, INPUT_PULLUP); pinMode(SW, INPUT_PULLUP); pinMode(RX, OUTPUT); pinMode(TX, OUTPUT); pinMode(KEY, INPUT_PULLUP); xmit(digitalRead(KEY)); // set RX|TX, KEY = LOW is TX freqOut(freq); // cHz, output freq dispFreq(4, 0, freq, 1); // display freq kHz col 4 row 0 dispMsg(0, 1, scanPlan()); // display band plan col 0 row 1 } void loop() { // tune? if (tune()) { freqOut(freq); // output freq dispFreq(4, 0, freq, 1); // update freq display dispMsg(0, 1, scanPlan()); // update band plan display } // step? if (button()) { dispStep(step, 14, 0); } xmit(digitalRead(KEY)); // RX|TX } // tune? bool tune() { unsigned char dir; // tuning direction CW/CCW dir = rot.process(); // read encoder if (dir != DIR_NONE) { // turned? if (dir == DIR_CW && (freq < bp[PLANS - 1].upper - step)) freq += step; if (dir == DIR_CCW && (freq >= bp[0].lower + step)) freq -= step; return true; } return false; } // change step? bool button() { if (digitalRead(SW) == LOW) { // button pressed? while (!digitalRead(SW)); // wait for release if (step == 1000000) step = 10000; // reset else step = step * 10; // or increment by x10 return true; } return false; } // search for band info char *scanPlan() { for (int i = 0; i < 15; i++) { if (freq >= bp[i].lower && freq < bp[i].upper) // find plan return bp[i].alloc; // return when found } } // Output Freq for SDR, on CLK2, f cHz void freqOut(uint32_t f) { dds.set_freq(f * 4ULL, 0ULL, SI5351_CLK2); } // Tx/Rx KEY HIGH = RX, LOW = TX void xmit(bool x) { if (x == LOW) // TX { dispMsg(0, 0, "TX "); digitalWrite(RX, HIGH); // Rx off digitalWrite(TX, LOW); // Tx on } else { dispMsg(0, 0, "SDR"); digitalWrite(RX, LOW); // Rx on digitalWrite(TX, HIGH); // Tx off } } // display char msg at col c, row r void dispMsg(uint8_t c, uint8_t r, char *m) { lcd.setCursor(c, r); lcd.print(m); } // display freq in kHz at col c, row r, f cHz, d decimal places void dispFreq(uint8_t c, uint8_t r, uint32_t f, uint8_t d) { lcd.setCursor(c, r); lcd.print((float)f / 100000, d); // convert to float & kHz lcd.print("kHz "); } // display step void dispStep(uint32_t s, byte c, byte r) { switch (s) // display step { case 10000: dispMsg(c, r, " "); break; case 100000: dispMsg(c, r, " +"); break; case 1000000: dispMsg(c, r, "++"); break; } }
The code include RX/TX switching, and so you must ground the Arduino UNO pin 8 for PTT, this pulls D12 low (and D12 high to disable the SDR RX) and enables the FST3253 TX Mixer.
Monday, 7 November 2016
BASIC Tech Group - MyNews 3 - RF Meter
Here's the RFMETER. Input impedance is 50R, input attenuator of 20dB, max input power 2W. Two line display of dBm, Watts & Volts
Input is to Arduino Uno pin A0, AREF analog reference is connected to 3.3V.
Code
// RF-Meter, // input 50R/2W via a pi 20dB attenuator 82R - 240R - 68R // displays dBm, Watts, Volts. Autoscaling #include#include #define LCDADDR 0x3F #define LCDCOLS 16 #define LCDROWS 2 // Analog input pin #define DCIN A0 #define AREF 3.3 // intercept (dBm), slope (mw/dB), input impedance, attenuator (dB). #define INTERCEPT 84.0 #define SLOPE 25.0 #define IMP 50 #define ATTN -20 LiquidCrystal_I2C lcd(LCDADDR, LCDCOLS, LCDROWS); void setup() { lcd.begin(); lcd.backlight(); // 3.3V connected to AREF analogReference(EXTERNAL); lcd.clear(); lcd.setCursor(4, 0); lcd.print("RF METER"); } void loop() { float mV, dBm, mW, V; // calculations for MV input, dBM, mW, and Volts mV = 1000.0 * (float)analogRead(DCIN) * (AREF / 1023); dBm = (mV / SLOPE) - INTERCEPT; dBm -= ATTN; mW = pow(10, (dBm / 10)); V = sqrt((mW / 1000) * IMP); // dBm lcd.setCursor(0, 1); lcd.print(dBm, 0); lcd.print("dBm "); // Watts if (mW < 1.0) { lcd.print(mW * 1000, 0); lcd.print("uW "); } else if (mW < 1000.0) { lcd.print(mW, 0); lcd.print("mW "); } else { lcd.print(mW / 1000, 1); lcd.print("W "); } // Volts if (V < 1.0) { lcd.print(V * 1000.0, 0); lcd.print("mV "); } else { lcd.print(V, 1); lcd.print("V "); } delay(500); } float dbmMw(float dbm) { return pow(10, (dbm / 10)); }
Saturday, 29 October 2016
BASIC Tech Group - MyNews 2 - Freq Meter
This project has been abandoned as the accuracy is too low
Natively the Arduino UNO can use its timers to count up to around 6MHz. This can be extended up to a more useful 60MHz by using a divide by ten pre-scaler, for example the CD74HC4017 chip.
Here's the schematic for a FREQ_BASIC shield, it uses a 2 line by 16 column I2C Serial LCD display:
Code
// FREQ-Basic, v2, Input Pin 5 #include#include #include // this LCD has an address of 3F, some others use 27. 16 columns, 2 rows #define LCDADDR 0x3F #define LCDCOLS 16 #define LCDROWS 2 // lcd object LiquidCrystal_I2C lcd(LCDADDR, LCDCOLS, LCDROWS); // count result, and Arduino crystal correction unsigned long count; float freq; float corr = 0.99852; void setup() { lcd.init(); lcd.backlight(); lcd.clear(); FreqCount.begin(1000); } void loop() { if (FreqCount.available()) { count = FreqCount.read(); lcd.setCursor(3, 0); lcd.print("Frequency"); freq = (float)count * corr / 100000; // lcd.setCursor(3, 1); lcd.print(freq, 3); lcd.print("MHz "); } }
On test with Arduino Si5351 DDS VFO on the left
Accuracy is better than +/-500Hz, so not so good for accurate readings or frequency calibration, But OK for a general purpose indicator.
Thursday, 6 October 2016
BASIC Tech Group - MyNews 1 - Concept & Basic
Last year we made a DDS in the "Concept" program, this provides us with an Arduino shield for frequency synthesis from 100kHz to 250MHz, SDR IQ outputs and a real time clock.
New BASIC project
The list of possible boards in the project is:
1. VFO - A 40m Basic VFO along the lines of that needed by the Amateur Radio Intermediate course. Introducing a Colpitts serial tuned oscillator with vari-cap tuning and an output buffer stage.
Eagle files can be downloaded here Schematic, Board.
2. DCRX - A 40m Basic Direct Conversion Receiver for CW and SSB, based on the world's simplest circuit using the SA612 mixer and LM386 audio amplifier.
Eagle files can be downloaded here Schematic, Board
Combined together the VFO and DCRX it makes a simple receiver for 40m, with manual or Arduino software tuning.
Here are the input filter LTSpice simulations:
Combined with the DDS frequency synthesiser board of the previous CONCEPT project, instead of using the VFO, the receiver can be tuned to an accurate frequency in the 7MHz band.
Here is the DDS & DCRX in operation, with WSPR signals being received on 40m, with the RX output fed to a Startech ADC running at 16bit/44.1kHz and fed to the WSPR program running on my iMac.
3. Future projects which are just ideas today and would be developed by members include:
- RFMETER - An RF measurement meter, measuring -80 to +10dBm. Update see later posting for completed design.
- BRIDGE - An Antenna Analyser, basically a 50 ohm bridge that shows the antenna impedance and SWR. RF input from the VFO or DDS
- QRP_RIG - a complete SDR based QRP TX RX
- WSPR PA - a 2W PA for 40, 30, 20m for a WSPR beacon.
- BPF - a switchable 40, 30 20m BPF board that can be used with the RFMETER and QRP_RIG
... and as many other ideas that members have. As an aside have a look at this web site by PY2OHH for a combine measurement system, similar to a combination of our boards stacked on our Arduino UNO. Could give some inspiration.
Thursday, 18 August 2016
BBC Micro:bit calls CQ CQ...
There is a new module available for the BBC micro:bit in the MicroPython programming language. This is a speech generating module.
The results are crude, unless you very carefully adjust the message content and speech settings. But it works out of the box.
Here is a short program to call CQ for myself, M6KWH.
Code
# Call CQ M6KWH from microbit import * import speech # init pin0 to 0 to define a level and stop "hum" pin0.write_digital(0) message = "C Q! C Q! C Q! M 6 K W H! calling C Q!" while True: # flash arrow W display.show(Image.ARROW_W) sleep(500) display.clear() sleep(500) # if A pressed, say greetings if button_a.was_pressed(): speech.say(message, speed=80) sleep(1000)
Wednesday, 17 August 2016
433MHz control of room lighting
The Energenie sockets that are very low cost on Amazon, are controlled by a push button hand-held controller. It outputs codes over a 433.92MHz RF signal, which the sockets receive and respond to.
Each socket has a different code, one for ON and one for OFF.
RX & TX
There are some very low cost 433.92MHz transmitters and receivers on the market (below £2 the pair!). Using the receiver and some Arduino software the codes for your personal sockets can be read from the hand-held controller. Once you know these, a second Arduino program can be used to send these code out using the transmitter, and this will control the sockets.
The software for all this is in a library called "RCSwitch.h" downloadable here. The examples given with this library show how to use it.
These are the Energenie sockets and their controller. Each socket has to initialised to match a code from the controller, but when this is done the sockets can be controlled from the Arduino and connected transmitter.
The receiver is on the right and the transmitter to the left. Each has three connections (the OUTput of the receiver is on two connected pins). The receiver is connected to +5V, pin 2 (interrupt 0) and GND when you run the code reading sketch (see RCSwitch Examples). The transmitter is connected to +5V, Arduino pin 10 and GND. The sketch below allows you to type 1/2, 3/4, 5/6 into the Arduino Serial Monitor window and to switch ON or OFF three of the sockets (the code could easily be extended to cover the four sockets, and the ability to switch ON/OFF all the sockets at once. The codes below are for the sockets I bought, you will have to read and substitute your own codes.
Code to read remote codes
// RX_find_code_1 // detects remote RF signals and IDs LOW, HIGH and length // start program, then push a button on the remote // reset to re-run the program // LED pin, RX input pin #define LEDPIN 13 #define RXPIN A0 //Create an array to store the data const int dataSize = 500; byte storedData[dataSize]; // upper and lower thresholds const unsigned int upperThreshold = 100; const unsigned int lowerThreshold = 80; // maximum length of the signal, length of signal int maxSignalLength = 255; int dataCounter = 0; // start time, end time, read time unsigned long startTime = 0; unsigned long endTime = 0; unsigned long signalDuration = 0; void setup(){ Serial.begin(9600); pinMode(LEDPIN, OUTPUT); /* The following code will only run ONCE -------------- ---Press the reset button on the Arduino to run again-- */ //Wait here until a LOW signal is received while(analogRead(RXPIN) < 1) { startTime = micros(); //Update start time with every cycle. } digitalWrite(LEDPIN, HIGH); //Turn LED ON //Read and store the rest of the signal into the storedData array for(int i = 0; i < dataSize; i = i+2) { //Identify the length of the LOW signal---------------LOW dataCounter = 0; //reset the counter while(analogRead(RXPIN) > upperThreshold && dataCounter < maxSignalLength) { dataCounter++; } storedData[i] = dataCounter; //Identify the length of the HIGH signal---------------HIGH dataCounter = 0;//reset the counter while(analogRead(RXPIN) < lowerThreshold && dataCounter < maxSignalLength){ dataCounter++; } storedData[i+1] = dataCounter; /* Any readings between the two threshold values will be ignored. * * The LOW or HIGH signal length must be less than the variable "maxSignalLength" * otherwise it will be truncated. * * All of the HIGH signals and LOW signals combined must not exceed the variable "dataSize" * otherwise it will be truncated. * * The maximum number of signals is 1700 (memory limit) * If you try to extend this variable to a higher number than 1700 * then the Arduino will freeze up and sketch will not work.*/ } //Record the end time of the read period. endTime = micros(); signalDuration = endTime - startTime; //Turn LED OFF digitalWrite(LEDPIN, LOW); //Send report to the Serial Monitor Serial.println("====================="); Serial.print("Read duration: "); Serial.print(signalDuration); Serial.println(" us"); Serial.println("====================="); Serial.println("LOW, HIGH"); delay(20); for(int i = 0; i < dataSize; i = i+2) { Serial.print(storedData[i]); Serial.print(", "); Serial.println(storedData[i+1]); delay(20); } } void loop(){ //Do nothing here, press reset to re-run the program }Code to transmit the codes
/* Example for my own codes, yours may be different */ #includeMy future target is to add a speech recognition board from Audeme to the Arduino UNO and control my lighting by voice!// constructor for mySwitch object RCSwitch mySwitch = RCSwitch(); byte inByte = 0; void setup() { Serial.begin(9600); // Transmitter is connected to Arduino Pin 10 mySwitch.enableTransmit(10); // Optional set pulse length. // mySwitch.setPulseLength(320); // Optional set protocol (default is 1, will work for most outlets) // mySwitch.setProtocol(2); // Optional set number of transmission repetitions. mySwitch.setRepeatTransmit(4); Serial.println("Ready"); // Ready to receive commands } void loop() { /* Switch using decimal code */ if(Serial.available() > 0) { // A byte is ready to receive inByte = Serial.read(); if(inByte == '1') { // byte is '1' mySwitch.send(14237327, 24); Serial.println("1 ON"); } else if(inByte == '2') { // byte is '2' mySwitch.send(14237326, 24); Serial.println("1 OFF"); } else if(inByte == '3') { // byte is '3' mySwitch.send(14237319, 24); Serial.println("2 ON"); } else if(inByte == '4') { // byte is '4' mySwitch.send(14237318, 24); Serial.println("2 OFF"); } else if(inByte == '5') { // byte is '5' mySwitch.send(14237323, 24); Serial.println("3 ON"); } else if(inByte == '6') { // byte is '6' mySwitch.send(14237322, 24); Serial.println("3 OFF"); } } }
Thursday, 11 August 2016
Morse Code Trainer
One thing about morse code is you need repetitive training. No better way to learn and improve your reception. So here's a thing - a MicroPython program running on the BBC micro:bbit that generates random morse letters and sounds for you to train by.
The connections are simple, pin'0' and GND go to an active piezo buzzer.
Code
The code is self explanatory, for those that know Python. It was written in the "Mu" code editor which has been specifically written to support the micro:bit on all platforms.
from microbit import * import random # 'constants' for delays all derived from dot length dotlength = 250 dashlength = dotlength * 3 interelement = dotlength interletter = dotlength * 2 # images for displaying dots and dashes dot_img = Image('00000:00000:00900:00000:00000:') dash_img = Image('00000:00000:09990:00000:00000:') letter = ("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z") # Dictionary morse = { "A":".-", "B":"-...", "C":"-.-.", "D":"-..", "E":".", "F":"..-.", "G":"--.", "H":"....", "I":"..", "J":".---", "K":"-.-", "L":".-..", "M":"--", "N":"-.", "O":"---", "P":".--.", "Q":"--.-", "R":".-.", "S":"...", "T":"-", "U":"..-", "V":"...-", "W":".--", "X":"-..-", "Y":"-.--", "Z":"--.." } # function to convert string to pattern of dots and spaces def EncodeMorse(message): m = message.upper() enc = "" for c in m: enc = enc + morse.get(c," ") if morse.get(c," ") != " ": enc = enc + " " return enc # function to flash out a Morse pattern on the matrix def FlashMorse(pattern): for c in pattern: if c == ".": display.show(dot_img) pin0.write_digital(1) sleep(dotlength) display.clear() pin0.write_digital(0) sleep(interelement) elif c=="-": display.show(dash_img) pin0.write_digital(1) sleep(dashlength) display.clear() pin0.write_digital(0) sleep(interelement) elif c==" ": sleep(interletter) return # helper function to encode and flash in one go def MorseCode(message): m = EncodeMorse(message) print(m) FlashMorse(m) return while True: message = random.choice(letter) MorseCode(message) sleep(2000)
Tuesday, 9 August 2016
Micro:bit Traffic Lights
A simple, but fun, application of the BBC Micro:bit is to build a set of pedestrian traffic lights. You push the button, the lights cycle to red, it goes pip-pip-pip then the lights cycle back to green.
Pin 0 goes to the active piezo buzzer, pins 13, 14, 15 are the G, Y, R LEDs and the "cross" switch is on pin 16. The LEDs have series 330R resistors (the current must be limited to less than 5mA for the micro:bit), and the switch has a pull up resistor of 10k to 3V.
Code
# Traffic lights # pins 330R-LED-GND: 13 green, 14 yellow, 15 red, 16 switch(10k pull-up, active LOW) # import the micropython library from microbit import * # set period of pin 0 pwm output pin0.set_analog_period(400) pin0.write_analog(0) while True: # green on pin13.write_digital(1) display.show("G") # wait for switch if pin16.read_digital() != 1: # green off, yellow on pin13.write_digital(0) pin14.write_digital(1) display.show("Y") sleep(2000) # yellow off, red on, pip-pip-pip pin14.write_digital(0) pin15.write_digital(1) display.show("R") pin0.write_analog(200) sleep(8000) # yellow on, red remains on, pip off pin14.write_digital(1) display.show("Y") pin0.write_analog(0) sleep(2000) # red & yellow off pin14.write_digital(0) pin15.write_digital(0) # loopPress the button to cross the road
Saturday, 30 July 2016
Got my Micro:bit
I received my BBC Micro:bit this morning. Here's one of the first programs I tried out:
Using the Micropython editor "Mu" which runs on all platforms, edits code, and flashes the micro:bit directly - very easy and efficient... A note I should mention is that Micropython runtime is downloaded to the micro:bit along with your program when you "Flash".
Code
from microbit import * while True: reading = accelerometer.get_y() if reading > 400: display.show(Image.HAPPY) else: display.show(Image.SAD)
Resulting in two images on the micro:bit:
and when you tip it up:
Saturday, 9 April 2016
Plan for a Home Automation system
Actually what I would like to do is just control the lights in my home. But in a new way.
Recently there has been announced a very interesting new Arduino Shield product, the MOVI Voice Recognition shield. This is a stand alone VR shield that has its own 2GB dictionary and phonetic sound translation system. You train it with text phrases, it translates these into English phonetics and is then able to recognise these phrases when you speak into the built-in (or external) microphone. Providing a unique output to the Arduino for each phrase recognised.
My plan is like this:
I would use the Energenie RF controlled sockets, these have a 433.92MHz RX and recognise a unique ID, Number and control (ON/OFF) transmission from a small TX on a new Arduino shield. The recognised voice phrase will be translated by software on the Arduino to transmit the correct codes to turn ON/OFF the sockets.
So that's the project, now to acquire the MOVI shield, some Energenie sockets and build the RF TX shield (very simple) I will also build a RX shield so that I can find out the codes sent by an Energenie transmitter.
Wednesday, 23 March 2016
SSB from Raspberry Pi
The next thing I want to try is to generate SSB from the Raspberry Pi. To do this I use the "rpitx" program. To get this go to GitHub/F5OEO/rpitx where you will find everything you need and also stuff for SSTV, NBFM modes.
But first I need an audio file, which must be a mono, "wav" format, file and sampled at 48kHz. My Raspberry Pi is called "fido" and my "SSB" directory looks like this:
pi@fido:~/SSB $ ls CQIQ.wav CQ.wav pissb rpitx usage.txtHere you can see the original "CQ.wav" file. I generated this file on my Mac using the built-in microphone and Soundstudio software. I recorded it, converted it to mono, converted the sample rate to 48kHz, then applied some EQ and compression/normalisation. The result is not marvellous but its OK for testing.
You can also see in the directory this file after conversion to an "IQ" format file, "CQIQ.wav" - the kind you get from or send to your SDR radio to receive or transmit SSB, this is a stereo file with I = left and Q = right.
The conversion is made with the program "pissb", it converts to USB today, LSB is not yet an option:
./pissb CQ.wav CQIQ.wavThen to transmit this as SSB, with the output on GPIO18 (pin12) of the R_PI, at 7110kHz:
sudo ./rpitx -m IQ -i audioIQ.wav -f 7110.0 -l"sudo", or run as superuser, is needed to access the GPIO pins. The command line is made up like this
-m IQ - is the mode of transmission, that is IQ -i audioIQ.wav - is the input file name -f 7110.0 - is the frequency in kHz -l - means loop, or repeat the transmissionThis is the received signal on my Arduino SDR using the HDSDR software. Frankly it is not very good SSB and the bandwidth is over 3.5kHz, but it is readable.
The creator of the program is said to be working on improving the SSB generation.