Weather Station Facelift

Tyler Pattison N1QQ Arduino Weather Station

The online user interface for my weather station project got a nice face lift recently. I've managed to streamline some of the php code and do some formatting using bootstrap which resulted in a much more pleasing GUI. I also am in the process of adding humidity measurements to my weather stations, but I'm not happy with the current platform. Ideally I'd like to have all digital sensors to avoid noise problems that I'm dealing with using long cable runs to outdoor locations. Another option might be using an ADC at the sensor with enough resolution to give a precise temperature reading.

I'll be exploring this problem more in my free time, but for now, take a look at the updated display page. Also, thanks to the generosity of family in Spokane, I now have two identical weather stations taking measurements, and they both can be accessed online in real-time thanks to the recent changes I made in the php code.


Low power HF beacon project using Arduino

I recently got a cheap 40MHz signal generator board off of ebay for a few bucks. I modified some code I found online to use it to be able to send morse code from the serial port on my computer using putty. Putty is a nice piece of free serial terminal software. The output power is very low (easily measured in microWatts with a small antenna) but after some impedance matching and a amplifier stage you could easily use this for a nice HF beacon project. Here is the code if you want to try it for yourself:


//Has the ability to send morse code from the serial port

#define WPM 20
#define pttOut 13
#define pwmOut 5
#define toneFrequency 400  //Hz
#define W_CLK 8       // Pin 8 - connect to AD9850 module word load clock pin (CLK)
#define FQ_UD 9       // Pin 9 - connect to freq update pin (FQ)
#define DATA 10       // Pin 10 - connect to serial data load pin (DATA)
#define RESET 11      // Pin 11 - connect to reset pin (RST).
#define txfrequency 14015000

byte morseLookup[] = {
                      //Letters
                      B01000001,B10001000,B10001010,B01100100,B00100000,B10000010,
                      B01100110,B10000000,B01000000,B10000111,B01100101,B10000100,
                      B01000011,B01000010,B01100111,B10000110,B10001101,B01100010,
                      B01100000,B00100001,B01100001,B10000001,B01100011,B10001001,
                      B10001011,B10001100,
                      //Numbers
                      B10111111,B10101111,B10100111,B10100011,B10100001,B10100000,
                      B10110000,B10111000,B10111100,B10111110,B10111110,
                      //Slash
                      B10110010
                    };


void setup(){
  Serial.begin(9600);
  Serial.print("Loading...");
  pinMode(pttOut,OUTPUT);
  pinMode(pwmOut,OUTPUT);
  pinMode(4,OUTPUT);
  digitalWrite(4,LOW);
  pinMode(3,OUTPUT);
  digitalWrite(3,HIGH);
  setupDDS();
  delay(500);
  Serial.println(" complete");
}

void loop(){
  if(Serial.available()){sendSerialMessage();}
  transmitString("73 de N1QQ");
  delay(5000);
  transmitString("QST de N1QQ");
  delay(5000);
}

// transfers a byte, a bit at a time, LSB first to the 9850 via serial DATA line
void tfr_byte(byte data)
{
  for (int i=0; i<8; i++, data>>=1) {
    digitalWrite(DATA, data & 0x01);
    pulseHigh(W_CLK);   //after each bit sent, CLK is pulsed high
  }
}

void sendFrequency(double frequency) {// frequency calc from datasheet page 8 = <sys clock> * <frequency tuning word>/2^32
  int32_t freq = frequency * 4294967295/125000000;  // note 125 MHz clock on 9850
  for (int b=0; b<4; b++, freq>>=8) {
    tfr_byte(freq & 0xFF);
  }
  tfr_byte(0x000);   // Final control byte, all 0 for 9850 chip
  pulseHigh(FQ_UD);  // Done!  Should see output
}

void pulseHigh(int pin){
  digitalWrite(pin, HIGH);
  digitalWrite(pin, LOW);
}

void setupDDS(){
  pinMode(FQ_UD, OUTPUT);
  pinMode(W_CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(RESET, OUTPUT);
  pulseHigh(RESET);
  pulseHigh(W_CLK);
  pulseHigh(FQ_UD);  // this pulse enables serial mode - Datasheet page 12 figure 10
}

void sendSerialMessage(){
  delay(10);
  char message[64];
  int length = 0;
  
  while(Serial.available() && length < 64){
    message[length] = Serial.read();
    length++;
    message[length] = '\0';
  }
   transmitString(message);
}

void transmitString(char* message){
  for(int i = 0; message[i] != '\0'; i++){
    Serial.print(message[i]);
    transmitChar(message[i]);
  }
  Serial.println();
  wordSpace();
}

void transmitChar(char character){
  int lookupValue;
  if(character > 64 && character < 91){  //Capital Letter (0-25)
    lookupValue = character - 65;
  }
  else if(character > 96 && character < 123){  //Lower Case Letter (0-25)
    lookupValue = character - 97;
  }
  else if(character > 47 && character < 58){   //Number (26-36)
    lookupValue = character - 48 + 26;
  }
  else if(character == 47){  // slash (37)
    lookupValue = 37;
  }
  else if(character == 32){  // space
    wordSpace();
    return;
  }
  else{
    return;  //Invalid Character
  }
  byte length = (morseLookup[lookupValue] & B11100000) >> 5;
  byte pattern = morseLookup[lookupValue] & B00011111;
  byte mask = 1 << length-1;
  for(int i = 0; i < length; i++){
    if(mask & morseLookup[lookupValue]){
      dash();
    }
    else{
      dot();
    }
    mask = mask >> 1;
  }
  charSpace();
}

void dot(){
  digitalWrite(pttOut,HIGH);
  sendFrequency(txfrequency);
  tone(pwmOut,toneFrequency);
  delay(1200/WPM);
  digitalWrite(pttOut,LOW);
  sendFrequency(0);
  noTone(pwmOut);
  delay(1200/WPM);
}

void dash(){
  digitalWrite(pttOut,HIGH);
  sendFrequency(txfrequency);
  tone(pwmOut,toneFrequency);
  delay(3 * 1200 / WPM);
  digitalWrite(pttOut,LOW);
  sendFrequency(0);
  noTone(pwmOut);
  delay(1200 / WPM);
}

void charSpace(){
  delay(2 * 1200 / WPM);
}

void wordSpace(){
  delay(7 * 1200/WPM);
}

Homemade ECG machine using infrared

N1QQ Arduino ECG Machine phototransistor Scott Harden Tyler Pattison

Some interesting projects that I recently found online showed people using infrared phototransistors and op-amps to build basic light-based ECG machines. I thought that I'd try it for myself just to see how well it would work. It was certainly interesting to build this little circuit on a breadboard. Perhaps I'll build on this design in the future, but I havn't done so yet. The output signal is a bit noisy, but using an Arduino as an A/D converter I was able to capture my heartbeat and convert it into audio using Goldwave. This design was based on a circuit posted by Scott Harden.


Bench Power Supply Part 2

Now that I've got my specs figured out, it's time to start some high level design. This will allow me to get the layout of the power supply set before diving into the small details. Hopefully this will make the design process more efficient. One of the biggest things that will affect this high-level design is one particular design specification. That is, the call for a switching knock-down stage. The reason I chose to include this is efficiency. Many lab power supplies I've seen out there have one thing in common: Many of them use linear regulators like the LM7805 or LM317. These are good devices, but they all have very low efficiency, especially when the dropout voltage is high. Enter switching regulators. Switching regulators can have very high efficiency (upwards of 95%) which allows for higher current handling, and less heat dissipation. However, they have a drawback. Switching regulators typically have more noise on their outputs. They may be OK for some circuitry, but this inherent noise will not do for the lab power supply I intend to build. To get the best of both worlds, I plan to use both types of regulators in my design. The switching regulator will take care of most of the voltage dropout first, while leaving about 2-3 volts for the non-switching (a.k.a. linear) portion to drop second. This will reduce power dissipated in the non-switching section of the power supply, which has numerous advantages, including (hopefully) eliminating the need for a noisy fan, as I'd like to make this thing as small, quiet, and cool as possible. This would definitely not be possible without the switching section in front. Now, it's time to make some initial part choices:

Parts List:

  • Linear Output transistor: P-Channel MOSFET IRF9540
  • Switching Regulator: LM2679-ADJ
  • Switching Regulator Inductor: Digikey# 553-1121-ND
  • Switching Regulator Capacitor: Digikey# P15372CT-ND
  • Current Sensor: ACS712

This should help lay the groundwork of the power supply. Next we'll look at putting in some control circuitry, including op-amps and so on...


Bench Power Supply Part 1

Graduation is on the horizon, and I've spend too many years using wall-warts as my primary bench power supplies. I'm ready to finally build something I can be proud to have on my bench. So, I'm setting out to build a really high quality bench power supply. Every good project starts with a list of goals and in this case that means setting the specifications for my power supply. I think it's good design practice to decide what you seek to accomplish before you spend too much time designing. So, without further delay, here are the initial specs that I'll be designing to. Design Specifications:

  • Dual Floating Outputs
  • Adjustable Voltage, 0-30V, Steps of 10mV
  • Adjustable Constant Current 0-5A, Steps of 1mA
  • Soft output On/Off Switches (Default: OFF)
  • Output On/Off Indicator LEDs
  • OLED Text Display
  • Voltages/Currents set with single rotary encoder
  • Serial Computer Interface (Read/Set Voltage/Current)
  • High power efficiency, switching knock-down stage, regulated final stage
  • ICSP Header for firmware updates
  • Made from low cost parts

Now that the specs have been written down, I'll begin designing the circuitry. Stay tuned for part 2.


View All Posts