Ages and ages ago, I posted this and many people said they’d like a guide. So here it is!
This is a guide for making an LCD that connects to your computer using USB, primarily intended to be external. You can see mine here. To make the board smaller, it doesn’t have the GPOs.
This thread should also be used for suggestions on how to improve the circuit, add new features, and fix bugs in the firmware.
Note that I’ve used a transistor for the buzzer, so you can connect someting else there instead… mod on!
The connection to the rotary encoder works like this: (diagram)
Pin 2 on encoder goes to pin 1 on J2
Pin 3 on encoder goes to pin 2 on J2
Pin 5 on encoder goes to pin 3 on J2
Pins 1 and 4 on encoder go to pin 4 on J2
Installing in Windows
XP/2000: Download this to your desktop and tell Windows to use that as a driver when it asks.
Vista 64-bit: see scorpia’s post
I think Vista 32-bit works with the XP/2000 method, I’m not sure though.
This is the required programmer config (assuming 4MHz crystal). The USB voltage regulator is critical, as the PIC won’t even try to start up without it.
For quite some time I’ve been wanting to create a device that outputs VGA signals. My main goal was of course to be able to display whatever I wanted on the monitor I was currently using.
After extensively researching to see if this project had previously been attempted (or anything similar) I became very frustrated to find little information on the topic. So I decided to go ahead and expand on the information I did find and do this project for a computer interface circuits class I was taking.
The finished product looks kind of odd because of the wooden enclosure, however it serves its purpose as a ‘Test Box’.
Purpose & Overview of this project
The goal of this project is to create a device that is capable of outputing VGA signals to a CRT monitor inorder to display figures, text and characters.
Timing is a core essential in this project. If the signal is off by even 1 microsecond, the signal synchronization with the CRT display will be lost and forced to resync.
This will be done using a Microchip PIC microcontroller at 4 MHz clock speed. The programming required to achieve the VGA timing signals must be done in low level assembly because of the high level of precision that is necessary. The hardware assembly is just basic buttons, switches & wire that you can purchase from local electronics stores.
Several automated and semi-automated devices require a message to be displayed in order to indicate their working status. In continuation to LCD interfacing with PIC18F4550, this article explains how to display a message or string on a 16×2 character LCD.
In the previous article, a single character was displayed on LCD by properly configuring its data and command registers. A string is nothing but a sequential arrangement of several characters that can be displayed on LCD by using the programming steps mentioned here. The circuit connections and user-defined functions are same as earlier. The LCD data pins are connected to PortB of PIC18F4550 while the control pins are connected to first three pins of PortA.
Programming steps:
· Configure the LCD.
· Store a string in a character array.
unsigned char data[20]=“EngineersGarage”;
· Run a loop till the loop counter encounters the null character ‘\0’ of the string.
· Use lcddata() function to send individual character values of the string to be displayed on LCD.
This PIC16F877 microcontroller tutorial answers the question,
“How to interface LCD[1] in 4bit mode with PIC16F877″ ?
Also, using PIC16 simulator (Proteus) you can verify this LCD code and change it according to your needs. This code is written in C language using MPLAB with HI-TECH C compiler. You can download this code from the ‘Downloads‘ section at the bottom of this page.
It is assumed that you know how to blink an LED with PIC16F877 microcontroller. If you don’t then please read this page first, before proceeding with this article.
The following diagram (made in Proteus) shows the PIC microcontroller circuit diagram.
In the above figure, RB0 pin is being used as Enable pin for LCD. RB1 pin is used as RS pin and PORTB (RB4 to RB7) pins are used as Data bus for the LCD. When code starts running then ‘Hello World!‘ is displayed on the LCD.
Code
The code for the main function is shown below.
Downloads
LCD interfacing code using PIC16F877 was compiled in MPLAB v8.85 with HI-TECH C v9.83 compiler and simulation was made in Proteus v7.10. To download code and Proteus simulation click here.
This post provides a simple digital clock implementation using PIC16F84A microcontroller and an LCD display. This code is written in C language using MPLAB with HI-TECH C compiler. You can download this code from the ‘Downloads‘ section at the bottom of this page.
In this article, it is assumed that you know,
How to interface LCD with PIC16F84A microcontroller. If you don’t then please read this page.
How to configure timer0 of PIC16F84A microcontroller. If you don’t then please read this page.
The result of simulating the code in Proteus is shown below.
The above figure was taken after 1 minute and 6 seconds of code simulation in Proteus. In the code, timer0 is used as the base for digital clock generation. Timer0 is used here to generate 1msec interrupts. After every 1msec a global variable named msCounter increments. When msCounter reaches a value of 1000 then another global variable named secCounter increments and this process repeats itself. Similarly, when secCounter reaches 60, then minCounter increments. And when minCounter reaches 60 then hrCounter increments. This process continues until hrCounter reaches 24 then all of these variables reset their values. LCD is updated with the new values of hrCounter, minCounter and secCounter after every second.
A crystal of 4MHz value is used in this circuit, which makes this PIC16F84A run at a speed of 1MIPS (Million of instructions per second).
Code
The main function code is shown below.
In the main function, firstly LCD is initialized using InitLCD() function. Then Timer0 is initialized to generate 1msec interrupts. After that, in the while(1) loop, whenever msCounter reaches a value of zero[1], then new values of hrCounter, minCounter and secCounter are updated on the LCD. UpdateTimeCounters() function is called every time and it corrects the values of every counter variable depending upon the value of msCounter, which is incremented in the ISR function of timer0 (shown below).
Downloads
Digital clock display code using PIC16F84A was compiled in MPLAB v8.85 with HI-TECH C v9.83 compiler and simulation was made in Proteus v7.10. To download code and Proteus simulation click here.
This post provides the LCD[1] interfacing code using PIC16F84A microcontroller. This code is written in C language using MPLAB with HI-TECH C compiler. You can download this code from the ‘Downloads‘ section at the bottom of this page.
It is assumed that you know how to make an LED blink with PIC16F84A microcontroller. If you don’t then please read this page first, before proceeding with this article.
LCD interfacing circuit with PIC16F84A is shown below.
In the above figure, RA0 pin is being used as Enable pin for LCD. RA1 pin is used as RS pin and PORTB is used as Data bus for the LCD. When code starts running then Hello is displayed on the LCD.
Code
In the code you can easily select pins to be used for interfacing with the LCD. Following figure shows the pin selection code.
Downloads
LCD interfacing code using PIC16F84A was compiled in MPLAB v8.85 with HI-TECH C v9.83 compiler and simulation was made in Proteus v7.10. To download code and Proteus simulation click here.
This post provides a simple digital clock implementation using PIC12F675 microcontroller and an LCD display. This code is written in C language using MPLAB with HI-TECH C compiler. You can download this code from the ‘Downloads‘ section at the bottom of this page.
In this article, it is assumed that you know,
How to interface LCD with PIC12F675 microcontroller. If you don’t then please read this page.
How to configure timer0 of PIC12F675 microcontroller. If you don’t then please read this page.
The result of simulating the code in Proteus is shown below.
The above figure was taken after 1 minute and 13 seconds of code simulation in Proteus. In the code, timer0 is used as the base for digital clock generation. Timer0 is used here to generate 1msec interrupts. After every 1msec a global variable named msCounter increments. When msCounter reaches a value of 1000 then another global variable named secCounter increments and this process repeats itself. Similarly, when secCounter reaches 60, then minCounter increments. And when minCounter reaches 60 then hrCounter increments. This process continues until hrCounter reaches 24 then all of these variables reset their values. LCD is updated with the new values of hrCounter, minCounter and secCounter after every second.
Code
The main function code is shown below.
Downloads
Digital clock display code using PIC12F675 was compiled in MPLAB v8.85 with HI-TECH C v9.83 compiler and simulation was made in Proteus v7.10. To download code and Proteus simulation click here.
We designed a device that can aid in learning the alphabet in American Sign Language. We built a glove with various sensors to identify the hand position of the user closely and use that to give feedback on what they are doing right or wrong through the LCD display for each letter in the alphabet. The program detects how much the fingers are bent, contact between them, and hand orientation to determine this. The reason behind this project was to facilitate basic ASL learning for people that don’t necessarily need it, or may have someone in their lives with a hearing impairment. It means a lot when people that don’t have this difficulty learn or make an effort to learn ASL and facilitate communication, helping us to be more understanding and sensitive to those who don’t have the option of learning spoken languages.
High Level Design
The idea to do a project involving sign language began with an experience from one of the group members’ mom, who works as a social worker. She came across a college for the deaf, Gallaudet, which is partnering with Starbucks to open a signing only branch where all the baristas know sign language. People that don’t need sign language to communicate wouldn’t normally be inclined to learn it, so we thought it would be a good idea to design a device that can aid with learning sign language to increase accessiblility to those who speak it. The best way to learn is practice, so we decided to fashion a glove for our device and use various sensors to detect if the hand is in the correct position.
During the calibration state, the flex sensors measure the bend in 3 different position to set the thresholds for the states which are used to determine if each finger is bent enough for each corresponding letter. The first calibration step also sets the thresholds for the gyroscope and accelerometer to determine orientation and movement. The last component mounted on the glove are strips of copper tape used to detect contact, sending a high logical signal to the board indicating when 2 points make contact. The glove limits mobility a bit due to the large number of wire attached to it, which is a trade off for accuracy measuring accuracy. A cardboard box was also built to hold the components. The top level hold our board, with an opening to see the LCD display, while the bottom level contains the breadboard and the wires connected to the board. The top of the box also contains a button used to signal ready in the calibration stage, and a switch to go from learn mode to game mode and vice-versa.
Learn mode goes through the alphabet, and ensures the user holds the correct hand position for the corresponding letter for a second before moving to the next one, showing a picture of what it should look like and which parameter is not met, i.e. which finger is bent incorrectly, which axis to rotate the hand to get the right orientation, or wrong contact point. The game mode gives a time limit to get the correct hand position and keeps score of how many letters the user gets correctly, slowly decreasing the time limit.
Hardware Design
Our system takes includes a glove equipped with multiple sensors and a box housing our processor, display and buttons in order for the user to control the system. Below is an image of our final project.
The glove contains 3 different types of sensors in order for the processor to differentiate between the different signs. First we have 5 flex sensors sewn into the glove for each of the 5 fingers. These flex sensors change resitance in accordance with how much they are bent. Each sensor is also pulled down by a 100kOhm resistor in order to achieve ideal values for the adcThis is useful in determining if the user’s fingers are in the correct position.
Next, we have an IMU, specifically the MPU 6050 which communicates with the processor through i2c. We placed this device in the center of the back of the hand. This device detects absolute orientation in space as well as acceleration in 3 different axis. We use the orientation (the output from the accelerometer), to determine if the hand is facing the correct direction. We use the motion data (output from the gyroscope) to determine if the motions for the letters requiring a movement (j and z) are correct.
The last type of input we take from the glove is from copper tape attached to certain contact points. One piece of the tape is powered while the other is connect to a pulled down GPIO pin. When the two pieces touch, the pin goes high, making the tape act as a switch. We use these inputs to determine if certain fingers are touching in the right location. Below is a diagram of where we placed each of the pieces of copper tape.
These inputs then feed into our box which includes all hardware wiring inside as well as our development board. The development board houses the pic32 processor and the tft display. On top of the box we have mounted a button and a switch. The button starts the callibration sequence and the switch changes between the learn and play modes. Both the button and the switch are attached to pins that have internal pull-down resistors enabled via the pic32. A full diagram of the schematic can be found here.
Software Design
i2c_helper.h
This file was originally created by Desmond Caulley (dc686 @cornell.edu), Nadav Nehoran (nn233@cornell.edu), and Sherry Zhao (hz263@cornell.edu) for use with their self-balancing robot project. You can read more about their project via the link in the references. This file provides several functions for communicating with the IMU, including a function that returns all the accelerometer and gyroscope readings in an array. For our project, we didn’t need nearly as much sensitivity as this function provided. Therefore, our version of the function ignores the lower bits in the accelerometer readings. Other than this, nothing major has been changed.
sign_language_learner.c
On startup, the main function sets up the five ADC inputs, TFT display, IMU, input pins, and threads. It also calls the init_signs() function to add the data on all 26 signs to the sign array. Then, it initializes and schedules the four threads.
Sensors Thread
The Sensors Thread, protothread_sensors, is responsible for polling the sensor values and saving them. This thread runs every 120ms to ensure that the user receives prompt feedback and that quick motions are detected. The thread polls the contact points, IMU data, and all five ADC inputs. In addition to saving the raw ADC values, the thread also handles debouncing of each finger’s bend level. By requiring several consistent readings before altering the recorded bend, the program lowers the effect of noise.
Calibrate Thread
The Calibration Thread, protothread_calibrate, is used to calibrate the accelerometer and bend levels for the specific user. It is run automatically at startup, and can be run again at any time by pressing the “calibrate” button. It has three stages; each describes a hand position for the user to make and prompts them to press “calibrate” when ready. Then 20 samples of the current sensor data are taken.
Each position corresponds to a level of bend in the user’s fingers. Every finger is calibrated independently of the others to account for differences in how easy or far they can be bent. The ADC values from each sensor are recorded and averaged over all the readings to define the boundary points between the different levels of bend. These boundaries are used to determine the positions of the fingers during the learn and game modes.
In addition, the first calibration position requires the user to place their hand flat on the table in front of them, with their fingers pointed straight ahead. This is used to calibrate the accelerometer readings from the IMU. Since the user could be facing any direction, it’s necessary to calibrate each time to make sure their hand is facing the correct direction relative to their body. Once calibration is complete, the thread yields until “calibrate” is pressed again.
Learn Thread
The Learn Thread, protothread_learn, is used to run the logic for “learn” mode. This thread only runs when the switch is in the lower position and calibration is complete. When run, the thread displays a letter, an image of the correct hand position, and a pair of indicators. Below is an example of what the tft displays during the learn mode.
The first indicator is shaped like a hand; individual fingers turn red if they are incorrectly positioned, and white if they are correct. We chose to use the colors red and white because colorblind users would still be able distinguish them easily. Red dots on the fingers appear when a contact point at the indicated location is connected incorrectly. The second indicator, a circle with two lines through it, represents the hand’s orientation. If the x, y, or z orientation is incorrect, the corresponding line or circle turns red.
While a sign is being displayed, the thread checks the user’s hand position every 120ms. If the user is doing the sign correctly, a green circle will appear in the middle of the screen. An additional circle appears for every consecutive tick that the user is correct for; a mistake resets this. Once they reach five consistent readings, the sign is considered complete and the next letter in the alphabet is displayed.
To check if a sign is correct, the sign’s required bend levels are compared to the last recorded bend levels for each finger. The bend levels are defined as 0 (unbent), 1, and 2 (completely bent). Additionally, a finger position can be designated as “either 1 or 2”, which is useful for signs where the level of bend can vary while still appearing correct. Similarly, the contact point states and accelerometer values are compared to their ideal values. The accelerometer values have large deadbands (20 for x and y, 30 for z) to decrease the required level of accuracy while still rejecting signs that are blatantly wrong.
For signs that require a motion (j and z), more checks are hardcoded in. A single green circle will be displayed when the starting position is correct. After this, the gyroscope is used to detect a hand movement or rotation in the specified direction. For multi-stage motions, a timer gives the user 10 cycles to finish all movements, and an additional circle is added for each correct motion. Once the movement stops, the final orientation is checked; if it is correct, the sign is complete.
Game Thread
The Game Thread, protothread_game, is used to run the logic for “play” mode. This thread only runs when the switch is in the upper position and calibration is complete. The game thread works similarly to the learn thread, and uses the same functions to check if a sign is being formed correctly. However, there are a few differences.
First, the letters are displayed in a random order instead of alphabetically, and the pictures are not shown. This increases the difficulty for the player. However, the error indicators are still visible to prevent the game from becoming too frustrating due to the level of precision required for some of the signs. Secondly, there is a time limit for each sign. If the timer bar (displayed at the bottom of the screen) runs out before the sign is completed, the words “GAME OVER” are displayed. Three seconds after a game over, a new game starts. The timer starts at a little less than 10 seconds, and gets steadily faster as the game continues. Finally, the number of signs the player has correctly completed is displayed in the upper left hand corner of the screen as their score. An example of the tft during the game mode is shown below.
Results
Our final product was able to detect the hand gesture with fairly close accuracy to the standard ASL letters.
In learning mode, our device was able to give accurate feedback in regards to corrections that needed to be made to signal the letter correctly. The images displayed for each letter were very clear, and allowed the user to get a good understanding of what his/her hand should look like. All 26 letters of the alphabet were tested and worked properly, and the display showed any changes or adjustments made by the user as soon as they were made. The game mode successfully displayed a green bar shrinking to signal time left, as well keeping score of the letters correctly signaled and slowly decreasing the time given to signal correctly.
The only safety concern we had was a potential fire hazard by having the wiring inside a cardboard box. To deal with this, we made sure we covered all the bare wire connections with electrical tape to avoid heat conduction, particularly the push button and switch as they come in direct contact with the cardboard. No interference with other designs needed to be accounted for.
All members of the group were able to use this device. This device is particularly designed for people with hearing impairment, so all instructions are either displayed on the screen or written in the box completely avoiding the use of sounds as intended. However, the glove is only one size so it’s not user friendly to people whose hand size isn’t compatible with the glove. Conveniently, all members of our group have similar sized hands and were all able to use it.
Conclusion
After spending a month working on our sign language learner, we are very happy with the results. We can reliably detect if a sign is being used correctly and feel that anyone who uses our product would be able to learn the ASL alphabet. The user interface is easy to understand and interactive. If given the change to continue working on this project, here are a few improvements we would consider:
Improve checking of gyroscope values so the sign is recognized quicker.
Add a “free play” mode in which the user could sign freely and the letters would appear on the screen.
Include numbers and simple words or phrases to expand the systems capabilties.
Redesign the glove so that the natural movements of the user are less hindered and the product is more refined.
All code in our main file was implemented by us, with a few components taken from previous labs, like the setting of the adc parameters. The i2c_helper.h file was created by a previous ECE 4760 group and has been cited as such with a link in the references. Our design is also not reverse engineered from another design, so there are no intellectual property concerns there.
We are all interested in publishing a piece about our design, as we are very proud of our final result. We will consider submitting a piece for publishing to IEEE.
We have followed all portions of the IEEE code of ethics. All components on the glove have been properly insulated and do not pose a threat to the user or the public. While working on the project, we followed all safety guidelines of the lab inlcuding wearing safety glasses while soldering. We were careful to not short the system and used all of the technicle knowledge we have gained in order to properly build the device. We accepted advice and critisism from the TAs and Bruce Land. The three of use all assisted each other in our professional growth while working on this project. We also do not face any legal issues with this product.
Although this system can be grown and iterated into something more refined, we met all of our individual goals while working on this project. We enjoyed our time working together and gained a lot of experience. We are pleased with the final system we have produced.
A frequency counter is a useful addition to an engineer’s toolbox and you can create the design described on this page for free. All you need is a PIC microcontroller (or any microcontroller that has a high speed timer input module) and a 2 line LCD display (the standard HD44780 one is the one used here).
This PIC frequency counter project uses an LCD to display the frequency and PIC timer 1 to measure the input signal and Timer0 to measure the timing period.
It uses Timer 1 in 16 bit counter mode to count the input signal edges and overflows of the counter are accumulated to give the total count in multiples of 65536.Adding the current value of the counter at the end gives the total count.
The crystal oscillator is chosen to be 4MHz (Fosc) so that the processor internal clock is 1MHz (Fosc/4). All you do is count 1e6 processor clocks (Timer0) to give a 1second count period.
Since the measurement time is 1 second the final count is actually the frequency of the input signal i.e. number of input periods counted in 1 second is the frequency in Hz.
Using the 1 second measurement time also gives a frequency resolution of 1 Hz.
Specification: LCD frequency counter circuit
Min frequency
1Hz
Max frequency
~50MHz (limited by input pin characteristics).(Tested using TTL oscillator at 20MHz).
Input signal level
TTL
Note: The exact maximum operating frequency is determined by the PIC input pin characteristic.
Compiler
Mikroelectronika MikroC Compiler Free!
Target
16F877A (retargetable to other PICs that have TMR1)
Software level
Advanced.
Software notes
Interrupt Driven counting and time measurement.
Hardware level
Easy.
Hardware notes
None
Project version
1.03
Project files
Enter your details to get the Download Link and get the microcontroller newsletter:
(Note: Your email is safe it will never be sold or rented). You will get All theC source code and hex file.
Note: Check your email for the project code download link.
PIC frequency counter schematic using LCD and TMR0 and TMR1. (Click diagram to open a pdf.)
Pic frequency counter Hardware
The hardware is simple and the main blocks are shown in the diagram below.
The LCD is used in 4 bit mode interface so you only need 4 data lines and three control lines and it then fits into a single 8 bit port.
The crystal oscillator is simply a crystal and two capacitors connected to the PIC oscillator port at OSC1 and OSC2. The capacitors can both be fixed at the same value unless you want to tune it using a frequency reference. If you don’t have an accurate reference then use fixed capacitors.
The PIC micro can be any type that has Timer 0 and Timer 1 hardware modules and and has enough memory to hold the program ~1.6k words.
The LED is toggled to indicate that the processor is alive – so if there is no input signal you can tell that the software is working. Also if there is no input signal the the LCD displays a flashing zero.
You can program the PIC in circuit through the ICSP connector in circuit.
Description
To time a 1 second count Timer0 is used. Since the main clock is running at 4MHz then the processor clock (Fosc/4) is 1MHz which is the rate that Timer0 is set-up to use i.e. the internal clock. Therefore we need to get a 1 second count using that timer. Since the timer is only 8 bits long you can use the fact that an interrupt is generated when it overflows – you can then count these overflows to get near to 1e6 counts.
Since the overflow occurs every time that the counter passes 256 we need to count 1e6/256 overflows
1e6/256 = 3906.25
We can only count integer overflows so must manipulate the last count to get the exact time. So we need the modulus of 1e6 and 256:
1e6 % 256 is 64 (0.25*256 is 64).
The interrupt routine starts off after being zeroed by counting 3906 overflows, it then controls a flag variable (do_TMR0_end_count) that indicates this is the last overflow for which the Timer0 value is set to overflow after 64 Fosc/4 cycles:
TMR0 = 256-64+2; // 2 cycles lost when writing to TMR0 so add 2.
At the end of the last overflow the values of Timer1 are captured to:
st_TMR1L
st_TMR1H
st_TMR1_ovfl
An LCD update request is sent from the interrupt routine to the main routine by setting a flag (update_LCD) and the main routine then uses ltoa to calculate and output the frequency measurement to then display on LCD.
There are other files since MikroC version 6.0.4 seems to need a lot more than V5! just keep them in your project folder.
C Source files. Frequency_counter_4MHz_LCD_TMR1.c ltoa.c
Header files. bit.h ltoa.h
Output files Frequency_counter_4MHz_LCD_TMR1.hex
For a tutorial on compiling these files click here.
You only need to recompile the pic frequency counter files if you want to change the source code or examine how the code works using the built in simulator since the hex file to program the chip is included in the download.
Brief description
frequency_counter…c : contains the code start point (in routine ‘main’) and the interrupt routine.
ltoa.c contains a long to ascii converter used for display of the frequency count.
bit.h : contains macros for bit manipulation.
All other header files contain prototypes.
PIC frequency counter code operation.
The code uses the built in LCD driver routines which are automatically included by the compiler. Note automatic include is unusual but it seems to work well in mikroC.
Interrupts are not used only the flags that can be polled (timer overflow) are activated.
frequency_counter_4MHz_LCD_TMR1.c
This file contains the port initialization, interrupt and main routine.
After initialization the code enters an endless loop where it continuously performs a measurement and display operation. After an accurate 1 second delay the counter result is processed and displayed on the LCD.
The main operation of this code is within the interrupt routine that both counts the input edges and obtains an accurate 1s time by counting the edges of the internal oscillator clock (Fosc/4).
Interrupts
The most important part of this counter is the interrupt() routine. This is where all the action and decisions are made.
The interrupt code for Timer1 is very simple and all it does is increment a long variable for counting multiple input events.
The more tricky interrupt code, for Timer 0, counts time as described above. It counts 3906 overflows followed by a single 64 cycle count to reach a time of 1 second after which it captures the event count and then triggers an update to the LCD to calculate and display the frequency. The update triggers the actions in main().
bit.h
This contains macros for bit manipulation which should be compiler independent.
4 prototype boards arrived today. After going over them carefully, I found 4 lines that crossed each other. After some quick surgery with a knife and some solder and wire, the IDE project is now semi portable. The power supply is still out of a PC, so it’s tied to an AC outlet. I’d like to make it battery powered or at least get a smaller power source on it so it’s more easily moved.
There’s mounting holes for standoffs so it can piggyback with a hard drive. Right now, I’ve got the compact flash adaptor mounted on it.
I’ve been spending every waking moment for the last 3 weeks working on this project. The low level assembly routines have been done for a while. I’ve just been delaying putting them here. My main focus right now is finishing this project in Optama C. I’m working on something I’m going to call PICDOS. So far, I have about 14 commands defined and am working on writing the code behind those commands. For testing purposes, the user interface is a VT100 serial terminal using the built-in USART. Eventually that interface will be replaced with an I2C interface so a microcontroller (such as the BS2) can easily access a FAT partition with minimal hassle.
Here’s the low-level routines wrapped in a C function call:
Also, here’s an updated schematic. I’ve switched to an 8-bit LCD interface and moved A5 to C2 to keep all the LCD lines together.
The assembly code is working and allows for an amazing 430kb/s transfers from drive to RAM! It will read my entire 8MB CF card in less than 19 seconds. That’s 134 times faster than the basic code. As soon as I get the rest of the routines converted, I’ll post the code in its entirety. Until then, here’s what I have done.
Here’s the all basic routines and the schematic. The speed is confirmed at 3.2kb/s when writing to RAM, either from a fixed value or from the drive. I haven’t done speed tests for drive write times, but I assume they would be comparable. The assembly routines are partially written. There’s some issue with timing (the PIC is faster than the CF card!) so I’ve had to pull out my o-scope to try to resolve the problem. I think it’s just a matter of inserting a few NOPs.
I’ve finally taken some time to wire up the new PIC version. Other things have taken priority…It took over 3 hours to wire up the PIC, IDE header, 2-74LS373s & 2-64kx8bit cache ram chips pulled from an old 486 motherboard. Basically, I’ve got 128kb of ram arranged so I latch the whole 16bit address, then read/write a whole word of data at a time. This allows for 16bit transfers to/from the hard drive directly to/from RAM. The PIC doesn’t have to intercept or handle the data in any way during a transfer between the hard drive and RAM. So far, I’m using 24 pins out of the 33 available on the PIC. I still have to wire up the LCD before any programming starts.
The project demonstrates the implementation of the sound spectrum analyzer for 8-bit microcontroller PIC18F4550 manufactured by Microchip . Spectrum analysis is performed using an optimized fast Fourier transform algorithm (Fast Fourier Transformation, FFT), written entirely in C language. Data Visualization (spectrum) is carried out in real time on a graphical LCD display with a resolution of 128 × 64 pixels. Key Features:
sampling rate 20 kHz;
frequency range 312 Hz – 10 kHz;
the display speed of 10 frames per second;
display resolution of 128 × 64 pixels;
To calculate the values of the fast Fourier transform algorithm in the range of sound frequencies necessary to prepare the signal for further processing microcontroller. PIC18F4550 has an integrated multi-channel ADC, which can be used to measure voltage in the range 0 V – 5 V with 10-bit resolution (0-1023). The main characteristics of the microcontroller:
core PIC18, the operating frequency to 48 MHz;
32 KB Flash-memory programs;
2 MByte RAM;
one 8-bit timer, three 16-bit timers;
USB interface, SPI interface;
13-channel 10-bit ADC;
35 I / O lines for general use.
Audio signal from audio line-out is an alternating signal wave with an amplitude of about 1 V. The lower oscillogram clearly shows the sinusoidal tone frequency of 5 kHz (reference point on the chart W2 ).
If such a file directly to Segal ADC of the microcontroller, we get only a small range of input voltage (0 V – 0.5 V), ie we obtain the values of only the top of the wave and the calculation of FFT algorithm will be incorrect.
In order to get the correct calculations, we need over the original signal to do some action. First you need to amplify the signal in order to use the entire working range of the ADC of the microcontroller (0 V – 5 V). In the second stage, we need to shift the signal at 2.5 V (“virtual” 0) to the ADC can capture all the values of the analog signal. Thus, the microcontroller will be able to do sampling positive and negative half-wave signal.
To this end, the device used a simple on-chip amplifier LM386-1 – we solve the first condition – the signal gain. Nutrition amplifier is +5 V, and because of this, we perform the second condition – positive offset signal. With the same purpose is permissible to use rail-to-rail operational amplifier (op amp output signal c scale, equal to the voltage supply).
Oscillogram below shows the shape of the signal after the amplifier LM386-1 (control point on the chart W3 ).
The device has a stereo input J4, but with two resistors (R1, R2) par 10k done mixing the two signals. With the potentiometer R3 is possible to regulate the amplitude of the signal. The output signal from the amplifier passes through a simple RC filter is 10 kHz, and the resulting signal to the input of the ADC of the microcontroller.
RC filter 10 kHz in our case used as a filter of “smoothing” for the FFT, which can not correctly detect a signal with a frequency above 10 kHz. It is worth noting: RC filter – the filter is simple and very inefficient, but this type of filter was chosen because of ease of implementation, since required all two passive elements. Users can replace this part of the scheme, such as a filter using the operational amplifier.
To display the data using a graphical LCD display ATM12864D , one based on the controller and KS0108B KS0107B. The display connects directly to a microcontroller with 8-bit bus. In addition there are three LEDs, which are used in the test mode conversion, “music-light.” Two buttons SW1 and SW2 are used to switch display modes. The second connector J5 is designed to implement the through channel (eg, headphones). J2 connector is designed to connect the programmer and in-circuit programming of the microcontroller. To supply schemes applied voltage regulator LM7805 .
The developed one-sided printed circuit board is designed for use and installation of components with pin terminals.
However, a schematic diagram of the device is not complicated and can collect it on the breadboard. Possible to use another microcontroller, software compatible with the PIC18F4550 (for example, PIC18F2550 ).
Schematic diagram and printed circuit board (format and expressSCH expressPCB) – download
In the second part of this article, we look at the highlights in the software of the microcontroller.
In the first part Spectrum analyzer based PIC18F4550. Part 1, we met with the scheme, with the appointment of individual nodes and elements, over the principles of operation.
Microcontroller software is written entirely in C language, and it can be conditionally divided into 4 parts. 1. ADC sample data (sampling)
Implementation of sampling analog-digital converter is the channel every 50 ms RA0. This gives us a sampling frequency of 20 kHz (20,000 times per second). For the Fourier transform is very important that the samples were uniform and accurate. With this purpose in the subroutine get data from ADC introduced a short time delay, which was calibrated using an oscilloscope connected to the control point W4 on the board. Square-wave period as measured in this reference point should be exactly 50 microseconds. ADC works with a full 10-bit resolution, and the results are shifted down to 512 to implement a “virtual earth” input signal. This means that the resulting data will be in the range from -512 to 512, as required for the mathematical transformation FFT.
The procedure for obtaining the samples will take a little time to 32 ms (64 × 50 microseconds) for each cycle.
2. 16-bit FFT
Subroutine, which implements the calculation algorithm FFT, was found on the Web so (link to the original code is in the source code at the end of the article). Math FFT is complex and difficult to understand. The code has been slightly simplified and adapted for the PIC18F4550. Since the microcontroller has a hardware multiplier 8 × 8 as part of its arithmetic and logic devices have been optimized computing, allowing the compiler to correctly use the features of the microcontroller.
Many times when I’m working with a small MCU such as 8 pins or 18 pins MCU. I found that I don’t have enough MCU pins for parallel LCD display. So it’s good to have a one-pin-require LCD module for experiment. Acctually, serial LCDs are sale on the market but still I built it myself becasue I can do it and it’s cheap.
It’s a very simple schematic, I use PIC16F88 becasue It has internal oscillator and Usart module. And a 16 x 2 LCD character and numeric. PORTA is a data port connect to D4 – D7, PORTB 0 and 1 are control port connect to RS and E. RB2 is input pin for serial input data. For serial LCD, 0xFE is consider as a prefix command. The command codes are list below:
1: Clear screen.
2: Home.
12:Hide cursor.
13: Show blink cursor.
14: Show underline cursor.
16: Move cursor one character left.
20: Move cursor one character right.
24: Scroll display one character left.
28: Scroll display one character right.
192: Move to fisrt character of second line.
The communication format is 8-bit data, one stop bit and no parity (RS-232). The default BAUD rate is fix at 9600.
The code.
/*
* Project name:
Serial LCD moduel from parallel LCD
* Copyright:
Nicholas Sirirak
* Description:
Introduction
An HD44780 Character LCD is a liquid crystal display (LCD) display device designed for interfacing with embedded systems. These screens come in a variety of configurations including 8×1, which is one row of eight characters, 16×2, and 20×4. The most commonly manufactured configuration is 40×4 characters, which requires two individually addressable HD44780 controllers with expansion chips as the HD44780 can only address up to 80 characters. These LCD screens are limited to text only and are often used in copiers, fax machines, laser printers, industrial test equipment, networking equipment such as routers and storage devices. Character LCDs can come with or without backlights, which may be LED, fluorescent, or electroluminescent. Character LCDs use a standard 14-pin interface and those with backlights have 16 pins.
I am going to show you how to interface such a LCD to a PIC microcontroller (PIC16F628A). The programming for PIC will be done in mikroC (a C compiler for PIC from mikroelektronika).
he software is here:
Note: Never forget to disable the comparator functions on PORTA.0, 1, 2, 3 pins if you are going to use those pins as digital I/O.
/*
* Project name: Test LCD in 4-bit mode * Description: This code demonstrates how to display test message on a LCD which is connected to PIC16F628A through PORTB. D4-D7 pins of LCD are connected to RB4-RB7, whereas RS and EN pins connected to RA0 and RA1
Displaying content on a normal alphanumeric display is very limited ,we have to be limited with the font size and we can’t draw any graphics also. but convention Graphics lcd are really very expensive so here is the solution, you can use Nokia 3315 / 3310 monochrome LCD to display your large font text and graphics . the reason behind using this LCD is ,it is really very cheap and can be powered with 3 volts supply. so it is really good for battery powered application.
Project Description
however you can use almost any microcontroller (with capability to work on 3v ) do display content on this LCD, may be that micro controller is PIC , AVR or MSP 430 , but in this demonstration we will be using Microchip PIC 18F458 Microcontroller. The software program for this project will be written in C with MPLAB IDE , This LCD has a resolution of 84×48 pixel.
About LCD:-
Nokia 3315 / 3310 Graphical LCD uses PCD8544 Controller chip From Philips. It is a chip-on glass(COG) with 8 pin connector on the back side of the LCD . You can refer to its datasheet for more information about this controller. (CLICK HERE TO DOWNLOAD PCD8544 Controller DATA SHEET).we will discuss only few main points here for out project purpose.
The typical example of RAM is shown in the figure blow, The vertical axes area addressed form 0 to 5 with eight bits for each address when combining with x axes, it can be represented as bank.
The horizontal axes are addressed form 0 to 83 and each bit will refer the corresponding pixel in X direction.
Addressing Mode
There are two type of addressing mode in this LCD Vertical addressing Mode
A byte is sent to The LCD as follows:-
1:- Set SCE To GND
2.Set D/C to required state (Data or command)
3.Place a bit in SDIN line
4. Make high-to-low transition in CLK input.
5.Repeat step 3 and 4 for the remaining seven bits.
The initialization sequence of LCD
1. Pull SCE line to Ground to Enable The LCD.
2 Set D/C pin low to send commands to the LCD.
3. Write 0x21 Byte to LCD on the serial Bus. Here the LCD operates in Function set Command For extended instruction set.
4. Write 0xC8 Byte to LCD on the serial Bus. This set the operating voltage (Vop) of the LCD. 5. Write 0x06 Byte to LCD on the serial Bus. This set the temperature coeffcient. 6. Write 0x13 Byte To LCD on the serial Bus. This set the bias system of the LCD.
7. Write 0x20 Byte To LCD on the serial Bus. This allow the LCD to operate in function set command with basic instruction.
Recently I got my hands on a couple of HSDL-1100 based IR transceivers and a KS070B LCD display module. This was a nice opportunity to experiment with three things: (1) controlling an LCD module, (2) serial communication between two PIC microcontrollers, and (3) making this work over an IR link.
Serial protocol supports addressing of up to 32 devices over shared media (IR or direct connection) and have basic error detection (2 inverse parity bits). Packets consist of 16 bits, as given below:
P0 – inverse parity of all even numbered bits [2-14]
P1 – inverse parity of all odd numbered bits [3-15]
Device ID – ID of the target device; LCD responds to ID 00001
C/D – Code or Data; if “1”, following byte contains command (for example, LCD “CLEAR SCREEN” command); if “0”, following byte contains data (in case of the LCD this would be code of a character to be displayed).
Data is encoded as a sequence of short pulses. The beginning of a data packet is shown below:
Here in this post i am going to teach you how to display images on Graphical lcd using Pic Microcontroller(16F877). I am using JHD12864E graphical LcD in my Project. JHD12864E is 128×64 dimension lcd. 128×64 means it has 128 coulombs and 64 rows. So total dots it has is 128×64=8192. You can display an image of maximum size(Dimension = 128×64) with in this range. Some notable things..
You can only display images of .bmp format. Images bitmaps are obtained only by .bmp format. Graphical lcds consists of dots, we have to display our images using these dots and .bmp image is also comprised of dots. we can easily find bits of images of .bmp format and can map them on Graphical lcd.
You can only display black and white images(Monochrome images bitmap is hard to generate. Non software is found for generating bitmap of monochrome images on internet).
If you want to display images of size greater than 128×64 than first change the size of the image. I used an online image dimension converter(My image size is 960×1280. I converted it to 128×64 using an online image dimension converter. You can found many tools to convert images just Google for it).
If you are new to graphical lcd and didn’t know much about it just go through the tutorial below. You will become familiar with graphical lcd, its half and pages, its commands, its pin out and how to effectively use it. It will help you in understanding the code given below.
The first pic which i am going to display is mine(The Admin). Its original size is 960×1280, format is .jpg and its a monochrome pic. I converted it to black and white, format .bmp and size is reduced to 128×64 using an online software for image editing.
Now when you converted images its time to find bitmaps. Bitmaps are found using special softwares. I used an open source software The Dot Factory. Just give the path of the image and click generate it will generate bitmap with in a second. Download the software here…
Dot factory not only generates bitmaps it also gives you the dimension of the newly generated bitmaps. Once bitmaps code is generated you can copy them from their and place them in your code.
Pic16f877 microcontroller is used to display images on jhd12864E graphical lcd. Port-B is used to send data and commands to graphical lcd. It is connected to data pins D0-D7 of Graphical lcd. Lcd controlling pins en(Enable),rs(Register-select),rw(read-write) are connected to Port-D pins#7,6,5. Graphical lcd’s First-Half selection line is connected to Port-D Pin#4 and second-half selection line is connected to Port-C Pin#4.
oming to the code portion. Code is written in C++ language using MPLAB-IDE and HIGH-TECH C compiler is used to compile and generate hex code of the project.
Functions in the code with their functions are explained below…. void delay(unsigned int d)
Delay Function is used to generate some arbitrary delay to be used in the code where necessary. void lcdcmd(char value)
This function is sending commands to lcd. It not only send commands but also manipulate the lcd controlling pins(en,rw,rs) high and low to succesfully execute the commnad. void lcddata(char data1)
This function is sending data to lcd. It not only send data but also manipulate the lcd controlling pins(en,rw,rs) high and low to succesfully display data on lcd. void CS1()
This function is selecting first half of JHD12864E graphical lcd. void CS2()
This function is selecting Second half of JHD12864E graphical lcd. void createimage(const char *image)
Create image function is creating image on JHD12864E graphical lcd.
This post explains the idea of creating custom characters on any LCD ( e-g on 16×2 LCD ) which has HD44780U controller in it. Almost all 16×2 or 20×2 LCDs have HD44780U controller in them[1]. This controller provides the functionality of CGRAM ( Character Generator RAM ). We can write character patterns on this RAM and then they can be easily displayed on the LCD. The code for custom character generation using PIC16F84A microcontroller and Proteus simulation can be downloaded from the ‘Downloads‘ section at the bottom of this page.
If you don’t know how to interface LCD with PIC16F84A in 8bit mode, then you should read this post first. The required circuit for displaying custom characters on LCD is shown below.
PORTB is being used as data bus for the LCD. Also, RA1 pin is used as RS (Register Select for LCD) and RA0 pin is used as E (Enable pin for LCD).
A crystal of 20 MHz is used here. You can use any crystal value from 0 to 20MHz in this circuit. Close-up picture of the LCD is shown below.
Figure 2 shows the custom characters displayed on the LCD by running the code.
How to generate custom character ?
I am going to explain custom character generation using an example. In the figure 2, first character displayed on the LCD is named ‘Curvy Object’ in the code. To generate this character, First make a box of 8 by 5 dots. Then fill the dots required to make the custom character you want to display. Following figure explains this concept.
After filling the dots, find out the value of each line. For example, ( in the figure 3 for ‘Curvy Object’ creation ) first line has a value of 0x01, because only first dot ( at 20 position ) needs to be displayed. Then second line has a value of 0x02, because only one dot at 21 position needs to be displayed. Similarly, third line has a value of 0x04, fourth line has a value of 0x08 and fifth line has a value of 0x10. Sixth line has the two dots to be displayed, hence 0x10 + 0x01 = 0x11 is it’s value. Seventh line has all the dots to be displayed, which corresponds to a value of 0x10 + 0x08 + 0x04 + 0x02 + 0x01 = 0x1F. Eight line has no dots to be displayed, so it has a value of zero. After finding out these values make an array of these values as shown in the figure 3. This array named ‘CurvyObject’, which has 8 bytes of data will be transmitted to the CGRAM of LCD.
Code
The code for the InitLCD() function is shown below[3]. This function is used to initialize the LCD properly with the custom characters.
Downloads
Custom character display on LCD code for PIC16F84A was compiled in MPLAB v8.85 with HI-TECH C v9.83 compiler and simulation was made in Proteus v7.10. To download code and Proteus simulation click here.
This post provides the LCD[1] interfacing code in 4bit mode using PIC16F84A microcontroller. This code is written in C language using MPLAB with HI-TECH C compiler. You can download this code from the ‘Downloads‘ section at the bottom of this page.
It is assumed that you know how to make an LED blink with PIC16F84A microcontroller. If you don’t then please read this page first, before proceeding with this article.
LCD interfacing circuit in 4bit mode with PIC16F84A is shown below.
In the above figure, RA0 pin is being used as Enable pin for LCD. RA1 pin is used as RS pin and RB4 to RB7 pins are being used as Data bus for the LCD. When code starts runing then Hello is displayed on the LCD.
Any 16×2 LCD can be used here which has HD44780U controller in it. For example, JHD162A LCD can be used with this code easily.
Code
The code for the main function is shown below.
In the main function, firstly LCD is initialized using InitLCD() function. After that, “Hello” is written on the LCD screen[2]. In this way using WriteDataToLCD() function, you can write any character on the LCD screen.
InitLCD() function initializes the LCD[3] by giving the initializing commands required to turn the LCD on. This function is shown below.
Downloads
LCD interfacing code in 4bit mode using PIC16F84A was compiled in MPLAB v8.85 with HI-TECH C v9.83 compiler and simulation was made in Proteus v7.10. To download code and Proteus simulation click here.
This project uses Myke’s 2-Wire LCD Interface from last week
and will help teach you “Graphics Animation” using LCD’s.
Last week, I showed how the PICMicro could be connected up to a Hitachi 44780 LCD using only two wires. This week, I wanted to use this circuit and show how simple graphic animation can be displayed on an alpha-numeric LCD display very easily. The technique used is “Character Rotation”, in which motion is simulated in a manner that is very similar to cartoon animation.
In cartoon animation, a series of pictures are photographed in which each one is slightly different from the previous one in the sequence. When these pictures are displayed rapidly enough (usually greater than 15 times per second), the human eye perceives that only one picture is displayed and the characters on the picture are actually moving. By photographing these pictures onto movie film and running them at more than 15 frames per second, the average human can be convinced that a road runner can dupe a coyote into running into his own leg hold trap and then over a cliff where a cannon ball will crush him into an accordion.
A similar process and result can be accomplished with a Hitachi 44780 based LCD Display. The basic 44780 has an approximate ASCII character set built in. When an ASCII character is sent to the display, it is converted into a seven high by five wide series of “pixels” (dots) which appear, to the user as a character.
I say that the character set “approximates” the ASCII character set because some characters (most notably the backward slash – “\”) are not present and the ASCII Control characters (everything less than 0x020) show up as characters and do not perform their assigned actions. Part of the area reserved by ASCII for Control Characters, from 0x000 to 0x007, can be used by an application to display custom (“user defined”) characters. These eight characters can be set up and used by an application very easily.
The user defined characters have their pixel patterns stored in a separate memory area within the Hitachi 44780 known as the “CGRAM”. This is an acronym for “Character Generator Random Access Memory”. Inside the 44780, character pixel patterns are generated from memories. For the most part (248 characters), this is a “ROM” (“Read Only Memory”) character generator which has been predefined and cannot be changed or defined by the user. The remaining eight characters have a “RAM” character generator which can be written to and when the representative character is to be displayed, the user defined pixel patterns is used instead of a predefined one.
This aspect of user or application pixel definition is why I usually refer to these eight characters as the “user defined characters”. If no pixel pattern is written to the 44780 and a character from 0x000 to 0x007 is displayed, then a random pixel pattern will be displayed.
If you power down the LCD display and display the character again, chances are the pixel pattern will be different. This is because the RAM does not power up to a set value and means that if you want to use the user defined characters, you have to make sure they are properly defined before they are displayed. Each byte within the CGRAM is used to display a line of pixels on the LCD display. The actual character definition is shown in the diagram below.
As can be seen in the diagram, the first line (or row) of pixels is at the character starting address in CGRAM with each line, going down, at an incrementing offset. When the 44780 was designed, the engineers took into account how people think and made it easy to figure out which bits are displayed for each row. Bit 0 of the row’s byte is on the right hand side of the eight by five character block; so to define a row, each pixel is represented as a bit in the byte and if the pixel is to be dark a “1” is placed in the byte that defines the row.
This is probably a bit hard to understand, to make it easier, I want to go through an example character that I created for the application that is presented later in this article.
To define a character, I usually take a piece of graph paper, outline an eight by five square box and draw the character inside it as I’ve shown in the diagram below: