Connect with us

need help with simple 3v to 34v transistor relay/switch

Discussion in 'General Electronics Discussion' started by sideburn, Jun 14, 2013.

Scroll to continue with content
  1. sideburn

    sideburn

    75
    2
    Jun 14, 2013
    OK, I know nothing about timers or interrupts and when I might nee one or both in microcontrollers at the moment so I wouldn't be surprised if the question makes no sense. :)

    Basically what I was getting at is if I have a timer and an/or interrupt. If I were to put a while(1); in my main() would the timer/interrupt hault or would it keep processing? Just curious.
    I guess I have been thinking about timers the wrong way. It is a register. I was thinking more like it was a thread running that I could put code in to do something every certain number of cycles.

    I am familiar with and have written code for various operating systems, cooperative and preemptive. And I am familiar with writing asynchronous and synchronous code. my "day job" is writing software for multiple platforms so what you are saying is sinking in, though it may not seem like it! That being said, I have never bene much of a systems architect type.. So it is a bit of a struggle for me in this area...Bare with me I am paying attention and appreciate your input.
     
    Last edited: Jul 1, 2013
  2. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    If you have an interrupt source (e.g. a timer, or the USART) triggering an interrupt handler, and your mainline goes into a loop, the interrupts will continue to occur and be handled by the interrupt handler, unless you disable interrupts in the mainline.

    Interrupts such as the received character interrupt will be accepted and will cause the interrupt handler to be called as long as the interrupt source is enabled through its individual interrupt source enable, and interrupts are enabled globally. Normally this is done with an instruction, which affects a bit in the flags register. This bit is a global interrupt enable/disable flag. When an interrupt handler is started, the global interrupt enable flag is set to disable, so that an interrupt handler in progress will not be interrupted by another interrupt; the interrupt handler may enable interrupts explicitly in some circumstances. Some architectures also implement a prioritised interrupt scheme where an interrupt handler will not be interrupted by an interrupt of a lower priority even if it has enabled interrupts.

    It's both. You can use a timer interrupt; this is often done. The interrupt may be at regular intervals, or it can be set to occur at a specific time. But if you can avoid interrupts, this can make the firmware design simpler, and that's what I'm suggesting. In this case you need to poll the timer, which is done by reading the timer register. This register counts upwards continuously at a programmed rate.

    Cool! You will probably find this project will improve your understanding of how those operating systems work "underneath". Processor architectures are similar enough that ideas you use for this project will have equivalents on higher-level platforms and operating systems.
     
  3. sideburn

    sideburn

    75
    2
    Jun 14, 2013
    Got it. I'm studying up on timers and interrupts now. I need to have a clear understanding of them, it's helping me get more familiar with how the pic itself works. Yes I have learned a lot already just working on this project. I'm going to experiment with a timer/interrupt for a bit and then resume the multitasking redesign.

    I know I could probably do a hack job and put a usart reader inside of my ringloop etc but I'd rather code it the right way because I know it will bite me later as things get more complex.
     
  4. sideburn

    sideburn

    75
    2
    Jun 14, 2013
    Well I finally finished the coding work. It's working great now but it was a real pain there for a while dealing with the usart and the buffer. I ended up doing a state machine basically. theres a main loop. and thats about it. and then I added an interrupt on the USART for handingling incoming messages form the GSM.

    I can now send the phone text messages and program names/numbers into it and then I can call people by their names. It works great!

    You can add and delete entries. dialing 1,1 redials last outgoing call, dialing 1,2 redials last incoming call.

    I almost ran out of room again on the flash.. I'm still not sure if a for loop uses less space than a while loop vs a strcpy etc.. I learned that pointers are not a good thing for microcontollers too.. im using array instead of ptr++

    I managed to free up about 10% of space by changing all of the ints and longs and shorts as I could to unsigned chars..
     

    Attached Files:

    Last edited: Jul 10, 2013
  5. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    That's great!

    Yes, a state machine is probably the best way to implement your USART interrupt handler on a small micro like the PIC. It's messy and you have to be careful, but it gets you a nice self-contained process.

    You have to be careful with variable ownership though, especially since it's interrupt-driven. Also, if you're doing strcmp()s in the interrupt handler, be aware of the maximum interrupt time, and the latency that will impose on detecting other events in the mainline.

    Re for() and while() loops, there's very little difference in code size. Look at your compiler's assembly language output, if this is accessible, and you'll see they're implemented the same way.

    I'm surprised that you say pointers aren't a good idea. All things being equal, I would expect a comparison or copy via pointers to be more compact than indexed accesses, because it avoids the need to recalculate the pointer value each time. A proper optimising compiler may reduce them to the same thing, but if you're using the free PIC compiler, don't expect it to optimise much.

    Yes you will save a lot of RAM, and significant Flash ROM, by using unsigned chars for variables that only need a 0~255 range, because the natural data size for the small PIC cores is 8 bits. Every time you use a 16-bit (or wider) variable, the compiler will generate multiple instructions, to deal with each 8-bit section of it independently, or a call to an invisible library function, if the operation is deemed complicated enough to warrant it. This wastes time as well as space.

    Congratulations on your achievements!
     
  6. sideburn

    sideburn

    75
    2
    Jun 14, 2013
    Thanks, I've been obsessed with it and haven't had much sleep since I started.
    I ran into a lot of problems trying to do too much inside my interrupt. I still don't quite understand the USART completely.. I guess if you don't grab the bytes from RCREG right away, you lose them.. or if you don't respond to RCIF right away you lose them. Thats' a gray area for me and was a challenge. The other challenge was some situations (like incoming SMS messages) come in in two lines.. I was resetting the buffer index after every cr/lf..That was a problem because the first line was the incoming SMS message ID with the senders phone number, which I needed in order to auto-respond to them.. and the next line after the cr/lf was the message itself that I needed. So in some cases I needed to capture 2 or more lines of text and in other cases I only needed one line. I solved it by checking the first few bytes for the incoming message and then using a linefeeds counter to determine how many cr/lf's to capture beffore setting terminating the input stream with a '\0'

    And the more I did in the interrupt the worse things got. and strstr's and strchr's were eating up too much time so i ended up doing if(inputBuffer[0] == '+' &&... to deal with it.

    On pointers, I had a terrible time in MPLAB's debugger trying to look at pointer values and it was always not what I was expecting.. That is one reason I quit using them. I use them a couple times when passing strings to functions but thats about it. Also,I read that pointers on the PIC are 16 bits long it's only an 8 bit processor. This means means that things like pointer addition (ptr++) actually takes two instructions.. Not that I care that much I'm running at 4mhz and its plenty fast enough. I thought about bumping it up to 8 though thinking it might make dealing with the USART easier but then I figured it wouldn't matter much since its running at 9600 baud.. But again, gray area for me..

    Yeah I am using the free version of the High-tech compiler. When I was at about 98.9% full I thought about diving in and getting the pro version but then I found out it's $1,000.00 so I decided to just tighten up my code. Reminds me of how it was back in the 80's when you really and to pay attention to your memory usage. I can't believe some of the things the game programmers pulled off with 4K or less back then.


    I've posted a blog page that gives the basic rundown in non techy terms of how the thing ended up here: www.retrocell.net

    I'm about ready to send my eagle files up to http://oshpark.com and get some boards made. That will be a first for me too.
    My board has no .1uf filter caps anywhere and only 1 or two pull-up resistors but its all working ok. I'm not sure about when and where I need caps. I think they are usually .1uf. and pull downs pull ups, I think I am ok with using the weak pull-ups on RB. I am using RA for outputs mostly.

    I need to wrap this project up, get back to real-paying gigs before they all fire me! And then I've got another project in mind that involves controlling servos from a pic so I have to learn how to do that next. I guess its PWM so I just oscillate a pin on and off to drive the servo. I might use a GSM again too I like the idea of controlling things with text messages.
     
    Last edited: Jul 10, 2013
  7. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    I know that feeling! I'll PM you my email address. Please feel free to ask me anything. I would be happy to help. This sort of stuff was my job for 20 years!

    Yes, you have to service the USART receiver before the next complete byte is received, otherwise you lose data. At 9600 bps asynchronous, if the GPS device is sending bytes end-to-end (and you can assume that it does), the minimum byte-to-byte time is 1042 microseconds, so that's how long you have to read the received data register, from the time the interrupt is signalled. If you don't read it by then, a byte (either that byte, or the next byte, depending on the design of the USART), will be lost.
    You can generalise the design a bit if you want to. If the first character of a line is not a letter, treat it as a phone number. You can pack two digits into each byte of storage using four bits to represent each character: values 0-9 represent the digits, and other characters such as "+" and possibly "-" which might appear in the string can be coded as 0xA, 0xB etc, or just thrown out, if the phone number string is always in a standard format. The end of the number could be marked with a 0xF nibble. Or you could use a nibble of 0x0 to signal the end, and use values 0x1 to 0xA for digits 1-9 and 0. Then set a flag saying that there's a valid phone number. When the subsequent line has been received, check the flag, and report the number to the mainline.

    You should be able to calculate a maximum length for the number string. Assuming a three-digit country code, three-digit area code, and nine-digit number (which seem like reasonable maximums for the foreseeable future), you need fifteen digits and a terminator, so eight bytes should be enough.
    Personally I prefer the idea of matching the text strings as they are received, rather than storing them in a buffer - at least in a simple application like this. It saves RAM, obviously, which is in pretty short supply on the small PICs, but most importantly it spreads out the workload over several interrupts, instead of concentrating a multi-character comparison (either explicit, or with strcmp()) in a single interrupt.
    I can't comment because I haven't used MPLAB.
    If the PIC has 256 bytes of RAM or less, and code can't be accessed through pointers, pointers would only need to be eight bits wide. If they're 16 bits wide, my guess would be that the compiler would treat bytearray[n] the same as *(&bytearray[0] + n) so 16-bit pointers would be used anyway, even though no pointer variables are declared. But compilers for highly constrained architectures often use target-specific and non-standard tricks to improve efficiency, so you may be right to assume that bytearray[n] will generate more efficient code than a *cp access. You would have to look at the assembly language output to know for sure.

    Edit:
    Of course, pointers need to be able to point to immutable (const) initialised data in the code space. RAM is so highly constrained that immutable data will not be copied into RAM; it will reside in Flash ROM at runtime. So you're probably right. Generalised pointers will need to be 16 bits wide, even if there's 256 bytes of RAM or less, because they need to be able to address either RAM or Flash ROM, but when the compiler knows that you're addressing data that's in RAM, it can probably take a shortcut and use an 8-bit address.

    I'm not familiar with the memory layout of the PIC but I'm pretty sure you can't access RAM and Flash ROM in the same address space through a simple pointer; I suspect the compiler must generate code to handle dereferencing of a generic pointer according to whether it addresses RAM or Flash ROM.
    I don't understand what you're getting at.
    Ah yes, those were the days :) When programmers were REAL men. Or REAL geeks :)
    That sounds interesting. I'll check it out when I get my full speed broadband back. Somehow I always seem to hit my data limit a week or two into my monthly allowance, and I have to limp by on 64kbps for the next two or three weeks :-(
    Perhaps you should post your schematic here before you send it off for manufacture, so we can check for obvious problems.
    You should definitely have a decoupler across the PIC, at least.
    Are you doing this for your employer?
    That will be interesting :)
     
    Last edited: Jul 10, 2013
  8. sideburn

    sideburn

    75
    2
    Jun 14, 2013
    Great, I've been in the business about that long too.. Since about 1992.. But I never went to engineering school so I have just been winging it my whole life... Basically I started out taking my toys apart and turning them into other things, then I got my first computer, A TRS-80 and I was off and running..
    My first job in the field was fixing circuit boards actually but again I was winging it.. I had an osciloscope and basic understanding of electronics and digital circuits. But soon after I moved into software and my electronics days kind of came to an end. So I am kind of rekindling my early electronics interests with this project. And In my software career I was always writing software for other peoples hardware..

    I will have plenty to keep you busy I am sure. Especially when I start trying to drive servos. I think my weakest area is on the electronics side of things.

    OK that's in line with what I was thinking. And during testing, if I blasted it a bunch of text messages one after another and simultaniously form 2 phones, all of those get lost. But at least its not hanging anymore.. Early I was getting in a trap where the RCREG had data but RCIF and the interrupt were not flagging, so everything would hang on me.

    It works a bit differently.

    An incoming SMS message looks like this:

    Code:
    +CMT: "+17605558767","","13/07/08,12:41:10-28"
    Hello there, this is my text message
    
    So by the time my routine that checks for incoming strings see's it it was only seeing the 2nd line and I could not back up and get the phone number out of the previous string. So what I did was the interrupt routine looks for "+CMT:" and then it knows skip past the first linefeed and capture the next before setting the bufferindex to 0. then my code that monitors the buffer does not do anything until bufferindex is 0.

    There are other cases where you get multiple lines.. like doing an address book lookup. I
    I am actually doing something pretty nasty in that area. When I lookup a name I am just capturing 1 of the lines, the first one.. but it is returning something like this:

    Code:
    +CPBF: 7,"7467757746",129,"Tavis"
    
    OK
    And my code watching the input buffer is getting the 'OK'.. but my buffer is 80 bytes so the previous string is still in memory and I jump forward and get the previous string containing the phone number "7467757746" I know... thats terrible but it works..

    Right now my code is pretty constrained. It looks for 10 digits (USA)... When it sees all 10 it places the call.. Unless you pause during dialing for 4 seconds and then it tries to lookup the dial you numbered inthe address book.

    I like that too, but I need to do this fast or I start losing characters. I could do some experimenting with this technique.

    You obviously understand this better than I do.. My makes my brain hurt.

    I just meant I thought that maybe increasing the clock speed would help in capturing the data from the USART better since it would be polling the input buffer faster.


    Attached. JP9 is the audio in and out from the GSM. Handset is the mic and speaker. RA7 is set set hi and low as the switch in hte rotary bounces when you dial to create that pulsing sound you used to hear inthe handset when you dialed. Thats what R5 and D2 are there for. R5 just lowers the volume level of the pulsing and D2 keeps current from the GSM from going back into the pic. I don't know if I did this correctly but it works...

    No this is just a personal project. I am a freelance software developer / web designer and I have been pushing them aside while I work on this and falling behind! I need to catch up before they start catching on :)


    Baiscally, this project will be an animated art piece. My dad is an artist and he has been making this really cool looking cybernetic sculpture guy.We are putting about 6 servos in it to control the eyebrows, head, mouth, eyes and other things around him. for starters I am going to hook it all to a 6 channel RC receiver But I want to end up making him self operating by using a microcontroller. I am also thinking of putting some 7 segment LEDs around it that are generating random alien looking characters or something like that.

    I've also bough a text to speech synthesizer board that I was thinking of maybe adding to it with a GSM so you could text it and he would repeat what you sent. And his mouth would need to move to the audio output so I will need to drive the servo based on the sound coming in. I am assuming I would/could use the PIC analog inputs for that.
     

    Attached Files:

    Last edited: Jul 10, 2013
  9. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    RCREG always "has data", in that if you read it, you will get a byte value. RCIF tells you whether it has NEW UNREAD data. Whenever you detect RCIF set, you read RCREG to get the new data byte; this also resets RCIF. It shouldn't be possible to get into a state where RCREG "has NEW data" but RCIF is 0.
    OK. The important thing to understand is that you need to be able to get the data out of the buffer and process it before it gets overwirtten. To do this properly, your simplest option is a small queue, aka a circular buffer, to hold received characters. You use pointers or offsets for PUT (used by the USART received character interrupt handler, which puts characters into the queue as they're received) and GET, which is used by a function called regularly by the mainline, that takes characters out of the queue and makes sense of them.

    This line buffering and processing function would need to be written as a simple state machine. It could start by building up the line in a linear buffer, controlled by received newline characters. When the newline is received, it would (directly, or by calling another function) deal with the line it has built up.

    Since the USART received characters are being buffered in the queue, the timing constraint on the line buffering function is very loose. Since the line buffering function only takes characters out of the queue when it's ready to, the line buffer cannot be overwritten by new data until it has been processed.
    In that case I would use two line buffers and alternate between them. When you receive the "OK" with its newline, you already have the previous line in a safe place.

    Usually, improving the structure of the code is a better idea than throwing horsepower at the problem.

    Re: schematic
    I don't like that much, but as you say, it works...

    Here are some other comments I have on the schematic.

    All three LEDs should have resistors in series with them to limit the current through them. In the case of the LEDs that are driven by the PIC, having no resistor means that the PIC pin is clamped to the LED forward voltage, which is typically 2~3V, but the LED will probably not be damaged. For the LED that's driven by the MOSFET, the LED will be damaged by excessive current unless you add a limiting resistor.

    For Q1 I would use a gruntier device. We found that the bell only draws about 30 mA, which is well within the rating of a BC338, but still I'm uncomfortable with using such a small device. transistor; Actually, I would use an N-channel MOSFET rated for at least 1A and 60V, with a low Vgs(th) voltage so it will saturate fully with the 3.7V bias from the PIC.

    Ah, work. Dammit!
    Sounds interesting
    That might work if you just want the mouth to open and close. If you want to animate it properly, you'll need a number of devices to make the different shapes formed by the lips and tongue, and you'd also need some kind of information on the phonemes being simulated. Now THAT would be cool!
     
  10. sideburn

    sideburn

    75
    2
    Jun 14, 2013
    On the RCIF interrup code I ended up checking for specific commands coming in from the gsm. Incoming SMS and Address book look ups. Then I controll the buffering accoring to that. that way only need one buffer that I can use elsewhere too keep the ram usage down.

    Ah yes, I will add resisters to the led's. The one LED for the boos power inticator is not connected to the 34v output side of the MOSFET, it is the gate side so It is only 3v but it should also have an LED though.. Are you saying there would still be spikes of current that will damage it eventually as it is now?

    I have been testing it out this weekend and everythign is working well but the GSM does occasionally shut down on me. Probably because it is starting for more voltage.
     
  11. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    The LED that's connected straight across the supply voltage going into the boost converter will be damaged if it doesn't have a series resistor. Not by spikes of current; just by the heavy current that will flow when you try to apply 3.7V across a LED with a forward voltage of 2~3V. LEDs are current-driven devices and will be damaged if you try to force a voltage across them.
     
  12. sideburn

    sideburn

    75
    2
    Jun 14, 2013
    OK I thought at 3.7v I would be safe.. So far they have been holding up but I will add some resistors to them. about 70ohm? Also should I only add 1 .1uf filter cap between the input VCC and GND next to the battery connector?
     
  13. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    The proper value depends on the voltage across the resistor, which depends on the forward voltage of the LED, which depends on the colour and type.

    Find out the forward voltage of each LED, subtract that from 3.7, and calculate the resistance using Ohm's Law, R = V / I where V is the remaining voltage across the resistor and I is the desired forward current in amps. LEDs are often run at 20 mA but I would use 10 mA for the ones that are connected to PIC pins, to reduce loading on the PIC.

    You should have a 0.1 uF decoupling capacitor for the PIC, connected as directly as possible between the VDD and VSS pins of the PIC device itself. Also it's common to have a bit of bulk decoupling - for example, 100 uF - on the supply rail somewhere.
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-