EEVblog Electronics Community Forum
Electronics => Microcontrollers => Topic started by: wicket on March 17, 2014, 09:59:04 am
-
Hi,
I'm using a PIC16F628A USART to communicate with my SE T610 GSM. MikroC compiler.
Circuit:
(http://shrani.si/f/e/Gq/1VtUiTSy/vezje.jpg)
How program works - when RB0 goes high, uC transmits "at" command to my GSM and it responds "OK". I've included a char compare routine to see if the response is indeed "OK". And it works - if it receives chars O, K, \n or \r the LED turns on.
My problem - I'm trying to use the exact same program and circuit (with appropriate pin adjustments, of course) with my PIC18F4520 and PIC16F887 but it doesn't work.
Transmittion works fine, I've tried "atd" command instead of "at", and GSM makes a call, which means transmission is ok. And uC also receives something back, because interrupt does occur (i've tested it), but when I compare incoming chars, none of them are what they are supposed to be ("OK\n\r").
I've also connected the GSM to my PC directly and tested it using putty to make sure it's not GSMs fault. It works perfectly.
Voltage levels of Tx and Rx pins are correct, I've also tried different Fosc's and baudrates, but couldn't make it work. Unfortunatley I don't have an access to any oscilloscope to check what am I actually receiving.
I don't understand why it works on 16F628A, but not on other two PICs. I suspect it has something to do with USART configuration. I've read all 3 datasheets but it seems to me nothing should change regarding USART init.
I would really appreciate any help.
Code from PIC16F887, where I'm using PORD intead of PORTB I/O:
volatile unsigned char uart_rd = 0; // serial input byte (RCREG)
unsigned int b = 0;
// UART Initialization
void uartinit()
{
UART1_Init(9600); // initialize UART module at 9600 bps
Delay_ms(100); // let it stabilize
PIE1.B5 = 1; // turn on USART interrupt bit RCIE
}
// UART Interrupt: Receive character
void interrupt()
{
if (PIR1.B5) // if interrupt occurs - if RCIF = 1(RCREG full)
{
uart_rd = RCREG; // read incoming byte (character)
if (uart_rd == 79) PORTD.B1 = 1; //if incoming byte is "O", turn on LED
PIR1.B5 = 0; // reset RCIF flag bit to 0
}
}
// Main program
void main()
{
uartinit();
INTCON = 0b11000000; // enable PEIE and GIE interrupts
ADCON1 = 0b0111; // configure all pins as digital
TRISD = 0b01;
PORTD = 0b00;
while (1)
{
if ((PORTD.B0 == 1) && (b == 0)) // if input goes high
{
b = 1; // set flag, so this if loop is disabled in future
UART1_Write_Text("at"); // phones response should be "OK"
UART1_Write(13); // \r
}
}
}
-
The usart portion of the code looks ok. Issue is likely somewhere else, like pin setup - analog and comparator off....
-
16F887 datasheet (http://ww1.microchip.com/downloads/en/DeviceDoc/41291F.pdf)
Possible, yes. I've set all analog pins to digital using ADCON1 = 0b0111; as described in datasheet, but I can't seem to find comparators module with this PIC.
-
Page 87 & 109
-
Whoops, I downloaded 877 datasheet instead of 887.
I've corrected the code, but it still doesn't work:
volatile unsigned char uart_rd = 0; // serial input byte (RCREG)
unsigned int b = 0;
// UART Initialization
void uartinit()
{
UART1_Init(9600); // initialize UART module at 9600 bps
Delay_ms(100); // let it stabilize
PIE1.B5 = 1; // turn on USART interrupt bit RCIE
}
// UART Interrupt: Receive character
void interrupt()
{
if (PIR1.B5) // if interrupt occurs - if RCIF = 1(RCREG full)
{
uart_rd = RCREG; // read incoming byte (character)
if (uart_rd == 79) PORTD.B1 = 1; //if incoming byte is "O", turn on LED
PIR1.B5 = 0; // reset RCIF flag bit to 0
}
}
// Main program
void main()
{
uartinit();
INTCON = 0b11000000; // enable PEIE and GIE interrupts
ANSEL = 0b00000000; // configure all pins as digital
CM1CON0.B7 = 0; // comparators off
CM2CON0.B7 = 0;
TRISD = 0b01;
PORTD = 0b00;
while (1)
{
if ((PORTD.B0 == 1) && (b == 0)) // if input goes high
{
b = 1; // set flag, so this if loop is disabled in future
UART1_Write_Text("at"); // phones response should be "OK"
UART1_Write(13); // \r
}
}
}
I get into interrupt routine, but received byte is still not O, K, \n or \r.
-
As a test you could loop mcu tx and rx and see if what you send is what you get back. Might gives some clues to help understand where the problem is
Save up and buy a scope, so useful for this sort of stuff.
-
Yeah, I tried using intergrated UART tool and it worked all right. I received what i sent.
I'm simply lost, duplicating the exact same routine on different PIC... Strange.
And yes, I'll definitely get myself a scope.
-
Aside from actual differences between peripherals, you want ckeck analog, comparator, and fuse.
-
Have you tried using your micro unit with some PC terminal software to see if the baud rate is correct?
A loopback will succeed with the wrong baud rate because the micro tx and rx are at the same (incorrect) rate.
-
I think it's time to throw a blinky on all three chips, using the same code base, and making sure blinky does it's blinking at the correct rate.
I'm betting you'll find one of them is 4x off.
-
Have you tried using your micro unit with some PC terminal software to see if the baud rate is correct?
A loopback will succeed with the wrong baud rate because the micro tx and rx are at the same (incorrect) rate.
I connected my PIC to TTL - USB converter and tried to used putty, but I cannot type anything into terminal window and I also don't receive anything. But if I use MikroCs integrated UART terminal, it works.
What if I insert a parity bit check into my interrupt routine (FERR)? Would that signalize incorrect baudrate or xtal? I've read that UART is extremely sensitive regarding oscillator.
-
Checking that the oscillator is running at the correct speed should be at the top of your list.
-
Would that signalize incorrect baudrate or xtal? I've read that UART is extremely sensitive regarding oscillator.
....hence the earlier suggestion to hook up an LED and write a quick blinky program...
...(sigh)...
-
....hence the earlier suggestion to hook up an LED and write a quick blinky program...
...(sigh)...
Gonna try it then. :)
-
I connected my PIC to TTL - USB converter and tried to used putty, but I cannot type anything into terminal window and I also don't receive anything. But if I use MikroCs integrated UART terminal, it works.
Putty won't display characters you type, but they are still sent. Normally, when you see what you are typing, it's because the receiver is echoing the characters back.
From what you've said so far, it certainly sounds like the baud rate is set incorrectly. I would double check the CONFIG bits, and the OSCCON register. You can also set OSCCON manually at the top of your main() routine to be sure it is what you expect. I don't use MikroC, but the UART1_Init() library routine will be setting up the UART registers based on what it believes the clock rate is.
You could also not use UART1_Init() and just setup the USART registers yourself, it's really only a few lines of code.
-
I understand. Instead of calibrating INTOSC, I'm gonna test it using 3.6864 MHz in 11.0592 MHz crystals, which are supposably the best fit for UART (theoretical 0% baud error).
I'm gonna set UART registers myself and also try to duplicate the same program in MPLAB instead of MikroC. I'll let you know how it goes.
-
The point isn't really that your crystal, internal oscillator, etc. is off by 1% or 2% or whatever... The point is figuring out if you've got your oscillator configuration set correctly and therefore your baud rate division is being done correctly.
Example...If you do a one second blinky, and actually get a 4 second blinky, might be trying to use the 4xPLL, but it's not actually on, or something along those lines.
-
might be trying to use the 4xPLL
The chip is unlikely to have a pll.
9600bps is usually the upper limit for internal rc oscillator. If you suspect that the internal oscillator isn't that accurate, you can try to tune it or lower the baud rate to a point where oscillator errors are sufficiently insignificant.
It is generally a good idea to use crystal when high speed uart is used, however.
-
I tried the framework of your code and it worked: in my case, I was looping back RX to TX and flipping PORTD.1 on '\n'. So your issues are anything other than the portion of the code posted.
One suggestion:
INTCON = 0b11000000; // enable PEIE and GIE interrupts
I would rewrite that code using bits, if your compiler supports it:
PEIE = 1; //enable peripheral interrupts
GIE = 1; //enable global interrupts
In case the positions of PEIE and GIE are different from chip to chip.
-
Clarify a little bit further: as I don't have your compiler, I had to set CREN and others bits to get my code to work, in the spirit of your code. Your usart initialization may or may not have done similar things. but the isr is identical (functionally).
-
Ok, I decided to leave behind my PIC 887 (I only used it to compare to my 628A and 4520) and only focus on 18F4520, which I'll be using in my final product. I also found 7.3728 MHz oscillator, which gives me 0% baud error using BRGH = 1, BRG16 = 0 and desired baud of 9600 bps.
Tried a simple 1 second blinky, works fine.
To avoid any potencial mess, I also initialized UART myself, instead of inbuilt UART1_Init() library.
Also tried PORTD instead of PORTB. Everything is the same, I do get into the interrupt routine, but an led doesn't turn on when comparing incoming chars.
I've measured voltage levels of the circuit (I'm powering it from 7805 reg.):
Vdd - 5,02 V
PIC Tx pin (GSM Rx) - 5,02 V
PIC Rx pin (GSM Tx) - 2,78 V
Since I don't own a scope, I was measuring PIC Rx voltage during reception and a slight voltage drop does occur (I know multimeter isn't fast enough, but it seems there definitely is something going into the PIC).
-
/* ---
Here's the exact code I used on PIC16F887 ( 887 !!)
Worked fine with internal 8MHz oscillator (INTOSC) - both PIC to PIC and with many serial terminals - FTDI and RS422 links
It may be worth looking at the FERR flag, as I found that closes the UART until it is cleared and re-initialised as shown below.
--- */
// =================================================================
:
:
:
// ---- serial port --------------------------------------
#define SER_19200
#ifdef SER_9600
TRISC6 = 0;
SPBRG = 12; // 9600 bps @ 8MHz CLOCK
BRGH = 0; // high speed flag
BRG16 = 0;
#endif
#ifdef SER_19200
TRISC6 = 0;
SPBRG = 25; // 19200bps @ 8MHz CLOCK
BRGH = 1; // high speed flag
BRG16 = 0;
#endif
#ifdef SER_57600
TRISC6 = 0;
SPBRG = 34; // 57600bps @ 8MHz CLOCK
BRGH = 1; // high speed flag
BRG16 = 1;
#endif
// ------------------
SYNC = 0; // asynchronous
RX9 = 0; // 8 bit
CREN = 1; // receiver enabled
TX9 = 0; // 8 bit
TXEN = 1; // enabled
SPEN = 1;
:
:
:
// =================================================================
void sendChar(char c) {
while ( (TXIF == 0 ) );
TXREG = c; // push char to tx register
DelayUs(100); // allow the receiver to digest the char - no handshake
}
// =================================================================
static void interrupt isr(void) {
while (RCIF) { // serial character(s) have been received into FIFO
CLRWDT();
if (OERR) { // over run
CREN = 0; CREN = 1; OERR = 0;
rptr = rxBuf; wptr = rxBuf; // reset the rx Buffer
break;
}
if (FERR) { // framing err
rptr = rxBuf; wptr = rxBuf; // reset the rx Buffer
dummy = RCREG; // grab the dud character
break;
}
mychar = RCREG; // put char from rx register into buffer
:
:
:
}
// =================================================================
-
Yes, checking for overruns and frame errors (and reacting to them) is essential.
-
if (uart_rd == 10) PORTB.B1 = 1; //if incoming byte is "\n", turn on LED
Use
if (uart_rd == 'a') PORTB.B1 ^= 1; //if incoming byte is "\n", turn on LED
and tie RX to TX. Insert a long delay like 500ms in the main loop - don't set b in the main loop.
If you observe B1 blinking, your code is working.
-
Using your advices, I programmed the chip in MPLAB (first time using this program, maybe something is way off).
First I only tried looping Tx and Rx through UART terminal and it worked fine, I received what I sent, also the LED was turning on/off on defined chars/strings.
When I hooked up my GSM, I got the same result as always till now... Transmission works and i get into the interrupt itself, but that's it.
Now I'm trying to do FERR and OERR check. I'm reading the 18F4520 (http://ww1.microchip.com/downloads/en/devicedoc/39631a.pdf) datasheet and it says, that this chip doesn't support hardware parity, but it is possible via software. I simply don't know how to handle this, it probably has to do something with 9-bit reception, whereas the 9th bit is a parity bit?
Oh, and I tried to use delays instead of "flag" b in mikroC, but it didn't help. And I don't know how to use a delay in MPLAB, so I couldn't test it there.
-
I agree with the above, you must check always for framing and other Rx errors.
I always first suspect the baud rate. Try setting BRG one step higher or lower, especially if you see framing errors. Try using a scope to measure the actual baud/bit rate coming out of each device and compare. You must be within 4% error (so each side no more than 2% error high/low from the desired rate). An error of just 5% doesn't sound like much, but consider there are ten bits in each frame (start, data*8, stop), so the tenth bit in each frame will be more 50% out of phase. Then one receiving side will likely see frequent errors. Often when the baud rate error is marginal, only one side sees framing errors.
Personal anecdote: I recently set up a terminal server (box with Ethernet and a bunch of network-accessible serial ports) and was getting strange errors talking to many devices. I scoped the signals to the baud rate and saw it was about 4 % low at any baud rate setting. The other device was maybe 1 % high. This caused errors. The fix was easy, just replace a 25 MHz oscillator with a (custom made) 26 MHz one, forcing the baud rate to be always 4% higher. It is now spot-on and can talk error free to everything I have plugged into it.
I just saw your post on Parity. Parity is most often not used. You can only use it if the other device does too, and it very very likely does not. There is an extra data bit sent as parity. For PICs, you need to calculate the bit based on your data, then set the (9th) bit in the appropriate register before writing to TXREG. On the receive side, you extract the parity (9th) bit before reading from RXREG, then calculate desired parity from the data bits and compare. Don't concern yourself with this as your device almost certainly does not use it.
-
Your voltage on the GSM Tx PIN (PIC RX) looks suspect. Are you trying to interface a 3.3V (or 2.8V?) device with your PIC at 5V?
-
and tie RX to TX. Insert a long delay like 500ms in the main loop - don't set b in the main loop.
If you observe B1 blinking, your code is working.
Tying RX to TX doesn't tell you if the baud rate is what you intend, it will work even with non-standard rates.
To the OP:
There's absolutely no reason you can't use the internal oscillator (HFINTOSC) at 8 MHz for 9600 baud. If you check the datasheet for the 16F887 for example, you will find that the internal oscillator is specified to +/- 2% over 0 C to 85 C. This gives a maximum error of ((8.16MHz / (64*(12+1)))-9600)/9600 = 2.16%. Assuming you are sitting at room temperature it will be much better. Maximum allowable will be around 4.5% for 8bits+parity+stop bit. Your issue is not about crystals, believe me.
-
18f4520 - has 4xPLL, other 2 chips don't have it.
-
18f4520 - has 4xPLL, other 2 chips don't have it.
True, but why does that matter? The 16F887 has 8 MHz without 4xPLL, and the 16F628A has 4 MHz. No reason you need a 32 MHz oscillator to use a UART at 9600.
-
18f4520 - has 4xPLL, other 2 chips don't have it.
True, but why does that matter? The 16F887 has 8 MHz without 4xPLL, and the 16F628A has 4 MHz. No reason you need a 32 MHz oscillator to use a UART at 9600.
I know that. You know that. The O/P might not know that.
-
18f4520 - has 4xPLL, other 2 chips don't have it.
True, but why does that matter? The 16F887 has 8 MHz without 4xPLL, and the 16F628A has 4 MHz. No reason you need a 32 MHz oscillator to use a UART at 9600.
I know that. You know that. The O/P might not know that.
Good point! ;D
-
I have PLL disabled.
About 2.78 V on Rx pin - I actually started this project using Arduino Uno and it was a complete success. GSM was the same one I'm using with PIC, Sony Ericsson T610. I've read on arduino forums, that this GSM model should support 5 V Tx/Rx.
It seems as new Sony Ericsson phones need a TX/RX voltage of somewhere about 2,6V to get it working. If you use one of the listed older phones you should get it working with the 5V TX/RX from the Arduino.
T series :
T39, T68, T68i, T230, T250, T610, T630, T650i
I've never used Atmel chip by itself, so I don't know if there is a difference, but I measured voltages on Arduino again today and they are the same as with PICs.
-
In your PIC 18F4520 datasheet, pg. 335, you will note that the spec for VIH says 0.8 VDD on Schmitt Trigger inputs. Your UART RX pin is a Schmitt Trigger input. That means you need 5V * 0.8 = 4V for the high level, so your GSM phone isn't driving it high enough.
Anyhow, even if someone on the Arduino forums talks about interfacing with phones at 2.6V with the (presumably) 5V Arduino, that doesn't mean that is really OK. You shouldn't be driving the RX pin on the phone with 5V from your UART if it is using 2.6V logic. Sometimes pins are tolerant, but you want to check that out for sure. (My guess would be no, the phone isn't rated for 5V on it's RX pin).
Edit: Not intending to come across harshly. The Arduino forums are filled with bad ideas from an EE perspective, so just keep that in mind.
Hope this helps you solve your problem.
-
The voltage on rx pin reflects its duty cycle.
-
The voltage on rx pin reflects its duty cycle.
That is a good point, but I assume the OP measured the voltages when no data was being transmitted. Yes?
Edit: I re-read where you said you measured the voltages "during reception." It's hard to know what you really measured. Since you don't have a scope, check the level on the TX pin from the phone without any communication going on.
-
If I have my GSM hooked up to PIC, the TX voltage on the GSM is the same as if the GSM is disconnected from PIC - 2.78 V. RX voltage on the GSM is 5 V when hooked up and 0 V when disconnected from PIC.
I did observe the voltage when I have triggered the transmission and there was a slight (approx. 200 mV) voltage drop on GSM TX / PIC RX pin. But that probably doesn't tell you anything because multimeters refresh rate is to slow.
-
Maybe try a Pull-up resistor?
-
If I have my GSM hooked up to PIC, the TX voltage on the GSM is the same as if the GSM is disconnected from PIC - 2.78 V. RX voltage on the GSM is 5 V when hooked up and 0 V when disconnected from PIC.
I did observe the voltage when I have triggered the transmission and there was a slight (approx. 200 mV) voltage drop on GSM TX / PIC RX pin. But that probably doesn't tell you anything because multimeters refresh rate is to slow.
Right. So that 2.78V is definitely a problem for you, since the PIC requires the HIGH level on the RX pin to be > 4V. The normal UART setup is both lines idle HIGH. The receiver does just that, receives, and doesn't set the level on that line, it is set by the opposite TX output. That is exactly why you see 2.78V on the TX pin on the phone and 0V on the RX pin, until you connect the PIC, which then drives that line to 5V.
You are getting your interrupt when the PIC RX line goes LOW the first time, but it never goes high enough again to be detected by the PIC, due to it's Schmitt Trigger input.
You need a level shifter. You don't want to just pull that line high with a resistor to your 5V, because then you will be back-driving the output of the GSM phone and current will flow into the output. A level shifter can be made simply with one transistor and resistor because of the low speed in this case. The PIC has a bit which can be set/cleared to invert the UART logic.
-
In my last PIC project I used a RS232 Bluetooth Module and just used a pullup.
-
In my last PIC project I used a RS232 Bluetooth Module and just used a pullup.
That diagram is showing 5V TTL to 5V CMOS. The issue in that case is that TTL is based on BJTs, where CMOS is, well, MOSFETs. Those systems are both at 5V. Not the same thing here. Yes, you can sometime get away with a pull-up, but it's not the right way to do it. If you use simply a pull-up, you have current flowing through the body diode on the output transistor of the transmitter (GSM phone). If your project with the Bluetooth module is also at 3.3V you are doing the same thing in that case. This is bad idea.
If you don't believe me, have a look at this discussion on the TI forums:
http://e2e.ti.com/support/microcontrollers/msp430/f/166/t/60581.aspx (http://e2e.ti.com/support/microcontrollers/msp430/f/166/t/60581.aspx)
To the OP: why not just run your PIC at 3.3V (or 2.7V?), which will avoid these issues.
-
I'm gonna try both - 3.3 V circuit and level shifter. Maybe even a pullup, just for fun. :)
By the way, I really appreciate everyone's help.
-
I would try the pull up first.
-
I'm looking at a Voltage - Frequency graph on page 324 (http://ww1.microchip.com/downloads/en/DeviceDoc/39631E.pdf).
Can I even run this chip from 3.3 V?
-
Wicket... I'm looking at a Voltage - Frequency graph on page 324.
Can I even run this chip from 3.3 V?
PIC18LF2420/2520/4420/4520 - INDUSTRIAL
Yes but only if clocked at 10MHz or lower...
The other chip variants don't seem to be so accommodating
-
Can I even run this chip from 3.3 V?
Put in a couple of diodes on the 5v supply line and you will find.
Yes, it will - there is considerable room for tolerance for the specs.
-
AMEN! It's finally working! You were right, I replaced my 5 V regulator with 3.3 V one and it started blinking exactly as it should. 2,78 V was clearly not enough for logical high @ 5 V. I first tried it using 3.6864 MHz crystal, but it even works with internal osc. @ 4 MHz.
Oh and just so you know, I also tried using pullup @ 5 V, but it didn't help. I can finally move on now, it took me 10 days to get this right, jesus...
Anyway, thanks to everyone! :clap:
-
AMEN! It's finally working! You were right, I replaced my 5 V regulator with 3.3 V one and it started blinking exactly as it should. 2,78 V was clearly not enough for logical high @ 5 V. I first tried it using 3.6864 MHz crystal, but it even works with internal osc. @ 4 MHz.
Oh and just so you know, I also tried using pullup @ 5 V, but it didn't help. I can finally move on now, it took me 10 days to get this right, jesus...
Anyway, thanks to everyone! :clap:
Glad to hear you got it working!
-
AMEN! It's finally working! You were right, I replaced my 5 V regulator with 3.3 V one and it started blinking exactly as it should. 2,78 V was clearly not enough for logical high @ 5 V. I first tried it using 3.6864 MHz crystal, but it even works with internal osc. @ 4 MHz.
just so you know, I also tried using pullup @ 5 V, but it didn't help. I can finally move on now, it took me 10 days to get this right, jesus...
Anyway, thanks to everyone! :clap:
meh...don't feel too bad. You aren't the first one to get bit by this sort of thing. (eg. ST vs TTL vs CMOS inputs/outputs, etc.)
-
What would be the best way to boost up the 2.78 V signal from GSM? My entire circuit is based on 5 V (relays, sensors, other chips) and it's kinda awkward for me to use 3.3 V now. Can I use the level shifter just for this signal? Are this things fast enough though?
-
Easily fast enough for serial signals.
-
What would be the best way to boost up the 2.78 V signal from GSM?
Not sure about the best. The easiest would be to use a pull-up (=resistor + diode).
-
Use a single transistor and two resistors. See the attached image. You don't have to use a 2N3904 specifically, any garden variety NPN transistor is fine. Depending on how fast you want to run your serial connection, you may need to reduce the values of the resistors. The values shown should be fine for 9600 or 19200 baud.
This will invert the signal into the PIC, so you'll need to change the bit in the UART register for active-high/active-low.
The resistor/diode level shifting methods are safe for high-output-to-low-input voltage shifting, but there isn't a safe way to do it low-output-to-high-input, you always have some small current flowing back into the low-voltage supply rail. That is bad because the low-voltage supply can potentially charge up to a higher voltage (most regulators can only source current, not sink). Also, the high value resistors used limit the speed.
Transistors are dirt cheap, no reason to not use them :D
Good luck!
-
I've managed to get it working @ 5 V using 2k pullup resistor, but there was indeed 0.5 mA flowing back into the GSM. I'm not sure if that's enough to damage something.
I'll try to use the transistor now and invert the logic on PIC.
-
I've managed to get it working @ 5 V using 2k pullup resistor, but there was indeed 0.5 mA flowing back into the GSM. I'm not sure if that's enough to damage something.
I'll try to use the transistor now and invert the logic on PIC.
The main issue is if the GSM phone goes into a low-power mode and requires less than the current flowing back into it on its supply rail. Since the internal voltage regulator won't be able to sink the extra current, the internal supply voltage rail will rise up a higher voltage, which can damage things. Since you are working with a "black box" (the phone) you really don't know what's going on inside it.
Edit: Also consider what happens when the battery is removed from the GSM phone: you then have current flowing into the phone's supply rail, but on the output side of the regulator, so the voltage can rise above the normal supply voltage.
-
See the attached image.
That would require negative logic.
What's best is highly subjective. The pull-up idea is simple. But it may not work in all cases.
A more complex approach is to use a logic level mosfet (or bjt + diode). It has the advantage of being positive logic and bi-directional.
-
See the attached image.
That would require negative logic.
Hence why I said to switch the bit in the PIC UART config register.
-
Use a single transistor and two resistors.
Works like a charm! :-+ I don't have any mosfets at home, so I'll stick to this for now.
-
Glad it's working and you can now move on to other (more interesting) things! :)
-
Here is a bjt - implementation of the phillips' bi-directional level shifter.
V1 is the signal to be transmitted and the pick up, in this case, is on the bjt's collector (or emitter in case the transmission is the other way around).
If you only care about 2.7v -> 5v transmission, you can eliminate R1 / D1. If you replace Q1 with a mosfet, you can eliminate R2.
I typically include them all in the layout but don't solder them in if the transmission is one directional.
-
Also, if you aren't sure if the input (RX) on the GSM phone is really 5V tolerant, consider adding level shifting in the other direction as well. In that case (5V down to 2.7V) at only 9600 baud a simple voltage divider will be fine. Try a 1.8k + 2.2k to ground from the PIC TX line and take the output to the phone from the midpoint. (2.2k+2.2k may be close enough, but the output will be a bit low).
If you aren't too concerned about damaging the input on the phone, you can just leave it alone, but two resistors is cheap insurance.
-
Here is a bjt - implementation of the phillips' bi-directional level shifter.
V1 is the signal to be transmitted and the pick up, in this case, is on the bjt's collector (or emitter in case the transmission is the other way around).
If you only care about 2.7v -> 5v transmission, you can eliminate R1 / D1. If you replace Q1 with a mosfet, you can eliminate R2.
I typically include them all in the layout but don't solder them in if the transmission is one directional.
Is a fine circuit for sure, but requires access to the 2.7V supply rail, which I don't believe is available outside the phone....
-
You can simply pad up the output with a led (or diode string) and tie the base to the 5v rail.
-
You can simply pad up the output with a led (or diode string) and tie the base to the 5v rail.
It is definitely a nice level shifter topography, I've used it for I2C level shifting. I guess I just don't really see the advantage in this case if you add more components to drop down the 5V rail down to 2.7V. Then you have to either string diodes together, or find an LED with the right forward drop after tweaking the current through it.
Actually, reading your sentence again, I'm not really sure what you mean "simply pad up the output with an led (or diode string)"? Adding diodes on the collector side (5V side) will just shift the whole 2.7V waveform up by the diode drop. Sure, he could reach the 4V high level required, but then the low level will be up above 1V which is required by the PIC (0.2*VCC for Schmitt Trigger inputs). But perhaps I am misunderstanding what you mean. Either way, I still posit that the inverting unidirectional shifter is the simplest for this application.
-
I would have simply used a pull-up resistor + diode, and call it a day.
-
I would have simply used a pull-up resistor + diode, and call it a day.
I think you must be thinking of 5V to 2.7V translation, in which case a single diode+resistor is perfectly safe.
Show me how you would drive an input > 4V and < 1V from a 2.7V signal with a pull-up resistor and diode only, with no flowing current back into the 2.7V output. You might as well just leave the diode out, and just use a pull-up resistor, as already discussed (not a great idea).
-
Maybe the modem echos commands sent to it?
You really need to hook this thing up to some terminal software so you can see exactly what is being sent by each side.
-
(http://shrani.si/f/2B/gN/1diBUQB4/teraterm.jpg)
(http://shrani.si/f/f/I6/1Mrxipzs/teraterm1.jpg)
Is at displayed here because I typed it, or is it echoed back, how do I know that?
-
Is at displayed here because I typed it, or is it echoed back, how do I know that?
You have "local echo" turned off, so the modem must be echoing it back.