View previous topic :: View next topic |
Author |
Message |
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Tue Dec 18, 2012 8:59 am Post subject: Strange behavior, atmega88pa |
|
|
Hello everybody,
I have just started using Bascom, version 2076. I'm working with an atmega88pa. I have written a small program that is displaying some strange behavior during run time.
It runs fine in the simulator, but does not run the same on the controller. For instance, I have this in my code:
if RUN = &H01
'- Perform auto-sweeping (ramp up/down) try to find a match
If Setpoint > Current_val Then '- If our setpoint is greater than our actual current flow.
If Compare1a > &H3FE Then '- Do not let the value go over. (At max do not increase it)
Goto Bail_out_h '- PWM_DUTY is at max bail out.
End If '- If not, then go for increase
Compare1a = Compare1a + &H0001 '- Increment duty ratio (raise the current)
Exit Sub
End If '- End if for: Setpoint > Current_val
If Setpoint < Current_val Then '- If our setpoint is less than our actual current flow
If Compare1a =< &H01 Then '- Do not let the value go lower. (At min do not decrease it)
Goto Bail_out_l '- PWM_DUTY is at min bail out
End If '- If not, then go for decrease
Compare1a = Compare1a - &H0001 '- Decrease duty ratio (lower the current)
Exit Sub
End If
Bail_out_h: '- At max pwm value
Compare1a = &H03FF '- Highest Value
Exit Sub
Bail_out_l: '- At min pwm value
Compare1a = &H0000 '- Lowest Value
Exit Sub
Else '- If not, then RUN will be equal to 0x00 (Start button was not pressed or we are paused)
''Run = &H00 '- Keep Run Mode at 0x00
''Compare1a = &H00 '- Set the PWM_DUTY vairable to 0x00
''Disable Timer1 '- Stops the PWM-16bit module on Timer/Counter1 (Turn off the pulse width modulation)
''Portb.3 = 0 '- PortB PB3 Low level signal (Output for switching the h-bridge)
''Portb.4 = 0 '- PortB PB4 Low level signal (Output for switching the h-bridge)
''Disable Interrupts '- Disable the Global interupt
End If '- End if for: RUN = 0x01
End Sub
This is setup so that If the Compare1a value is higher than 0x03FE (0x03FF) it will jump to Bail_out-h and keep it set for 0x03FF. (do not increase it) The same holds true for the lower value, if Compare1a is less that 0x01 (0x00), jump to Bail_out_l and write set it for 0x00.
This works in the simulator, but when on the micro controller, Current_val becomes higher than the set point. it will start to decrease the Compare1a register as it should. However, it does not stop when it gets to a value of 0x01 or 0x00. It is still somehow decreases the compare1a value, resulting in the campare1a value rolling over to 0x03FF and having to count down once again.
It does not do this on the high value of ox03FF, it holds it there as it should.
I have also noticed a variable being changed, the RUN variable some how gets changed from 0x01 to a 0x00 and kicks it out of run mode, this occurs at random times.
Also if, I debug this code in AVR Studio 6 it would seem as if something strange is occurring while single stepping of the code (F11 key). if I just let the program run(F5 key) I can see the pwm rolling over on the scope., but If I break all, then single step through it, it will end up going to the "End" statement after the loop command in the main do loop. Like it somehow has the return address messed up.
It does that right after a read of the ADC and single stepping of the code, the ADC is read just prior to running the above code. If I place a break point on that End statement and just let it run, it will not break there, but only while single stepping through after an adc reading will it get to the end statement.
I would not think this is normal, as it should not be making it to the end statement, as it's supposed to be in a loop.
I did look into:
$regfile = "m88pdef.dat"
$crystal = 8000000
$hwstack = 80 '40
$swstack = 32 '16
$framesize = 64 '32
I have doubled the sizes for them, but I'm not to sure how they should be setup for correct operation.
Can somebody shed some light on this?
Thanks,
Robert |
|
Back to top |
|
|
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Tue Dec 18, 2012 11:03 am Post subject: |
|
|
Well, I did some checking and found that, it was elsewhere in my program that was causing the strange behavior.
when I simulated the entire code is when I found a problem
I'm still having trouble with it popping out of run mode, but this too, I suspect will be caused by a mistake on my part.
Cheers,
Robert |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Tue Dec 18, 2012 11:11 am Post subject: |
|
|
a bad OVERLAY can do that.
in most cases it is simple : check the variables that are dimmed before the one that is overwritten. And check them in your code. _________________ Mark |
|
Back to top |
|
|
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Tue Dec 18, 2012 2:16 pm Post subject: |
|
|
When you say overlay,
Then you are referring to the $swstack possibly being to small? (not large enough to hold all of the variables?
This is where all of my variables will be stored ?
How would I really know what to set it too? Do I just add up all of the variable sizes and go from there?
$regfile = "m88pdef.dat"
$crystal = 8000000
$hwstack = 80 '40
$swstack = 32 '16 <----------- This guy may need to be bigger ?
$framesize = 64 '32
Is there a good book for Noobs in Bascom Avr?
Robert |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Tue Dec 18, 2012 2:23 pm Post subject: |
|
|
overlay :
dim b1 as byte, b2 as byte
dim W as word AT b1 overlay
b2=1 : print w
while convenient it also can be dangerous since you can also overlay strings and bytes. but since you did not knew i guess you were not using overlay _________________ Mark |
|
Back to top |
|
|
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Tue Dec 18, 2012 3:10 pm Post subject: |
|
|
That would be correct,
I'm not doing any of that in this code.
Everything is just set up as:
Dim this as word
Dim that as byte
all at the beginning of the code
I did however play around with:
$regfile = "m88pdef.dat"
$crystal = 8000000
$hwstack = 256
$swstack = 256
$framesize = 256
I set them all pretty good sized, That seems to stop the pwm value from rolling over and stops it from dropping out of run mode.
But now, it won't let me change modes while running and the pause button is also being ignored.
But the ADC is reading fine on both channels, and all interrupts are working.
So it would seem that this has something to do with it:
$regfile = "m88pdef.dat"
$crystal = 8000000
$hwstack = 256
$swstack = 256
$framesize = 256
What is the correct way to set that up?
Thanks,
Robert |
|
Back to top |
|
|
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Tue Dec 18, 2012 3:16 pm Post subject: |
|
|
Hmmm,
I see what you mean by overlay, yes I could see where that could cause some problems if you were not careful.
Could save you some space though.
I'm going to have to look into that, as I will be doing a project soon an a tiny series avr. (may come in handy)
Thanks
Robert |
|
Back to top |
|
|
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Sun Dec 30, 2012 12:55 pm Post subject: |
|
|
Well I have pretty much finished this project,
I changed from using:
Sub
end sub
to just using labels gosub and return. This fixed all of the strange behavior that the program was having.
I'm now trying to measure resistance in the micro-controller. I'm doing this by using 10 bit PWM and a current sensor.
The output voltage ranges from 0.0 to 30.0 vdc in 1023 steps(10bit)
So lets say the PWM value is at 0x01FF (50%) that comes out to 14.93 Vdc (.0293vdc per step) and a current flow of .0035 ma
using ohms law it would be: 14.93 / .0035 = 4265 ohms
so I made the code like this:
Dim Current_val As Word '- Current sensor reading
Dim Ppm_hold As String * 16 '- Storage for the ppm value as a string (for conversions)
Dim Ppm_hold2 As Word
Res_Calc
Ppm_hold = Hex(current_val) '- Convert this value to a string
Ppm_hold2 = Hexval(ppm_hold) '- Convert the string to a numeric value
Ppm_hold2 = Ppm_hold2 * 0.0293 '- Get the voltage
Ppm_val = Ppm_hold2 / Current_val '- Get the resistance
Return
Current val is in hex from the current sensor, do I really need to convert this to a string then to decimal to perform the calculations?
is there an easier way to covert the hex value to a decimal value?
thanks,
Robert |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sun Dec 30, 2012 1:44 pm Post subject: |
|
|
Robert_d1968 wrote: | Sub
end sub
to just using labels gosub and return. This fixed all of the strange behavior that the program was having. |
Hmm, if this has an effect, you do some really weird programming.
Sub()/End Sub and Label:/Return is identical.
Quote: | Current val is in hex from the current sensor, do I really need to convert this to a string then to decimal to perform the calculations? |
This reassures me, that in fact you do weird programming
Where did you learn such nonsense ?
As more multiplying an integer with a float constant
Code: | Ppm_hold2 = Ppm_hold2 * 0.0293 |
won't work, the multiplier is zero as seen as integer, so the result is also always zero.
That's why your code won't work at all, and that makes me wonder, as you seem to describe it as working approach, however it is not. |
|
Back to top |
|
|
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Sun Dec 30, 2012 4:33 pm Post subject: |
|
|
That is not a working approach,
as far as :
Sub
End sub
I used this in the program at first, but for some reason it always did some strange things, so I switched to labels and returns.
Since the switch to using them, I have had no more wrong return address issues.
Maybe it was in my code someplace, but it matters not now, as it's working fine.
As far as "Current val is in hex from the current sensor, do I really need to convert this to a string then to decimal to perform the calculations"
This was construed through the help, index in Bascom. I was trying to see how to change a hex value into a decimal value
But matters not as, The voltage is represented by the PWM value (Compare1a) divided by the current sensor reading in hex gives the resistance in hex value.
So it's not that I learned strange things, I was simply trying something new. This is my first time using Bascom to write programs in for the avr, but it is most certainly not my first program.
I have been programming in one form or another in basic for the last 20 years. Weather in Real basic, Power basic or just assembly language itself (not basic) or even Q basic. |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sun Dec 30, 2012 5:34 pm Post subject: |
|
|
Robert_d1968 wrote: | Since the switch to using them, I have had no more wrong return address issues.
Maybe it was in my code someplace, but it matters not now, as it's working fine. |
That's not correct, it actually matters, maybe not for you, but for other readers.
If you would be correct, nobody could use the Sub()/End Sub syntax, because it would not work.
But it actually does.
Quote: | This was construed through the help, index in Bascom. I was trying to see how to change a hex value into a decimal value |
I do know the help, but there's nowhere a part that says it's necessary to convert integers into strings and back, just to do some simple math.
Quote: | But matters not as, The voltage is represented by the PWM value (Compare1a) divided by the current sensor reading in hex gives the resistance in hex value. |
The µC does not think in terms of "hex", it thinks in terms of binary, hex is only a different representation of that.
Your code has not any useful meaning for a hex-representation, that's why it made no sense. Moreover, because multiplying an integer with a float constant does not work, you did present us a non-working code as a base for discussion, which shows me that you only wrote this, but never tested it.
That's poor behavior and caught my attention.
Quote: | So it's not that I learned strange things, I was simply trying something new. This is my first time using Bascom to write programs in for the avr, but it is most certainly not my first program. |
No intent to insult, but your code and lack of understanding of how µC's do their math, makes me believe you're an absolute beginner. And beginners tend to blame the compiler, software and anything, instead having a look in the mirror to see who's really to blame |
|
Back to top |
|
|
Robert_d1968
Joined: 18 Dec 2012 Posts: 67 Location: America
|
Posted: Sun Dec 30, 2012 6:09 pm Post subject: |
|
|
I never said that there is something wrong with sub/end sub, Just that I did not work well for my application.
Switching to the labels/return seemed to correct this issue, weather or not it was related to my code, most likely, yes.
But there is certainly nothing wrong with the use of them.
Yes, it could be construed to be "poor Behavior" as set forth. To post up that code with out testing it, but I just wanted a simple hey! you can't do that Because ?
"The µC does not think in terms of "hex", it thinks in terms of binary" Well yes, no argument from me there.
"No intent to insult, but your code and lack of understanding of how µC's do their math" No insult taken, it's pretty easy to see from the post how that could be construed, I'll have to choose what I post a little more carefully next time.
I have a bad habit of doing that, one I must clearly break.
It was my intention to post something, that could define the nature of the question. Perhaps It would have been better to just ask " How would one go about converting a hex value to a decimal format" ? |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sun Dec 30, 2012 8:01 pm Post subject: |
|
|
Robert_d1968 wrote: | you can't do that Because ? |
First, a sample that won't work because of am impossible syntax, serves nobody.
Second, you expect members to take the efforts to think about your problem, but you do not take the small effort of testing before posting.
Quote: | No insult taken, it's pretty easy to see from the post how that could be construed, I'll have to choose what I post a little more carefully next time. |
Reading your post, I can't see your intention.
Quote: | It was my intention to post something, that could define the nature of the question. Perhaps It would have been better to just ask " How would one go about converting a hex value to a decimal format" ? |
I believe you just lack the basics:
Quote: | Dim Current_val As Word '- Current sensor reading
...
Current val is in hex from the current sensor, do I really need to convert this to a string then to decimal to perform the calculations? |
If you can get the result from the sensor and put it into a word, it is NOT a hex-representation, it is already interpreted as word, which itself is binary in it's tiniest bits. A hex is a representation to make it human-readable, and if you don't want to send it out by serial, to LCD or save it by some reason as string, it makes not the slightest sense to do a conversion into a hex-string here.
If you want to do calculations like shown, either use single or double types, or use fixed point math, but then you have to scale up any float constant to have a reasonable accuracy. |
|
Back to top |
|
|
Visovian
Joined: 31 Oct 2007 Posts: 584 Location: Czech
|
Posted: Sun Dec 30, 2012 10:05 pm Post subject: |
|
|
Quote: | Perhaps It would have been better to just ask " How would one go about converting a hex value to a decimal format" ? |
The only way to do this is to convert the value to a string.
And we use this only when we want to see the value with our eyes on a display.
As long as we do math operations with variables or constants we need no conversion.
Only when we want to see the result, we convert it to the string and print it. (Bascom PRINT or LCD command does this conversion automatically)
In your code variables Ppm_hold2, Ppm_val must be of type "single" so that they can hold fractional numbers.
Of course the conversion there-and-back is useless.
Code: | Dim Current_val As Word '- Current sensor reading
Dim Ppm_hold As String * 16 '- Storage for the ppm value as a string (for conversions)
Dim Ppm_hold2 As Word
Res_Calc:
Ppm_hold = Hex(current_val) '- Convert this value to a string
Ppm_hold2 = Hexval(ppm_hold) '- Convert the string to a numeric value
Ppm_hold2 = Ppm_hold2 * 0.0293 '- Get the voltage
Ppm_val = Ppm_hold2 / Current_val '- Get the resistance
Return |
Anyway your math is bad, if I do not err.
The result is allways 0.0293.
Code: | Ppm_hold = Hex(current_val) '- Convert this value to a string
Ppm_hold2 = Hexval(ppm_hold) ' Ppm_hold2 = current_val
Ppm_hold2 = Ppm_hold2 * 0.0293 ' Ppm_hold2 = current_val * 0.0293
Ppm_val = Ppm_hold2 / Current_val ' Ppm_val = current_val * 0.0293 / current_val = 0.0293
|
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sun Dec 30, 2012 10:18 pm Post subject: |
|
|
Visovian wrote: | The result is allways 0.0293 |
That's not correct, the result will be exactly 0.
integer * const (< 0) = 0 |
|
Back to top |
|
|
|
|
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 You cannot attach files in this forum You cannot download files in this forum
|
|