[Turning mad over christmas] Serial Read with an ATmega32 ...

Go To Last Post
22 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The following lines of code

read_pinc:

disable_Interrupt  = 1            ' Latch Interrupt disabled
Gosub set_Address
Gosub set_Port_pre
Dir_ext = 1                       ' set Device to sending state
Dir_int = 0                       ' set µ-Processor to receiving state
disable_Interrupt = 0             ' Latch Interrupt enabled
byte_Data = Pinc                  ' read Button/Device from the relevant port
disable_Interrupt  = 1
Gosub set_Port_post
data = Bin(byte_data)
byte_button = Right(data , 2)
byte_button = Binval(byte_button)

work just fine about a 1000 times. They read the last two bits of an 8bit-latch and return the last two bits (00, 01, 10, or 11). These bits represent the state of two buttons. It potentially reads it from different addresses(devices) specified via a variable byte_adr before these lines in question.

 

However, about two times within 1000 iterations it goes wrong. While no button is pressed, it returns the button-pressed state. TheH address remains untouched. Has anybody experienced anything similar? I depend on this working 100% rather than only 99.8%.

Thank you so much for any help on this

 


 

For completeness sake, here the subroutines:

set_Address:

  k_data_in = Bin(byte_adr)
  For count_Bit = 1 To 4 Step 1
     count_Bit_2 = 9 - count_Bit
     k_data = Mid(k_data_in , count_Bit_2 , 1)
     K(count_bit) = Val(k_data)
  Next
  Adr_ext0 = K(1)                                 ' This is a port connected to the latch communicating the address
  Adr_ext1 = K(2)
  Adr_ext2 = K(3)
  Adr_ext3 = K(4)

set_Port_pre:

   Ddrc = &B00000000                              ' prepares read-direction of the µ Processor
   Portc = &B00000000                             ' prepares the port

set_Port_post:

   Ddrc = &B11111111                              ' prepares read-direction of the µ Processor
   Portc = &B11111111                             ' prepares the port

 

Last Edited: Thu. Dec 28, 2017 - 10:54 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Welcome to the Forum.

 

It would be helpful to see a small, complete program, that demonstrates the problem.

What is your hardware?

Custom PCB?

Commercial PCB?

How long are the connections to the push buttons?

(Lengthy?, Susceptible to noise?)

Is there an RC filter on the push button inputs?

Are there LEDs on the Latch outputs which show the (incorrect) input being set high?

(i.e., was there a bogus signal that did, in fact, trigger the latch; or was the latch providing good data, and there is a software bug, (non-volatile variable, ISR's involved in the program, etc.))

Can you also post a schematic of your hardware?

 

JC

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear Doc,

 

thank you for the warm welcome and your questions. They helped already to find out that interrupts are apparently the problem. Also I forgot to mention the most important part:

The setup does not fail at all UNLESS the µP is "simultaneously" reading serial input. To illustrate this a small complete program follows the answers to your questions.

  • It is a custom PCB.

  • Connections between µP and latch are ~2cm.

  • No RC filter, just pull-up resistors.

  • no LEDs

$regfile = "m32def.dat"
$crystal = 3686400
$hwstack = 40
$swstack = 40
$framesize = 120
$baud = 115200
Mcucsr.7 = 1
Mcucsr.7 = 1
Ddra  = &B00000000
Ddrb  = &B00011111
Ddrc  = &B11111111
Portc = &B11111111
Ddrd  = &B11111110
'
' Aliases, DIMs, Declares, Configs, etc.
'
Enable Interrupts
Data_in = ""
Timer    = 0

Do
   Gosub read_Pinc              ' This is the first routine shown in the initial post
   If byte_Button <> 3 Then     ' If any button is read as 'pressed' while I don't press it
      Print "t=" ; Timer ; "; v=" ; byte_Button ; "; " ; "d=" ; Data_in ; ";"
   Else
      If Data_in <> "" Then
         Incr Timer
         Data_in = ""
      End If
   End If
Loop

Sub Serial0charmatch()
   Local Incoming_data As String * 30
   Input Incoming_data Noecho
   Data_in = Incoming_data
   Clear Serialin
End Sub

read_pinc:
   disable_Interrupt  = 1            ' Latch Interrupt disabled
   Gosub set_Address
   Gosub set_Port_pre
   Dir_ext = 1                       ' set Device to sending state
   Dir_int = 0                       ' set µ-Processor to receiving state
   disable_Interrupt = 0             ' Latch Interrupt enabled
   byte_Data = Pinc                  ' read Button/Device from the relevant port
   disable_Interrupt  = 1
   Gosub set_Port_post
   data = Bin(byte_data)
   byte_button = Right(data , 2)
   byte_button = Binval(byte_button)

set_Address:
    k_data_in = Bin(byte_adr)
       For count_Bit = 1 To 4 Step 1
          count_Bit_2 = 9 - count_Bit
          k_data = Mid(k_data_in , count_Bit_2 , 1)
          K(count_bit) = Val(k_data)
       Next
    Adr_ext0 = K(1)                                 ' This is a port connected to the latch communicating the address
    Adr_ext1 = K(2)
    Adr_ext2 = K(3)
    Adr_ext3 = K(4)

set_Port_pre:
   Ddrc = &B00000000                              ' prepares read-direction of the µ Processor
   Portc = &B00000000                             ' prepares the port

set_Port_post:
   Ddrc = &B11111111                              ' prepares read-direction of the µ Processor
   Portc = &B11111111                             ' prepares the port

The output would typically be:

t=42; v=1; d=test;
t=78; v=1; d=test;
t=135; v=0; d=test;
t=143; v=0; d=test;
t=226; v=1; d=test;
t=286; v=0; d=test;
t=361; v=0; d=test;
t=403; v=1; d=test;
t=455; v=0; d=test;
t=551; v=0; d=test;
t=632; v=0; d=test;
t=640; v=0; d=test;
t=776; v=1; d=test;
t=791; v=0; d=test;
t=921; v=0; d=test;

Eventhough v should always be 3 (which means no button is pressed), I read different values in 15 out of 1000 cases when receiving serial messages simultaneously.

 

 

If I remove the line

Enable Interrupts

all Errors are gone, but I also cannot have any incoming communication.

 

 

Could anyone point me towards the right direction?

Thank you and merry christmas

 

Last Edited: Wed. Dec 27, 2017 - 10:15 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

k3t0 wrote:
Sub Serial0charmatch() Local Incoming_data As String * 30 Input Incoming_data Noecho Data_in = Incoming_data Clear Serialin End Sub

 

Not that familiar with basic, but this Sub(routine) is not called from main, if this is a ISR, how is specified in basic as an ISR? 

One last comment, 115k is a fast speed for terminal I/O and can consume much of the mpu resources if the input is long or continuous, what is the nature of the serial input? 

Human input (typing) or some thing else?  Have you tried a much lower serial speed, (9k6, or 1k2)?

 

Jim

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

k3t0 wrote:

... a small complete program follows ...

 

It's not though is it?

 

read_Pinc is not shown anywhere.

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This looks like BASCOM-AVR?

 

I only have an older version but it won't compile the last code you posted.

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
read_Pinc              ' This is the first routine shown in the initial post
Last Edited: Tue. Dec 26, 2017 - 07:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

k3t0 wrote:
read_Pinc ' This is the first routine shown in the initial post
Yes, buried under

k3t0 wrote:

The following lines of code

read_pinc:

read_pinc: should have been placed in the code block.  You can edit your post to fix it and set_address:, set_Port_pre: and set_Port_post:.  They should all be in the body of the code block, not as disconnected standalone entries.

 

 

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Tue. Dec 26, 2017 - 08:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As someone who is asking for our help you are not doing much work yourself are you?

 

Your code is incomplete - you seem to expect us to cut and paste it into some sort of order and add the missing bits. Your code does not compile because of the many errors. Either post a complete piece of code that will compile and which demonstrates your problem or you'll find help is hard to come by. 

 

As my signature says..."This forum helps those who help themselves."

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear Larry,

 

thank you for your comment. All bits are now incorporated in the code block.

Hope it helps. Would be great to get some help.

 

Best,

k3t0

Last Edited: Wed. Dec 27, 2017 - 10:56 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

You could simply AND PinC with 3 rather than convert to a binary string, grab the last two chars then convert back to a value.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Please don't go back and edit earlier code. Later readers will want to see the chronology of how this developed/was solved.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

k3t0 wrote:

All bits are now incorporated in the code block.

 

Still doesn't compile though does it?

 

I'm out.

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Please don't go back and edit earlier code. Later readers will want to see the chronology of how this developed/was solved.

I told the OP to do it, and yes it was perfectly appropriate to do so in this case as there was no important code changed other than having the subroutine name within the code block along with the code.  It did not make any sense otherwise.  At least now the subroutines can be found.  Problem is it did not seem to alleviate other inherent code issues.

 

EDIT: Odd that the post I clearly was suggesting to change, #1, was not the one the OP chose to make the changes in.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Wed. Dec 27, 2017 - 03:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
  • Thank you to DocJC and Jim (Ki0bk) for commenting on the issue. With your help the problem is now solved.
  • Sorry to clawson for incorporating additional code in previous text. It won't happen again.
  • To larry: what I added to the first post was only the italic name tag "read_pinc:"

 

Recap of the problem:

The analog reading of an external button state went wrong about 2% (15 times in a 1000 repetitions) when a serial connection was simultaneously active.

 

Solution:

The serial communication had to be paused while the external button state is read. This is possible with the commands Enable/Disable Serial.

The working solution to the sample program sequence given above would have been:

Do
   Disable Serial
   Gosub read_Pinc              ' This is the first routine shown in the initial post
   Enable Serial

   If byte_Button <> 3 Then     ' If any button is read as 'pressed' while I don't press it
      Print "t=" ; Timer ; "; v=" ; byte_Button ; "; " ; "d=" ; Data_in ; ";"
   Else
      If Data_in <> "" Then
         Incr Timer
         Data_in = ""
      End If
   End If

Loop

Like this the serial connection remains active but there are no false reading of the analog input.

Cheers

Last Edited: Wed. Dec 27, 2017 - 04:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

It is good to hear that you have it working.

 

I am not at my computer right now, so I can't check other code and Instructions, but I think you are likely not using the interrupt driven, ring buffered serial communications provided by Bascom.

 

Have a look at the serial comm instructions, and at the sample code in the Demos folder.

It only takes one or two instructions to set up the serial comm's so that the serial comm's are interrupt driven, and incoming data is stored in a ring buffer for your program to read as it desires.

This allows the serial comm's to take place without interfering with other processes.

 

Also, make sure the three stacks that one sets up are large enough, and that your program is not overflowing a stack and a variable when the serial comm's is being performs, (as the program is currently set up).

If this is the case, and increasing the stacks solves the problem, then you will not to disable the serial comm's as you are now doing.

 

Good luck with your project.

 

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow, thanks for your input. It would be great to get it working without the need to disable the communication. The documentation suggests the following instructions to run an interrupt-driven serial comm.:

Declare Sub Serial0charmatch()
Config Serialin = Buffered , Size = 30 , Bytematch = 13

'Bytematch=13' means it waits for a carriage return (HEXCode 0x13 is carriage return) to call the interrupt, upon which the function 'Sub Serial0charmatch()' is executed.

 

 

With this config lines set and without disabling the serial communication (as done in post #15), I still get the same output:

...
t=403; v=1; d=test;
t=455; v=0; d=test;
t=551; v=0; d=test;
t=632; v=0; d=test;
t=640; v=0; d=test;
...

:/ So you're probably spot on and something's overflowing. Is there a way to track the three stacks as the program runs? So far I have:

$hwstack = 40
$swstack = 40
$framesize = 120

I figure HW is not the problem and played with SW and FRAME upto 600 each but it's all the same.

Last Edited: Thu. Dec 28, 2017 - 12:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

k3t0 wrote:
(HEXCode 0x13 is carriage return)
Actually 0x0D is the hex for the return. (13 decimal)

David (aka frog_jr)

Last Edited: Thu. Dec 28, 2017 - 01:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does (this) BASIC not support symbolic constants for this kind of thing?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you got decoupling capacitors?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear dbrion,

no I don't have any there's only pull-ups (#3). The connecting wires between latch (HCT245) and µP are very short 2cm. Still you're right, I'm using a custom PCB as a backplane with 12 long wires (40cm) behind the latch and those can act as capacities. I need to probe these 12 pretty rapidly and can't afford capacities in there.

 

Maybe somebody has experience in setting up the serial communication properly using bascom. That would be a great help. There might be an error in what is done in #17.

Last Edited: Fri. Dec 29, 2017 - 10:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Subroutines called with 'Gosub' must end with RETURN. (similar to call-ret in Asm)

I see 4 Gosub and no Return in your code. 

 

Unfortunately Bascom does not warn about it.

 

 

Last Edited: Sat. Dec 30, 2017 - 07:49 AM