|
|
View previous topic :: View next topic |
Author |
Message |
unkani
Joined: 16 Nov 2014 Posts: 2
|
Trouble receiving TTL from fingerprint scanner PIC16F1829 |
Posted: Mon Nov 17, 2014 12:03 am |
|
|
I'm using a PIC16F1829 to interface with a serial LCD and fingerprint scanning module that uses TTL.
I'm able to transmit to the LCD, as well send my command packets to the fingerprint scanner. However, I'm unable to receive anything back.
It doesn't seem like the interrupt is triggering at all, and I have no idea why - my hardware connections are there, and I can see the voltage drops on an oscilloscope.
I read that there can be problems when interfacing a 3.3V peripheral with the 5V microcontroller, but I don't think this should be a problem, considering that the distance between the peripheral and the microcontroller is minimal, and with the TTL input, 3.3V should register high.
Additionally, I have also noticed that when I create an array, it's not actually empty, unless I initialize it with zeros... such as "char array[2] = {0, 0}"
With the code below, my output is as follows "bf 0 c"
I've been stuck on this for a couple of weeks... I have no idea what I'm doing wrong (probably a lot of things). I'm very very new to C programming with microcontrollers. Any ideas? I would really really appreciate it!
Here is the program code:
Code: | #include <16F1829.h>
#device PIC16F1829 *=16
#include <STDLIB.H> // look in the PIC C User Manual to see what this library contains
#include <MATH.H> // look in the PIC C User Manual to see what this library contains
#fuses INTRC_IO, NOWDT, NOMCLR, PUT
// Set for internal oscillator operation with RA6 and RA7 as digital I/O,
// Disable the WDT. Later setup WDT = 2048 ms WDT, ref 16F1829.h to find syntax
// Disable the /MCLR pin so that it can be used as general I/O
// Enable the Power-Up Timer, allows power supply to stabilize at start-up
#use delay (clock=4000000) // 4 MHz, 1 us instruction cycle, CHECK TIMING DELAYS!
#use RS232 (baud=9600, xmit=PIN_C1, rcv=PIN_B6, stream=FPS)
#use RS232 (baud=9600, xmit=PIN_C2, rcv=PIN_B6, stream=LCD)
#use fast_io(B)
#define BUFFER_SIZE 32
byte buffer[BUFFER_SIZE];
byte next_in = 0;
byte next_out = 0;
#define bkbhit (next_in!=next_out)
///////////////////////////////////////
// SUBROUTINES, Here is where you set up your I/O ports and other features of the microcontroller
void init_ports(void) {
INPUT(PIN_B6);
}
///////////////////////////////////////
// PIC18F1320 goes here at RESET
char test;
#INT_RDA
void serial_isr()
{
/*
Receive_String[counter_read]=fgetc(FPS); // Gets chars from uart
counter_read++; // Increment counter
if(counter_read==bufferz){
counter_read=0;
greeting = 'b';
}// Circle Buffer printf(LCD, "interrupted");
*/
// buffer[1] = fgetc(FPS);
// fprintf(LCD, buffer[1]);
// OUTPUT_BIT(PIN_C4,1); //Green LED
int t;
buffer[next_in] = getc();
t = next_in;
next_in = (next_in+1) % BUFFER_SIZE;
if(next_in == next_out){
next_in=t; // Buffer full !!
}
test = 'b';
}
//getc will cause errors
int8 bgetc()
{
byte c;
while(!bkbhit);
c = buffer[next_out];
next_out = (next_out+1) % sizeof(buffer);
return c;
}
//======================================================
void main() {
delay_ms(100);
char msg[32];
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
init_ports(); // Initialize ports
test = 'c';
fprintf(FPS, "%c%c%c%c%c%c%c%c%c%c%c%c", 0x55, 0xAA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01); //First line. Required.
delay_ms(20);
while(TRUE) {
fprintf(FPS, "%c%c%c%c%c%c%c%c%c%c%c%c", 0x55, 0xAA, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x13, 0x01); //Lights up the LED of FPS
delay_ms(100);
//fprintf(FPS, "%c%c%c%c%c%c%c%c%c%c%c%c", 0x55, 0xAA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x12, 0x01); //Turns off the LED.
// Parameter //Command //Checksum
fprintf(FPS, "%c%c%c%c%c%c%c%c%c%c%c%c", 0x55, 0xAA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x12, 0x01); //Turns off the LED.
// for(i=0; bkbhit && i<sizeof(msg); ++i){
for(int i = 0; bkbhit; i++){
msg[i] = bgetc();
}
for(int j = 0; j<sizeof(i); j++){
fprintf(LCD, "%x", msg[j]);
}
fprintf(LCD, " ");
delay_ms(50);
fprintf(LCD, "%d", i);
delay_ms(50);
fprintf(LCD, " ");
delay_ms(50);
fprintf(LCD, "%c", test);
delay_ms(500);
fprintf(LCD, "%c%c",0xFE,0x01); //Clear code
// output_low(PIN_A5); //Sets LED down to low
}//While
}//Main |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Nov 17, 2014 1:45 am |
|
|
INT_RDA, is _only_ available for the hardware UART.
The hardware UART on your chip, uses RB5/RB7, or RC4/RC5.
Unless you use the hardware pins, and configure the hardware UART to be on these pins, INT_RDA is _not_ available to you.
As it stands, the compiler will be configuring a software UART, which can only receive if you are sitting polling the data waiting for it to arrive.
Separately, you can't have the same pin used for receive by two ports.
Then you are doing far too much in the ISR. Just receive the character, into the buffer get rid of the other code into the main loop. You seem to be trying to get two characters in the routine, one from the scanner, and one from the LCD!..... getc, will get from the _last_ serial defined, if used with multiple serials setup, instead of fgetc. Wrong.
Then you are selecting fast_io on port B, but then not setting the TRIS. Once fast_io is selected, it becomes _your_ responsibility to setup the TRIS. just using input and output, no longer automatically sets things....
As a comment, you do realise that you can just include constant values into the printf (or even putc) string without fiddling with %c....
How are you protecting the FPS module from overdrive?. If you are driving a 3.3v module from a 5v serial pin on the PIC, you will be over-driving both the PIC output, and the input pin to the module. How is the connection made?.
'Of course' an array won't be empty. It'll contain whatever the memory has in it. This is true of all uninitialised variables, unless you explicitly use either '#ZERO_RAM', which clears all of the memory on boot - slow, or declare a variable as global and static (in which case it is initialised to zero). This is why anything you _want_ to have a known value at the start must always be initialised. |
|
|
unkani
Joined: 16 Nov 2014 Posts: 2
|
|
Posted: Tue Nov 18, 2014 12:55 am |
|
|
Thank you so much for your input! I'm able to receive inputs now!
I disabled fastio, and switched my ports to RB5/RB7.
Why is it that I have to use both RB5 and RB7 for INT_RDA to work, rather than only the RX being on a hardware UART?
Also, I forgot to clarify - the LCD doesn't actually respond - there is no TX pin on it, only an RX. Early on in the coding, I didn't realize you could name the streams, so I figured that as long as the RX was on the same pin, I could just redo the #rs232 to switch the transmission pin. Really convoluted, I know...
As far as I can tell, this doesn't pose any problem. My fingerprint scanner transmits and receives, and I am able to transmit to my LCD.
About the buffer code, are you talking about the next_in stuff? I took the code from a PICC example file, so I can't claim to understand what exactly is going on... to me, it seems that my #INT_RDA code is only 7 lines, and all of it deals with the buffer, doesn't it? The int8 bgetc() is a function outside of the #INT_RDA
Also, I'm not sure what you mean about fiddling with the %c. Without it, my fingerprint scanner doesn't understand my code... like this:
fprintf(FPS, 0x55, 0xAA, 0x01...(and so on) )
I've got my output pin going through a simple voltage divider so my FPS doesn't fry. Thanks for the concern!
I just want to thank you again - self-learning is awfully difficult, and you have single handedly saved me from what is no-doubt tens and tens of more hours banging my head against this microcontroller. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Tue Nov 18, 2014 1:22 am |
|
|
OK.
You have to define both pins to say 'use the hardware'. The UART is a single 'entity', and it isn't used unless you tell the code to use the whole thing. However having done this, you can afterwards turn off the transmit side of the hardware if you only want to use RX. A search here will find 'how to do this' (I've covered this in the past on several occasions...)
On the printf, the point is that you can include the constants in the format string, or in a string to putc.
So:
Code: |
fprintf(FPS,"\x55\xAA\x01");
|
says to print the characters one after the other, to the FPS stream.
Without the escape (\x), the _text_ '0x55' gets printed as four characters. With the escape, the binary value 0b01010101 is sent for the first character etc..
What you are doing is having a definition string saying 'print a character' 'print a character' etc., then defining the characters separately. The actual character definitions can be included directly in the string.
Well done on moving forward. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|