This weeks task: make your own board output something...
Let me short think about some output-ideas:
LED or seven-segment-display -> Look at week 8
Use the UART to bring some livesigns out -> Look at week 11
Use the I2C to fire some display -> Look at week 11
Okay, we will use a stepper motor. Always a nice feature if you want to make a robot
or any moving device.
Some theory about the standard stepper-interface:
The most interfaces uses 3 signals:
Motor direction (CW or CCW)
There are a lot of ready-to-use stepper-driver out there, for example the polulu boards.
Classical self-made drivers uses the L297 and L298 ICs. A little bit outdated, but still good and
easy to use.
For making this assingment a little more interessting i will use an old 5.25" floppy drive.
This old drives have a stepper motor for the read/write-head that is not controlled by the drive
itself, but on the external floppy-controller. Therefore the drive has the enable, direction and step
signal routed out to the connector.
In my bookshelf i found an old book from 1994, with the connector-description from the old drives:
Hooking the floppy and the Fab-Pic together:
Writing some code, and this comes out (turn your volume up for the nice old floppy-sound):
Ok, there was a little more work in it ;)
For generating the step-pulses i use a timer of the pic, timer 1.
This timer has a 16bit value, and after some calculating i get the values
for the pre- and postscaler. All other configs are good described in the datasheet:
T1CON = 0b00000011; //Config Timer2
IPR1bits.TMR1IP = 1; //Setting Timer1 to high-prio
PIE1bits.TMR1IE = 0; //Disable Timer1 Interrupt until drive to middle
PIR1bits.TMR1IF = 0; //rest TMR1-Interrupt flag
RCONbits.IPEN = 1; //enable High/Low-Prio
ei(); // master switch to enable interrupt
INTCONbits.GIE_GIEH = 1; //enable all Low-Prio-Interrupts
INTCONbits.PEIE_GIEL = 1; //enable all Low-Prio-Interrupts
Everytime the timer overflows an interrupt is generated.
Due to the fact that our PICs just knows 2 interrupt-priorities we
have to check on every interrupt which interrupt-source has generated the interrupt.
After the check we can execute some code, and reset the interrupt.
Because we want different frequencys we preload the timer-value on every interrupt:
The calculation of the preload-value is made by the subroutine "play".
The main program just calls play one time with a wished frequency, and after this nothing
needs to be done anymore.
void play(int frequency)
//Using Timer1 for PWM-Generating
//Timer is configuered as 16-Bit, running on FOSC/4 = 8MHz, 65536 counts max
//For one periode pf sound (1Hz) two timer-overflow are needed (one low, one high)
//TMR1H is the high register
//TMR1L is the low register
if (frequency <=62) frequency = 62;
if (frequency <=62) frequency = 62;
okay, a little excurse:
A lot of music files you can find in the web are in MIDI-format.
This format is designed in a time, when memory was very expensive. And it is desigend
by musicans, for musicans.
Because of this the time-delays are not in seconds but in quarter-notes and metronome-ticks.
And there are no frequencys but notes. Yes notes. Like C1 or D3.
Due to the MTM-Week (still have to write the docu for presentation next day) i will
not explain the whole format to you. If you are interessded, google it. There are
a lot of good explanations out there. I used these to write a php-script.
Here on github the server can´t execute PHP, so you have to execute it on your PC or server.
For some time you can also use the srcipt on my own server: