The start of a hacker-friendly weekend

It’s winter and I’ve gotten a little lazy about hiking. My list of “must-hike” has shrunk and my list of “must-build” has grown… a lot. So this weekend I’ll be strapped to the bench checking out all the items I’ve gotten in the mail and then picking something to work on.

I don’t know what the normal electronics/software engineering personal “blog” gets for hits, and I imagine it has a lot to do with level of content and frequency of updates? My content level is medium-low (compared to blogs such as absorbtions) but I think I do a decent job of updating the last 8 or 9 months I’ve blogged? Wednesday, while at work, I got a weird noise out of my phone I’d never heard. I took a quick peek at my phone and it was WordPress declaring I had a very high peak of abnormal traffic. Well… it wasn’t kidding. Dangerous Prototypes latched on to my last post. I’m guessing they must get a considerable amount of traffic considering the amount of traffic they pushed to my site despite it being a topic I’d find rather niche. My typical traffic is the occasional google search leading someone new trying to get some feature of a PIC to work. Well anyways, the photo says it all.

That's not a normal week!
That’s not a normal week!

.. so back to the bench!

PIC 16F1509 NCO code sample

I didn’t read a forum post all the way through (or maybe I was just tired) and I accidentally responded to question about PWM; however the question was specifically about using the numerically controlled oscillator (NCO). I decided to take a look at this module and wrote some quick code. I also have been testing hardware for isolating PWM signals… so I married them together despite not being how I would use this in a real world application.

The NCO code worked great and was easy to set up. I used a simple loop to have it sweep a frequency… dumped the output of NCO1 (RC1) into a optoisolator which originally I was driving it way to fast… well unfortunately my isolation circuitry wasn’t quite up to the challenge of the speed but in the lower end of my sweep I got adequate results and ultimately the NCO test was very successful. While I was reading up on the NCO in the 16F1509 manual I started reading the configurable logic cell (CLC) module section. What a surprise to find this block in a 16F series microcontroller! The CLC is definitely going to get some more attention from me in the future. As always sample code follows below…

 

I had answered a question about a PWM signal a while back and responded with some PWM code ... well I didn't read it all and they were wanting to use NCO. I hadn't used it... so I just hacked some stuff together to check it out.
I had answered a question about a PWM signal a while back and responded with some PWM code … well I didn’t read it all and they were wanting to use NCO. I hadn’t used it… so I just hacked some stuff together to check it out.

 

So the important stuff! The code written for the Microchip XC8 compiler:

No warrantee and don’t assume it’s free of bugs. It free to steal; enjoy. Code fix recommendations in the comments please.

Download: 16F1509_NCO.c

* File: main.c
 * Author: Charles M Douvier
 * Contact at: http://iradan.com
 *
 *
 * Target Device:
 * 16F1509 on Tautic 20 pin dev board
 *
 * Project:
 *
 *
 * Version:
 * 1.0
 *
 */
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 4000000 //4Mhz FRC internal osc
#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
#endif
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//config bits
#pragma config FOSC=INTOSC, WDTE=OFF, PWRTE=OFF, MCLRE=ON, CP=OFF, BOREN=ON, CLKOUTEN=OFF, IESO=OFF, FCMEN=OFF
#pragma config WRT=OFF, STVREN=OFF, LVP=OFF
#define _XTAL_FREQ 4000000 //defined for delay
int count;
/*
 *
 *
 *
 * NCOxCON: NCOx CONTROL REGISTER
 * bit 7 NxEN: NCOx Enable bit
 * 1 = NCOx module is enabled
 * 0 = NCOx module is disabled
 * bit 6 NxOE: NCOx Output Enable bit
 * 1 = NCOx output pin is enabled
 * 0 = NCOx output pin is disabled
 * bit 5 NxOUT: NCOx Output bit
 * 1 = NCOx output is high
 * 0 = NCOx output is low
 * bit 4 NxPOL: NCOx Polarity bit
 * 1 = NCOx output signal is active low (inverted)
 * 0 = NCOx output signal is active high (non-inverted)
 * bit 3-1 Unimplemented: Read as ‘0’
 * bit 0 NxPFM: NCOx Pulse Frequency Mode bit
 * 1 = NCOx operates in Pulse Frequency mode
 * 0 = NCOx operates in Fixed Duty Cycle mode
 *
 * NCOxCLK: NCOx INPUT CLOCK CONTROL REGISTER
 * bit 7-5 NxPWS<2:0>: NCOx Output Pulse Width Select bits(1, 2)
 * 111 = 128 NCOx clock periods
 * 110 = 64 NCOx clock periods
 * 101 = 32 NCOx clock periods
 * 100 = 16 NCOx clock periods
 * 011 = 8 NCOx clock periods
 * 010 = 4 NCOx clock periods
 * 001 = 2 NCOx clock periods
 * 000 = 1 NCOx clock periods
 * bit 4-2 Unimplemented: Read as ‘0’
 * bit 1-0 NxCKS<1:0>: NCOx Clock Source Select bits
 * 11 = NCO1CLK pin
 * 10 = LC1_out
 * 01 = FOSC
 * 00 = HFINTOSC (16 MHz)
 * Note 1: NxPWS applies only when operating in Pulse Frequency mode.
 * 2: If NCOx pulse width is greater than NCO_overflow period, operation is undeterminate.
 *
 */
int main(void) {
 // set up oscillator control register, using internal OSC at 4MHz.
 OSCCONbits.IRCF = 0x0d; //set OSCCON IRCF bits to select OSC frequency 4MHz
 OSCCONbits.SCS = 0x02; //set the SCS bits to select internal oscillator block
 OPTION_REGbits.nWPUEN = 0; // enable weak pullups (each pin must be enabled individually)
TRISCbits.TRISC0 = 0; // output
 TRISCbits.TRISC1 = 0; // NCO1
 TRISCbits.TRISC2 = 0; // output
 TRISCbits.TRISC3 = 0; // output
 TRISCbits.TRISC6 = 1; // input
 TRISCbits.TRISC7 = 1; // input
ANSELC = 0x00; // all port C pins are digital I/O
NCO1INCH = 0x00; // has to be set before INCL
 NCO1INCL = 0x4F; // low accumulator register
NCO1CLK = 0xE1; // 0xE1 = PW 128 clk 0x41 [010][000][01] 8 CLK PER, INT OSC,
 NCO1CON = 0xE1; // Enable, Ouput On, PWF Mode
count = 0;
while(1)
 {
 count = count+1; //just a little test code
 if (count < 1) //LED didn't like the low freq
 count=10;
 NCO1INCH = 0x00; //has to be set before INCL
 NCO1INCL = count;
 __delay_ms(50);
 }
 return (EXIT_SUCCESS);
}

	

My Electronics Read&View List

My current electronics-related online reading/viewing list:

Please comment if you have some great additions! I was (and may consider in the future) rating all the sources based on my own opinion, but I decided against it in case I hurt some feelers.

Full disclosure: My interests are mid-level hobbyists projects, test equipment and tutorials/code examples. In the realm of digital electronics I primarily use microchip based mid-range microcontrollers and I’m most knowledgeable with the 14-bit cores. (think 12F, 16F MCUs) I have some interest in expanding to the MSP430 based MCUs and doing something other than practicing coding in python on my Raspi. I have no interests in Arduino besides admiring someone else’s hard work and deciding if I could do it on a different platform. I started with assembly on the RCA CDP1802 and it’s a hard habit to break. I’ve made a new years resolution to code in C as much as possible this year. I also have a fondness for analog and RF electronics; I was a broadcast engineer for sometime and I feel analog electronics are more challenging than 1’s and 0’s. My interests weigh greatly on how I rate my interest level in electronics blogs as should yours.

vlogs

http://www.youtube.com/user/w2aew/featured some of the best tech videos on youtube
http://www.youtube.com/user/whisk0r TYMKRS, basic electronics, a lot of music based stuff…
http://www.youtube.com/user/TheLonghornEngineer/featured
http://www.youtube.com/user/thebenheckshow/featured The Ben Heck Show
http://www.youtube.com/user/I8U2Astromech/featured  Brad Oakley (Made an R2D2)
http://www.youtube.com/user/weirdocollector/featured  Weirdocollector Crafts (makes Z80-based microcomputers)
http://www.youtube.com/user/IanScottJohnston/featured
http://www.youtube.com/user/TheSignalPathBlog/feed usually tear-downs
http://www.youtube.com/user/gezzasw/featured Gerry Sweeney (Hobbyist), long videos but in depth
http://www.youtube.com/watch?v=S6LFp_EM5SU Frozen Electronics, very basic..

blogs, etc

http://hackaday.com Hack A Day, no original content, just articles
http://eevlog.com a lot of content here, a lot of reviews which I’m not really interested in
http://dangerousprototypes.com/  Open Source Projects
http://hackedgadgets.com/
http://hackersbench.com/ John promises to start on this shortly; This site has some content but it likely to have a lot of great content in the near future.
http://www.therengineer.com/
https://trandi.wordpress.com/ low on depth
http://www.martinmelchior.be/
http://www.rrkb.lv/musings/ not updated often, low on content
http://runawaybrainz.blogspot.com/
http://www.baldengineer.com/
http://www.tinkerhobby.com/
http://tronixstuff.com/
http://anthony.liekens.net/
http://www.eevblog.com/forum/projects/
http://www.kerrywong.com/ One of the best hobbyist blogs out there
http://www.fringeneering.com/ not a huge amount of electronics but interesting
http://gerrysweeney.com/category/electronics/
http://www.circuitsathome.com/
http://smokedprojects.blogspot.com/
http://kevinrye.net/ a personal favorite
http://mightyohm.com/blog/
http://www.theamphour.com/ (podcast with some posting info)
http://www.vk2zay.net/
http://retrointerfacing.com/
http://homepage.cs.uiowa.edu/~jones/ (static)
http://www.kukata86.com/
http://www.evilmadscientist.com/
http://www.microchipc.com/
http://embedded-lab.com/blog/
http://www.g4ilo.com/
http://www.ka7oei.com/

Testing an LCD with the PIC 16F1509 and the XC8 compiler

Nuts and Volts, January 2014 had an article named “The (Nearly) Universal Process Monitor”. The whole magazine had a number of Microchip PIC based articles which is rare these days, as the articles win out to other platforms such as MSP430, Propeller, and Arduino. The article is a pretty nice project but I went to download the code and it’s just a HEX file. Lame! I’ve been guilty of this and I promise never to do it again.

If you’re as disenchanted with building something without modifiable code as I am here is a starting block! I don’t normally program in C but I’m trying to force myself so I can get better. You can trim down many timing delays, and certainly shouldn’t be a problem to optimize my code as I made no effort to do so myself.

LCD+A/D test on the PIC

 

When writing the A/D math for this I found some interesting issues; here is one of those: (in pseudo code)

int_Var1 = 8-bit A/D conversion
long_int_Var2 = int_Var1 * 5000

given int_Var1 = 17  long_int_Var2 should equal 85000 but it didn’t; It came out 19,464 (roll over from 65,536).

However:

long_int_Var2 = int_Var1
long_int_Var2 = long_int_Var2 * 5000  //works like a charm.

Weird? I tried this in an ANSI C compiler and the first equation worked okay; I guess this is just a quirk about XC8. I somewhat understand why it would act that way and caught it quick but it could easily have been a difficult bug to hunt down.

There is obviously not the greatest amount of resolution in an 8-bit conversion but I was really just testing an LCD I just got off eBay and through this would be a fun way to do so, work on my C skills, and help out anyone wanting a head-start on building their own metering application. If you don’t want to do the math yourself you’ll find you get about 20mV/step resolution (5000mV/256) at 8-bit.

 

The thousands position is moot and could be dropped. The resolution of the A/D being used in 8-bit doesn't allow for reliable usage in the thousandths.
The thousands position is moot and could be dropped. The resolution of the A/D being used in 8-bit doesn’t allow for reliable usage in the thousandths.

 

Notes: Refresh is slow, clearing the LCD line #2 is slow because I didn’t like the flash of clearing the whole display… it could have also been made more quick had I not written 16 spaces and just written enough to cover my 7 digits of output. I also should have dropped the LSB of my number because it’s a worthless bit considering my resolution. I will if this gets used on anything other than a breadboard test.

I used a standard 44780 16×2 LCD, a Tautic development board, and a PIC 16F1509 (happens to come with the dev board). For programming I used MPLAB X IDE v1.95 and XC8 v1.21 (free version) and the PICkit 3 programmer. The code is commented enough to figure out the hardware setup.

code (with whatever fixes since wiring the blog) can be found at : https://github.com/chasxmd/iradan.com-2014

at writing it looks like:

/* 
 * File: main.c
 * Author: Charles M Douvier
 * Contact at: http://iradan.com
 *
 * Created on January 18, 2014, 9:42 AM
 *
 * Target Device:
 * 16F1509 on Tautic 20 pin dev board
 *
 * Project:
 * A/D --> LCD Test
 * 8-bit resolution across Vdd to Vref (0-5V)
 * for 3.3V operation adjust A/D math
 *
 * LCD (44780 type) Test with XC8 compiler
 * LCD code ported from Mike Pearce's 2001 LCD code for HI-TECH C
 * as found on http://www.microchipc.com/
 */
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <plib.h>
//config bits
#pragma config FOSC=INTOSC, WDTE=OFF, PWRTE=OFF, MCLRE=ON, CP=OFF, BOREN=ON, CLKOUTEN=OFF, IESO=OFF, FCMEN=OFF
#pragma config WRT=OFF, STVREN=OFF, LVP=OFF
#define _XTAL_FREQ 4000000 //defined for delay
int an9_value; //value for a/d
 char buf[10]; //buff for iota
 long int fvar; //long for format math
 long int ones; //left of decm
 long int decm; //decimal places
 int tempi; //to add leadign zeros..
/*
 * LCD RS LATA.5
 * LCD EN LATA.4
 * LCD DATA4 LATC.0
 * LCD DATA5 LATC.1
 * LCD DATAT6 LATC.2
 * LCD DATA7 LATC.3
 * LED LATA.0 for scan rate/heartbeat
 */
void lcd_strobe (void) //TOGGLE LCD_EN
{
 LATAbits.LATA4 = 0;
 __delay_ms(20);
 LATAbits.LATA4 = 1;
}
/* write a byte to the LCD in 4 bit mode */
void lcd_write(unsigned char c)
{
 LATC = c >> 4;
 lcd_strobe();
 LATC = c;
 lcd_strobe();
 __delay_us(100);
}
/*
 * Clear and home the LCD
 */
void lcd_clear(void)
{
 LATAbits.LATA5 = 0;
 lcd_write(0x1);
 __delay_ms(2);
}
/* write a string of chars to the LCD */
void lcd_puts(const char * s)
{
 LATAbits.LATA5 = 1; // write characters
 while(*s)
 lcd_write(*s++);
}
/*
 * Go to the specified position
 */
void lcd_goto(unsigned char pos)
{
 LATAbits.LATA5 = 0;
 lcd_write(0x80+pos);
}
/*
 * Write 16 spaces on LCD 2 to avoid blanking, (ugly CLEAR effect)
 * this is slow but work for my needs
 */
void lcd_clrline2(void)
{
 lcd_goto(40);
 lcd_puts(" ");
 lcd_goto(40);
}
/* initialise the LCD - put into 4 bit mode */
void lcd_init(void)
{
 LATAbits.LATA5 = 0; // write control bytes
 LATC = 0x03;
 __delay_ms(150); //power on delay
 lcd_strobe();
 __delay_ms(5);
 lcd_strobe();
 __delay_ms(5);
 lcd_strobe();
 __delay_ms(5);
 LATC = 0x02; // set 4 bit mode
 __delay_ms(5);
 lcd_strobe();
 __delay_ms(5);
 lcd_write(0x28); // 4 bit mode, 1/16 duty, 5x8 font
 lcd_write(0x08); // display off
 lcd_write(0x0C); // display on cursor+blink off
 lcd_write(0x06); // entry mode
}
int main(void) {
 // set up oscillator control register, using internal OSC at 4MHz.
 OSCCONbits.IRCF = 0x0d; //set OSCCON IRCF bits to select OSC frequency 4MHz
 OSCCONbits.SCS = 0x02; //set the SCS bits to select internal oscillator block
TRISCbits.TRISC0 = 0; // output
 TRISCbits.TRISC1 = 0; // output
 TRISCbits.TRISC2 = 0; // output
 TRISCbits.TRISC3 = 0; // output
 TRISAbits.TRISA0 = 0; // output
 TRISAbits.TRISA4 = 0; // output
 TRISAbits.TRISA5 = 0; // output
 TRISCbits.TRISC7 = 1; //analog input
 ANSELCbits.ANSC7 = 1; //...setup on PORTC.7/AN9
 LATAbits.LATA0 = 0; //LED Im-Alive test
__delay_ms(250); //let the power settle
lcd_init();
 __delay_ms(10);
 lcd_clear();
//display test message
 lcd_puts("Testing the LCD.");
 lcd_goto(40);
ADCON0 = 0b00100101; //select AN9 and enable
/* ADCON1
 * bit 7 ADFM: ADC Result Format Select bit
 * 0 = Left justified. Six Least Significant bits of ADRESL are set to ?0? when the conversion result is loaded.
 * bit 6-4 ADCS<2:0>: ADC Conversion Clock Select bits
 * 110 = FOSC/64
 * bit 3-2 Unimplemented: Read as ?0?
 * bit 1-0 ADPREF<1:0>: ADC Positive Voltage Reference Configuration bits
 * 00 = VREF+ is connected to VDD
 */
 ADCON1 = 0b01100000; //left justified, FOSC/64 speed Vref=Vdd
while(1)
 {
 LATAbits.LATA0 = 0; //debugging

 lcd_clrline2(); //clear LCD line 2 by writting " " and return
__delay_us(5); 
 GO = 1;
 while (GO) continue; //wait for conversion
 an9_value = ADRESH; //AN9 value
 //format value for LCD read out
 //value = AD_value * 5000 (because 5000mV is Vref)
 //value = value / 256 (8 bit number)
 fvar = an9_value;
 fvar = fvar * 5000;
 fvar = fvar / 256;
 ones = fvar / 1000;
 ones = ones % 10;
 decm = fvar % 1000;
LATAbits.LATA0 = 1; //LED Im-Alive test. I made it through conversion
//page 366 of XC8 user guide
 itoa(buf,ones,10); //int conv to buffer
 lcd_puts(buf); //outputs "1s" place to LCD.
 lcd_puts(".");
 //page 374 of XC8 user guide
 ltoa(buf,decm,10); //long conversion to buffer
 tempi=strlen(buf); //uh, adding leading zeros..
 tempi=3-tempi; //probably a better way of doing thing
 while (tempi) //first figure out how many zeros
 {
 lcd_puts("0"); //missed 3-string length
 tempi=tempi-1; //then send them until done
 }
 lcd_puts(buf); //output buffer to LCD
lcd_puts(" V"); //attach some units for display
 //delay
 __delay_ms(999); //LCD refresh rate
 }
 return (EXIT_SUCCESS);
}

MC1377 Memories

