PDA

View Full Version : PWM and MEMORY



pescador
- 13th May 2016, 12:32
I designed a board using a 12F683 to provide a PWM signal to dim lights. Works great. Now I need to have it function where if the power is turned off - it remembers the values it had when it was shut off. Can someone help me choose a new micro-controller and how to implement that function? I'd like to keep the package size - 8 pins. I only need to store 1 byte - the duty cycle number from 1 to 255.

Charlie
- 13th May 2016, 12:49
Simply use the device you already have, but write your code so that you keep those values in a specific location, then read from that location as the starting values on power-up. As the program progresses you can change the values as needed, but it always starts by looking at that special location. You could use the EEPROM area, but the regular memory area is flash, and so it will also preserve the value for years when the power is off.

pescador
- 13th May 2016, 12:52
Good - now I need to figure (read my brains out) how to save and retrieve that variable. I do it once I'll have it forever..

$25 for the first person to show me how with code, I'll show you my existing code and we can work together - is this legal to do in this forum?

HenrikOlsson
- 13th May 2016, 12:53
No need to change microcontroller. The 12F683 has 256 bytes of EEPROM in which you can store whatever you want. Use the WRITE and READ commands to store and retrieve your values.
How to implement it depends on how often the value changes. The EEPROM has an finite number of write cycles so if the value changed several times per second it's not a good idea to constantly write it to the EEPROM, in that case you need som power fail signal which triggers a write. If the value doesn't change very often a simple timer which triggers a write after 5 seconds (or whatever) of unchanged value should be good enough.

/Henrik.

HenrikOlsson
- 13th May 2016, 12:55
You could use the EEPROM area, but the regular memory area is flash, and so it will also preserve the value for years when the power is off.
The 12F series can't write to its own FLASH memory so you have to use the EEPROM if you want the value to be changeable AND persistent.

/Henrik.

mackrackit
- 13th May 2016, 12:57
The 12F683 has an EEPROM.

Depending on how often your light signal changes, write that value to the EEPROM. When the chip boots have it read the EEPROM first to get the value for PWM.

Or if this is only for scheduled shut downs write a shut down sequence to save the value.

--edit--
While I was typing the question was answered...

pescador
- 13th May 2016, 13:00
The rate changes with the push of a button - duty cycle decrements from 128 to 10 and start back to 128. I found 128 is the brightest my leds will go. The user can hold the button in and it auto counts down, goes dim, then goes back to 128. I dont know how but the PWM command resets itself to 128 - the original value - without me having to maker it 128. If that makes sense. I'll post my simple code in next post.

pescador
- 13th May 2016, 13:01
The 12F series can't write to its own FLASH memory so you have to use the EEPROM if you want the value to be changeable AND persistent


uh oh - what? - I cant use a 12f683?

pescador
- 13th May 2016, 13:06
'12f683

' ======= config SETUP =================================

#CONFIG
cfg = _INTOSCIO
cfg&= _WDT_ON
cfg&= _PWRTE_OFF
cfg&= _MCLRE_OFF
cfg&= _CP_OFF
cfg&= _CPD_OFF
cfg&= _BOD_ON
cfg&= _IESO_ON
cfg&= _FCMEN_ON
__CONFIG cfg
#ENDCONFIG

' ======= Common Settings =================================

OSCCON = %01110001 ' Internal 8MHz osc.
DEFINE OSC 8
CMCON0 = 7
ANSEL = 0
OUTPUT GPIO.1
INPUT GPIO.4

PLEDOUT var GPIO.2 ' PWM output
BUTTEN var GPIO.4 ' BUTTON IN

HERTZ VAR byte
DUTY VAR byte

DUTY = 128
HERTZ = 50


MAIN:

pwm pledout,duty,HERTZ ' PLM output

IF BUTTEN = 0 THEN
DUTY = DUTY - 2
IF DUTY < 10 THEN
DUTY = 128
ENDIF
ENDIF

GOTO MAIN
END

pescador
- 13th May 2016, 13:15
cmon guys - help me out here... can a 12f683 do the job?

HenrikOlsson
- 13th May 2016, 13:18
No one said the 12F683 can't do the job. It can.
Charlie implied that you could store your value in the FLASH memory - which you can, as a non changeable constant of course - but if you need to be able to change it and store it during runtime, which is what you're asking about then the FLASH memory can't be used because the 12F series lack the abillity to write to its own FLASH memory.

The EEPROM on the other hand will work just fine. Look at READ and WRITE in the manual.

/Henrik.

pescador
- 13th May 2016, 13:19
What I think I'm reading is from all this is I need an extra chip (EEPROM) to store my variable if its changing all the time. It will change, the user can press the dim button at will - and it needs to remember that value when powered down.

I can change the design - if its not a 12F - what could I use in its place? - or I just add an EEPROM.

richard
- 13th May 2016, 13:32
perhaps a read of the 1st page of the pic12f683 data sheet would let the penny drop

ps a 12f1822 can write to its flash

mackrackit
- 13th May 2016, 13:32
Use the EEPROM on the 12F683. No need for an external EEPROM.

pedja089
- 13th May 2016, 13:32
How about to look datasheet for your pic, and manual for PBP?
You may find nice little surprise inside.

pescador
- 13th May 2016, 13:35
How about to look datasheet for your pic, and manual for PBP?
You may find nice little surprise inside.

I'm reading my brains out - dont kid yourself...I'm asking to save time...I'm scrambling - if you read my posts I'm offering cash for advice..

pescador
- 13th May 2016, 13:38
perhaps a read of the 1st page of the pic12f683 data sheet would let the penny drop

ps a 12f1822 can write to its flash


thats the spirit.... thanks for the ps..

pescador
- 13th May 2016, 13:40
ok I'm a bit slow - I'm old... the 683 has an EEPROM - I'll read after my day job how to do it - thanks guys...

any advice on the code I already have would be nice...

pedja089
- 13th May 2016, 13:42
No need to change microcontroller. The 12F683 has 256 bytes of EEPROM in which you can store whatever you want. Use the WRITE and READ commands to store and retrieve your values./Henrik.
Com on, you won't read what is written here, won't read datasheet. And you are willing to throw little money someone, just to write you what is already said few times..

richard
- 13th May 2016, 13:48
i think your missing the point , if you cant work out how to use the eprom on the 12f683 you already have then good luck with flash writes , it only 4 times more complicated.
and don't forget flash mem has only 1/10 of the endurance of eprom mem

paid gigs would be a new concept here ,theres no frame work for it yet.

Jerson
- 13th May 2016, 16:40
'12f683

' ======= config SETUP =================================

#CONFIG
cfg = _INTOSCIO
cfg&= _WDT_ON
cfg&= _PWRTE_OFF
cfg&= _MCLRE_OFF
cfg&= _CP_OFF
cfg&= _CPD_OFF
cfg&= _BOD_ON
cfg&= _IESO_ON
cfg&= _FCMEN_ON
__CONFIG cfg
#ENDCONFIG

' ======= Common Settings =================================

OSCCON = %01110001 ' Internal 8MHz osc.
DEFINE OSC 8
CMCON0 = 7
ANSEL = 0
OUTPUT GPIO.1
INPUT GPIO.4

PLEDOUT var GPIO.2 ' PWM output
BUTTEN var GPIO.4 ' BUTTON IN

HERTZ VAR byte
DUTY VAR byte

' DUTY = 128 ' this is not needed any longer
HERTZ = 50



read EE_Duty, Duty ' read from EEPROM address EE_Duty to Duty variable
if Duty > 128 then Duty = 128 ' limit the duty to 128 if it is > 128

MAIN:

pwm pledout,duty,HERTZ ' PLM output

IF BUTTEN = 0 THEN
DUTY = DUTY - 2
IF DUTY < 10 THEN
DUTY = 128
ENDIF

' save the new duty to eeprom
write EE_Duty, Duty
ENDIF

GOTO MAIN
END
Hope this helps

pescador
- 13th May 2016, 20:54
Com on, you won't read what is written here, won't read datasheet. And you are willing to throw little money someone, just to write you what is already said few times..

I was in a rush this morning - I'm getting it.. I admit I panicked.. I do read - I work 80- hours a week - 40 hours at a real good job and 40 my own business... I try to save time sometimes...

pescador
- 13th May 2016, 21:01
Jerson - I notice you have code on top of main: - the read and if - is that meant to be in the main? It actually compiled - and I have no endif for the if Duty > 128 statement... I dont understand this...

plus I created a word var - EE_DUTY...

update - works great - its what I needed.. I reduced the hertz to make it less choppy.

What I dont understand is the if without the endif above the main. Hope someone can clarify..

can I quick pay you?

pescador
- 13th May 2016, 21:24
1/2 my lab in basement - pick and place in foreground.. work area and test on right.

Heckler
- 13th May 2016, 21:33
you only need the "endif" if the "if" statement takes up more than one line...

IF A=B THEN dosomething

versus...

IF A=B THEN
dosomething
ELSE
IF B>A THEN
dosomethingelse
ENDIIF

And as far as your question to Jersen...
It looks to me that he is just having the code check the stored value in EE memory only on power up (or after a reset).
You would not need to keep checking the stored value in EE every time the program loops
You only wanted to retrieve the last stored value on power up so it does not need to be in the Main block.


check the PBP manual for the IF statement...


5.35 IF..THEN
IF Comp {AND/OR Comp...} THEN Label
IF Comp {AND/OR Comp...} THEN Statement...
IF Comp {AND/OR Comp...} THEN
Statement...
{ELSEIF Comp {AND/OR Comp...} THEN
Statement...}
{ELSE
Statement...}
ENDIF


hope this helps
dwight

Nice lab!!
lets see the other half (or is that where all the dead bodies are) :D

pescador
- 13th May 2016, 21:38
thanks Dwight - do the commands above the main only happen once? - I thought once it hits main and we loop on main that it doesn't occur again - we read then the value only once.

Obvious answer maybe - ...

pescador
- 13th May 2016, 21:45
pic of board - 2 layer board with a 5v reg connected to a 12f683 - fet driving output pin with ground activating the changing of PWM duty cycle. I'm doing a bit of conditioning of the pwm out of pin 5 with a 1uf to ground and 4.7k resistor to the base of a NPN 3904 transistor, driving a P channel Fet

just a prototype..

works good so far!!

thanks everyone!!!

richard
- 13th May 2016, 23:08
pwm out of pin 5 with a 1uf to ground and 4.7k resistor to the base of a NPN 3904 transistor, driving a P channel Fet

for my 2 cents worth , the 1uf to ground probably just makes the fet switch slower and dissipate more energy . if the pwm freq is high enough and
if the light is for humans then pwm flicker is invisible even at 50 Hz [can you see your mains freq ac lighting flicker ?]

Jerson
- 14th May 2016, 04:07
Jerson - I notice you have code on top of main: - the read and if - is that meant to be in the main? It actually compiled - and I have no endif for the if Duty > 128 statement... I dont understand this...

plus I created a word var - EE_DUTY...

update - works great - its what I needed.. I reduced the hertz to make it less choppy.

What I dont understand is the if without the endif above the main. Hope someone can clarify..

can I quick pay you?
I did not notice that. I meant to give you a quick hand up from where you were.

And the code


if duty > 128 then duty = 128

is supposed to lock down the duty value to max 128. This comes in handy when the chip is newly programmed and the eeprom will read the value of duty as $FF.

Can you quick pay me - of course not - thank you. That's what we are here for. Lend a helping hand. It's you who learnt something out of it and I was once in your shoes.

Jerson
- 14th May 2016, 04:07
Jerson - I notice you have code on top of main: - the read and if - is that meant to be in the main? It actually compiled - and I have no endif for the if Duty > 128 statement... I dont understand this...

plus I created a word var - EE_DUTY...

update - works great - its what I needed.. I reduced the hertz to make it less choppy.

What I dont understand is the if without the endif above the main. Hope someone can clarify..

can I quick pay you?
I meant to give you a quick hand up from where you were.

And the code


if duty > 128 then duty = 128

is supposed to lock down the duty value to max 128. This comes in handy when the chip is newly programmed and the eeprom will read the value of duty as $FF.

Can you quick pay me - of course not - thank you. That's what we are here for. Lend a helping hand. It's you who learnt something out of it and I was once in your shoes.

Jerson
- 14th May 2016, 04:10
Wish I could give a thumbs up for getting your board to work. You have a nice lab.

pescador
- 14th May 2016, 12:45
Moral of the story is - things sometimes appear more complicated than they really are. Simply 2 or 3 lines of code solved this problem when to me for awhile it seemed like I had to address memory space in an external chip and constantly refresh that memory space every time I did a button push.

PICBASIC made it very simple.

My project was a lLED dimmer. I'm using a 12f683 to produce a pulse width modulated (PWM) signal from pin 5 that's constantly on. It drives a P channel FET that provides a +12V pulse to the anodes of LEDs in parallel - common ground on the cathodes. The FET is capable of driving up to 14 amps of current, though that's way overkill for this application. I have a pullup resistor on pin 3 to +5V, with reverse polarity protection in case the user puts +12V to that pin, blowing up the PIC. A button tied to ground connects to pin 3. When the button is pushed, it provides a low to pin 3 and my code adjusts the duty cycle of the PWM command. (pwm ledout,duty,HERTZ). I did not debounce the signal - maybe on next rev. I probably do not need to condition the PWM signal with a cap and resistor in this application.

What I ignored was that when the circuit is powered up it needed to remember what brightness the leds were at when it was powered down - you don't adjust your dash lights in your car every time you start it. (dumb of me to not think of this).

Create a variable for the value you want to store - do a READ command, first value on initial power up is $ff - 255 unless you force it to another desired number - in my case 128 for the duty cycle of my PWM pulse.
Then do a WRITE command to the internal EEPROM on the 12f683 after each button push. I'm only writing one number (word) to the register - so I'm not worried about space. (it does write to same location - right?). Writing after each button push did affect the leds constant on, so I adjusted the HERTZ variable to remove blinking.

Power cycle the PIC and the PIC reads the EEPROM with the READ command and viola, the LEDs are the same brightness as when the PIC was turned off..


Simple -

thanks everyone..

pescador
- 14th May 2016, 13:20
Schematic...

pescador
- 25th May 2016, 13:19
for my 2 cents worth , the 1uf to ground probably just makes the fet switch slower and dissipate more energy . if the pwm freq is high enough and
if the light is for humans then pwm flicker is invisible even at 50 Hz [can you see your mains freq ac lighting flicker ?]


update - you were right - I had to remove the cap (base to ground on npn) altogether for the PWM to even work. I was using a .1uf - seems it was filtering off the signal. I didn't look too much into it as why with a scope - just removed it. The user manual puts comments in there like the pulse coming out of the PIC isn't really clean so I thought I'd clean it up. No need..