Display

So that the wheelie even during driving is fully under control, it gets a 2.1 inch TFT display. The values are output by the processors on USARTs and changed with the MAX232 to RS232. This ensures smooth transmission to the display. The wheelie can also be connected to the PC instead of the display. There must be started a VT100 compatible terminal.
Hans-Peter Küsters provides a finished controller along with display and high-level commands in BASCOM. In addition, the set has an ATMega128 which has reserve for your own program code. Even in the basic version there is a RS232 converter available, so no additional hardware for my control panel is necessary. The price below 90 euros for display, controller, and RS232 converter has prevented me from DIY ;-)

First display test

Flash is required!

Howto

For the display-code 2 Lib-files are needed. These are shipped with the display. A converter that allows you to convert your own images into BIN files is also included. My background is stored in the files  lcd.bin and color.bin. They are later available for download.

Sourcecode

$hwstack = 128
$swstack = 128
$framesize = 128

$regfile = "m128def.dat"
$crystal = 16000000
$baud1 = 57600

Config Serialin1 = Buffered , Size = 60 , Bytematch = 13
Echo Off

Declare Sub Writeserinp
Declare Sub Checkserinp
Declare Sub Parser
Declare Sub Status_update

Const Mymainchannel = 2
Const Sw_down = 50
Dim Buffer As String * 15
Dim Serinpstr As String * 63
Dim Serinpbuffer As String * 63
Dim Cr_received As Bit
Dim Strsize As Byte
Dim Mainchannel As Byte
Dim Subchannel As Word
Dim Wert As Integer
Dim Frage As Byte
Dim Zeichenpos As Byte
Dim Intbuffer As Integer

Dim Strpuff As String * 20
Dim Status_old As String * 20
Dim Temp_level_oben As Byte
Dim Temp_level_unten As Byte
Dim Farbe As Word
Dim Voltage As Single
Dim Current_l As Single
Dim Current_r As Single
Dim Speed_l As Integer
Dim Speed_r As Integer
Dim Speed As Integer
Dim Speed_hold As Integer
Dim Strspeed As String * 20

Dim Parameter(6) As Integer
Dim Int_temp As Integer

Dim D7_touched As Byte
Dim D4_touched As Byte
Dim D5_touched As Byte
Dim D6_touched As Byte
Dim D1_touched As Byte

Dim Status As Byte
Dim Status_temp As Byte
Status = 1
Const P1 = 1
Const P2 = 2
Const P3 = 3
Const P4 = 4
Const P5 = 5
Const P6 = 6

'Now we need to select Port B as to an output port (data output to the display)
Ddrb = &B1111111                                            'DDR = Data direction register; All 8 ports switched to output (1)
Portd = &B11110011                                          'set Pullups from the buttons
$include Init21_display3000.bas

Open "COM2:" For Binary As #1

Orientation = Landscape
Graphics_mode = 256high_compressed
Gosub Lcd_cls
Restore Logo
Call Lcd_bitmap(0 , 0 , 175 , 131)
Enable Interrupts
Call Status_update
Do
   If Cr_received = 1 Then                                  'wenn was im ser. Buffer ist abholen
      Cr_received = 0
      Input #1 , , Serinpstr Noecho
      Clear Serialin1
      'zum Abtrennen eines oder mehrerer LF am Anfang des Strings, das noch vom Vorgänger-String im Buffer steht
      While Asc(serinpstr) = 10
         Strsize = Len(serinpstr) - 1
         Serinpstr = Right(serinpstr , Strsize)
      Wend
      'Hier ist der String empfangen und ein event. LF entfernt
      Call Checkserinp
   End If
   Status_temp = Status + 16
   If Pind.4 = 0 Then
      If D4_touched = 0 Then
         Int_temp = Parameter(status) + 1
         Buffer = Str(int_temp)
         Print #1 , "0:" ; Status_temp ; "=" ; Buffer
      End If
      D4_touched = 1
   Else
      D4_touched = 0
   End If
   If Pind.7 = 0 Then
      If D7_touched = 0 Then
         Int_temp = Parameter(status) - 1
         Buffer = Str(int_temp)
         Print #1 , "0:" ; Status_temp ; "=" ; Buffer
      End If
      D7_touched = 1
   Else
      D7_touched = 0
   End If
   If Pind.5 = 0 Then
      If D5_touched = 0 Then
         If Status = 1 Then Status = 6 Else Decr Status
         Call Status_update
      End If
      D5_touched = 1
   Else
      D5_touched = 0
   End If
   If Pind.6 = 0 Then
      If D6_touched = 0 Then
         Incr Status
         If Status > 6 Then Status = 0
         Call Status_update
      End If
      D6_touched = 1
   Else
      D6_touched = 0
   End If

   If Pind.1 = 0 Then
      If D1_touched = 0 Then
         Print #1 , "0:16=1"
      End If
      D1_touched = 1
   Else
      D1_touched = 0
   End If
Loop


'---------------------------------------------------------------------------
'     Serial1charmatch
'     Im Eingangspuffer wurde ein "13" empfangen
'     Dieser eine Takt Interrupt verzögert theoretisch die Regelung!?!
'---------------------------------------------------------------------------

Serial1charmatch:
    Cr_received = 1
Return

'---------------------------------------------------------------------------
'     Checkserinp
'     Hier der String abgeholt
'     Der Mainchannel und der : wird geprüft
'---------------------------------------------------------------------------

Sub Checkserinp
   If Asc(serinpstr) = 35 Then                              'Strings mit # gleich weiterleiten
      Exit Sub
   End If
   If Asc(serinpstr) = 27 Then                              'Strings mit ESC gleich weiterleiten
      Exit Sub
   End If

   Zeichenpos = Instr(serinpstr , ":")
   If Zeichenpos = 2 Then                                   ' Doppelpunkt Gefunden                                                 'kein *
         Serinpbuffer = Left(serinpstr , Zeichenpos)
         Mainchannel = Val(serinpbuffer)
         If Mainchannel = Mymainchannel Then
            Call Parser
         End If
   End If
End Sub
'---------------------------------------------------------------------------
'     Parser
'     Hier beginnt der Parser
'
'---------------------------------------------------------------------------
Sub Parser

   Zeichenpos = Len(serinpstr) - 2                          'der ":" und alles davor kommt weg                 'Instr(serinpstr , Doppelpunkt)
   Serinpbuffer = Right(serinpstr , Zeichenpos)
   Zeichenpos = Instr(serinpbuffer , "=")
    If Zeichenpos > 0 Then                                  '= ist vorhanden
      Frage = 0
   Else
      Frage = 1
      Zeichenpos = Len(serinpbuffer)
   End If
   Buffer = Left(serinpbuffer , Zeichenpos)
   Subchannel = Val(buffer)
   If Frage = 0 Then
      Frage = Len(serinpbuffer) - Zeichenpos
      Buffer = Right(serinpbuffer , Frage)
      Wert = Val(buffer)

     Select Case Subchannel
        'Lenker
        Case 3
           Strpuff = Format(buffer , " +0")
           Call Lcd_print(strpuff , 24 , 85 , 1 , 1 , 1 , Black , White)
          'Speed wird hier gezeichnet, da die Zeit bei den Speedbalken zu knapp wird.
           Speed = Speed_l + Speed_r
           Speed = Speed / 2
           If Speed < 1 And Speed > -1 Then Speed = 0
           Strspeed = Str(speed)
           Strspeed = Format(strspeed , " +0.0")
           Strspeed = Left(strspeed , 6)
           If Speed > Speed_hold Then
               Speed_hold = Speed
               Call Lcd_print(strspeed , 135 , 58 , 1 , 1 , 1 , Black , White)
           End If
           Strspeed = Strspeed + " km/h"
           Call Lcd_print(strspeed , 50 , 38 , 1 , 1 , 1 , Black , White)
        'Power Motor links
        Case 7
           If Wert < 0 Then
              Temp_level_oben = 0
              Wert = Wert * -1
              Temp_level_unten = Wert / 5
           Else
              Temp_level_unten = 0
              Temp_level_oben = Wert / 5
           End If
           If Wert > 160 Then
              Farbe = Red
           Else
              Farbe = Green
           End If
           If Temp_level_unten > 36 Then Temp_level_unten = 36
           Temp_level_unten = 90 + Temp_level_unten
           Call Lcd_box(100 , 90 , 105 , Temp_level_unten , Farbe)
           Call Lcd_box(100 , Temp_level_unten , 105 , 126 , White)

           If Temp_level_oben > 36 Then Temp_level_oben = 36
           Temp_level_oben = 90 - Temp_level_oben
           Call Lcd_box(100 , Temp_level_oben , 105 , 90 , Farbe)
           Call Lcd_box(100 , 53 , 105 , Temp_level_oben , White)
        'Power Motor rechts
        Case 8
           If Wert > 0 Then
              Temp_level_unten = 0
              Temp_level_oben = Wert / 5
           Else
              Temp_level_oben = 0
              Wert = Wert * -1
              Temp_level_unten = Wert / 5
           End If
           If Wert > 160 Then
              Farbe = Red
           Else
              Farbe = Green
           End If
           If Temp_level_unten > 36 Then Temp_level_unten = 36
           Temp_level_unten = 90 + Temp_level_unten
           Call Lcd_box(70 , 90 , 75 , Temp_level_unten , Farbe)
           Call Lcd_box(70 , Temp_level_unten , 75 , 126 , White)

           If Temp_level_oben > 36 Then Temp_level_oben = 36
           Temp_level_oben = 90 - Temp_level_oben
           Call Lcd_box(70 , Temp_level_oben , 75 , 90 , Farbe)
           Call Lcd_box(70 , 53 , 75 , Temp_level_oben , White)
        'Speed left
        Case 9
           Speed_l = Wert
           If Wert > 0 Then
              Temp_level_unten = 0
              Temp_level_oben = Wert / 5
           Else
              Temp_level_oben = 0
              Wert = Wert * -1
              Temp_level_unten = Wert / 5
           End If
           If Wert > 160 Then
              Farbe = Red
           Else
              Farbe = Blue
           End If
           If Temp_level_unten > 36 Then Temp_level_unten = 36
           Temp_level_unten = 90 + Temp_level_unten
           Call Lcd_box(75 , 90 , 80 , Temp_level_unten , Farbe)
           Call Lcd_box(75 , Temp_level_unten , 80 , 126 , White)

           If Temp_level_oben > 36 Then Temp_level_oben = 36
           Temp_level_oben = 90 - Temp_level_oben
           Call Lcd_box(75 , Temp_level_oben , 80 , 90 , Farbe)
           Call Lcd_box(75 , 53 , 80 , Temp_level_oben , White)
         'Speed right
        Case 10
           Speed_r = Wert
           If Wert < 0 Then
              Temp_level_oben = 0
              Wert = Wert * -1
              Temp_level_unten = Wert / 5
           Else
              Temp_level_unten = 0
              Temp_level_oben = Wert / 5
           End If
           If Wert > 160 Then
              Farbe = Red
           Else
              Farbe = Blue
           End If
           If Temp_level_unten > 36 Then Temp_level_unten = 36
           Temp_level_unten = 90 + Temp_level_unten
           Call Lcd_box(95 , 90 , 100 , Temp_level_unten , Farbe)
           Call Lcd_box(95 , Temp_level_unten , 100 , 126 , White)

           If Temp_level_oben > 36 Then Temp_level_oben = 36
           Temp_level_oben = 90 - Temp_level_oben
           Call Lcd_box(95 , Temp_level_oben , 100 , 90 , Farbe)
           Call Lcd_box(95 , 53 , 100 , Temp_level_oben , White)
        Case 11
          If Buffer <> Status_old Then
           Status_old = Buffer
           Call Lcd_print( "                    " , 10 , 25 , 1 , 1 , 1 , White , White)
           Select Case Wert
              Case 10
                 Call Lcd_print( "Störung! ADXL low" , 10 , 25 , 1 , 1 , 1 , Red , White)
              Case 11
                 Call Lcd_print( "Störung! ADXL high" , 10 , 25 , 1 , 1 , 1 , Red , White)
              Case 12
                 Call Lcd_print( "Störung! Gyro low" , 10 , 25 , 1 , 1 , 1 , Red , White)
              Case 13
                 Call Lcd_print( "Störung! Gyro high" , 10 , 25 , 1 , 1 , 1 , Red , White)
              Case 14
                 Call Lcd_print( "Störung! Fußschalter" , 10 , 25 , 1 , 1 , 1 , Red , White)
              Case Else
                 If Buffer = "Standby" Then Speed_hold = 0
                 Call Lcd_print(buffer , 10 , 25 , 1 , 1 , 1 , Black , White)
           End Select
          End If
        'Battery
        Case 12
           Voltage = Val(buffer)
           Voltage = Voltage * 0.0328
           Select Case Voltage
                Case 0 To 24
                 Farbe = Red
                Case 24 To 25
                 Farbe = Orange
                Case 25 To 29
                 Farbe = Green
                Case Else
                 Farbe = Black
           End Select
           Buffer = Str(voltage)
           Buffer = Left(buffer , 4)
           Strpuff = Format(buffer , " 0") + "V"
           Call Lcd_print(strpuff , 24 , 52 , 1 , 1 , 1 , Farbe , White)
        Case 15
           Current_l = Val(buffer)
           Current_l = Current_l - 512
           Current_l = Current_l * 0.122
           Select Case Current_l
                Case 0 To 10
                 Farbe = Green
                Case 10 To 20
                 Farbe = Orange
                Case 25 To 50
                 Farbe = Red
                Case Else
                 Farbe = Green
           End Select
           Intbuffer = Int(current_l)
           Buffer = Str(intbuffer)
           Buffer = Left(buffer , 4)
           Strpuff = Format(buffer , "  +") + "A"
           Call Lcd_print(strpuff , 24 , 106 , 1 , 1 , 1 , Farbe , White)
        Case 16
           Current_r = Val(buffer)
           Current_r = Current_r - 512
           Current_r = Current_r * 0.122
           Select Case Current_r
                Case 0 To 10
                 Farbe = Green
                Case 10 To 20
                 Farbe = Orange
                Case 25 To 50
                 Farbe = Red
                Case Else
                 Farbe = Green
           End Select
           Intbuffer = Int(current_r)
           Buffer = Str(intbuffer)
           Buffer = Left(buffer , 4)
           Strpuff = Format(buffer , "  +") + "A"
           Call Lcd_print(strpuff , 24 , 116 , 1 , 1 , 1 , Farbe , White)
        Case 17
           Parameter(p1) = Wert
           Strpuff = "P1: " + Format(buffer , " +0")
           Call Lcd_print(strpuff , 121 , 72 , 1 , 1 , 1 , Black , White)
        Case 18
           Parameter(p2) = Wert
           Strpuff = "P2: " + Format(buffer , " +0")
           Call Lcd_print(strpuff , 121 , 82 , 1 , 1 , 1 , Black , White)
        Case 19
           Parameter(p3) = Wert
           Strpuff = "P3: " + Format(buffer , " +0")
           Call Lcd_print(strpuff , 121 , 92 , 1 , 1 , 1 , Black , White)
        Case 20
           Parameter(p4) = Wert
           Strpuff = "P4: " + Format(buffer , " +0")
           Call Lcd_print(strpuff , 121 , 102 , 1 , 1 , 1 , Black , White)
        Case 21
           Parameter(p5) = Wert
           Strpuff = "P5: " + Format(buffer , " +0")
           Call Lcd_print(strpuff , 121 , 112 , 1 , 1 , 1 , Black , White)
        Case 22
           Parameter(p6) = Wert
           Strpuff = "P6: " + Format(buffer , " +0")
           Call Lcd_print(strpuff , 121 , 122 , 1 , 1 , 1 , Black , White)
        Case Else
     End Select
   End If
End Sub

Sub Status_update
    If Status = P1 Then Call Lcd_box(117 , 72 , 120 , 78 , Black) Else Call Lcd_box(117 , 72 , 120 , 78 , White)
    If Status = P2 Then Call Lcd_box(117 , 82 , 120 , 88 , Black) Else Call Lcd_box(117 , 82 , 120 , 88 , White)
    If Status = P3 Then Call Lcd_box(117 , 92 , 120 , 98 , Black) Else Call Lcd_box(117 , 92 , 120 , 98 , White)
    If Status = P4 Then Call Lcd_box(117 , 102 , 120 , 108 , Black) Else Call Lcd_box(117 , 102 , 120 , 108 , White)
    If Status = P5 Then Call Lcd_box(117 , 112 , 120 , 118 , Black) Else Call Lcd_box(117 , 112 , 120 , 118 , White)
    If Status = P6 Then Call Lcd_box(117 , 122 , 120 , 128 , Black) Else Call Lcd_box(117 , 122 , 120 , 128 , White)
End Sub

End

$inc Logo , Nosize , "data.bin"
$inc Colortable , Nosize , "color.bin"
$include Glcd21_display3000.bas
$include Glcd21_fonts.bas