My first working circuit that I designed was based on the Motorola MC1377. It’s a RGB to NTSC encoder. I am pretty certain I actually still have the chip stored away in my linear/analog microchip parts storage. Apparently they are still available NOS on eBay. I can’t claim that I designed it myself; I’m certain my best friend of the time, Jason G., likely had assisted and designed some of the circuit. At the very least he had a lot of input. It was decades ago, who has that kind of memory? Jason had gotten me interested in “the best” computer of the time. The Amiga 500. I don’t know if it was the best home computer of the time but it certainly was in front of the pack. A powerfully Motorola 68000 and color computing when the 8088 just got 4-color CGA! The Amiga had been around for a while why I bought mine; Long enough for me to buy a refurbished A500 from a commodore shop in north Kent/Tukwila, WA. Jason stayed overnight and we stayed up until the single digits of the morning building this circuit because I had not  yet saved enough money to buy the A 1084S monitor… the time had come.. my carpet sporting an extra burn mark from a soldering iron. I was 15 or 16 at the time and I usually soldered on the floor, there were already a number of burn marks by then. We powered up the circuit and plugged it into the Amiga and then my TV… Success! Well kind of.. everything was very purple but the output was perfectly usable. The start of my love affair with Amiga computers and a further solidification of my primary hobby; electronics.

I’m off to LA for some training this week. Hopefully I get some programming done on my projects. I brought a small “go bag” of electronics for out-of-town work. Hopefully the TSA doesn’t give me too much trouble. I’m sure a bag of electronics is a scary thing for those who don’t know what they’re looking at.

..workbench chatter

Melissa and I have been out of town for a little while. I was hoping to blog on the road but it just didn’t happen. That midwest weather is in a nasty way; I don’t miss winter weather at all. So I have a little more work on two posts I’m working on but I wanted to update the blog for if no one else myself. I need a little brain purge… I have a lot of stuff to work on.

When I got home I had a dozen and a half packages or so from China. A ton of fun stuff.. most of it was for the little robot I’m working on. I also brought back a ton of stuff from my house (in a storage room) that I have left behind.

On our travel across county we stopped by our house in South Dakota and picked up a bunch of our items in storage. I brought back a few boxes of miscellaneous electronics including a lot of older projects I built years ago.
On our travel across county we stopped by our house in South Dakota and picked up a bunch of our items in storage. I brought back a few boxes of miscellaneous electronics including a lot of older projects I built years ago.

 

Look at that pile of stuff! A part of one box of old projects I built. Only a few more boxes to go! I got excited about a bunch of copper clad board that turned out to be really cheap; lame!

While out of town a mailbox and a half of sensors arrived from China (eBay)! Time to get building.
While out of town a mailbox and a half of sensors arrived from China (eBay)! Time to get building.

 

Sensors! I guess it’s time to get building. I’m not sure what I’ll use.. I’ll just tinker around until I find what I like.

So I've etched PCBs by sharpie.. I've used the tape and stencils... even photo etching which provided decent results. With all the talk in the IRC chat room I finally decided I needed to try out this professionally built business.
So I’ve etched PCBs by sharpie.. I’ve used the tape and stencils… even photo etching which provided decent results. With all the talk in the IRC chat room I finally decided I needed to try out this professionally built business.

 

“My first PCB”… that I didn’t etch myself. The white stencil isn’t right but I knew it would be that way and I was in a hurry to get it on the way. It looks great. I haven’t checked out all the circuit paths but everything looks good. I decided on OSH Park because he is local-ish and seems like a decent guy. The preview feature is nice on his site.. and the price was reasonable. (yeah, I know.. it’s just a proto-board.. I didn’t build it for any specific reason).

Check out the motor controller heatsink!
Check out the motor controller heatsink!

 

Finally I got these tiny heat sinks I ordered .. (look at the motor controller on the robot platform). The motor controller is the same one I used for my Roomba Sumobot… it got very hot a few times I’m hoping to avoid those issues this time around with this heatsink that comes with some sticky stuff that hopefully conducts heat well. It was a 10 pack.. pretty cheap.

That’s it! I need to get along with my other posts…next week I’m out-of-town for training; maybe I’ll get something done then? 🙂

%d bloggers like this: