Share My Creation TFT Oscilloscope

TFT low frequency oscilloscope, bandwidth is DC to 2000Hz. Max sampling rate is 40000 samples per second. An oscilloscope with these specifications has limited use, but it is a good exercise in using LCD TFT. Arduino can be Uno or Nano.
The screen is constructed from 32 lines. The ADC reads the input at resolution of 10 bits, the MSB 8 bits are stored in the RAM and then transmitted to the LCD RAM by 4 wires SPI.
C code is for the SPI and setting the ADC to max speed.
The Sweep time is selected by the 10K pot, the ADC converts the pot voltage to digital delay as interval for the samples.
LCD TFT modules has the driver ST7735, 160x128 pixels, 1.8 inch.
B4X:
Sub Process_Globals

    Public Serial1 As Serial
    Private tmr As Timer
    Public CS As Pin
    Public DC As Pin
    Public SDA As Pin
    Public SCK As Pin
    Public RST As Pin

    Public  BLUE  As UInt=0x01F
    Public  RED   As UInt=0xF800
    Public  GREEN   As UInt=0x07E0
    Public  CYAN   As UInt=0x07FF
    Public  MAGENTA   As UInt=0xF81F
    Public  YELLOW   As UInt=0xFFE0
    Public  WHITE   As UInt=0xFFFF
    Private spires, spidata As Byte
    Private in As Pin
    Private sweep As Pin

End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    tmr.Initialize("tmr_Tick", 2000)
    tmr.Enabled = True
    CS.Initialize(10, CS.MODE_OUTPUT)
    DC.Initialize(9, DC.MODE_OUTPUT)
    SCK.Initialize(13, SCK.MODE_OUTPUT)
    RST.Initialize(8, RST.MODE_OUTPUT)
    SDA.Initialize(11, SDA.MODE_OUTPUT)
    in.Initialize(in.A0, in.MODE_INPUT)
    sweep.Initialize(sweep.A2, sweep.MODE_INPUT)
    
    RunNative ("set_spi",Null)
    TFTinit
    rectan(0,0,159,127,CYAN)    'clear screen

End Sub

Sub tmr_Tick
    Dim smpl(34), i As Byte
    Dim range As UInt = 1000
    Dim vin, zero, pol As Byte

    range=sweep.AnalogRead * 5

    'trigger on input rise
    i=0
    zero=1
    Do While i<200 And zero>0
        pol=255
        vin=in.AnalogRead / 4
        If vin>120 And vin<130 Then
            pol=vin
            vin=in.AnalogRead / 4
            If vin>pol Then zero=0
        End If
        DelayMicroseconds(1000)
    Loop

    'sample 32 readings
    For i=0 To 32
        smpl(i)=in.AnalogRead / 8
        DelayMicroseconds(range)    'slower sweep For low freq
    Next

    line(0,64,159,64,BLUE)
    line(79,0,79,127,BLUE)
    line(0,107,159,107,GREEN)
    line(0,20,159,20,GREEN)
    For i=0 To 32
        line(i*5,smpl(i),i*5+5,smpl(i+1),RED)
    Next
    Delay(1000)
    For i=0 To 32
        line(i*5,smpl(i),i*5+5,smpl(i+1),CYAN)
    Next   
End Sub




Sub spi(data As Byte)    'send byte over spi
    spidata=data
    RunNative ("spi",Null)
    Return
End Sub


Sub command(cmd As Byte)
    DC.DigitalWrite(False)    'command Mode
    CS.DigitalWrite(False)    'Select the LCD (active low)
      spi(cmd)'set up data on bus
      CS.DigitalWrite(True)    'Deselect LCD (active low)   
End Sub

Sub send_data(data As Byte)
    DC.DigitalWrite(True)    'data mode
    CS.DigitalWrite(False)    'Select the LCD (active low)
    spi(data)    'set up data on bus
    CS.DigitalWrite(True)    'Deselect LCD (active low)
End Sub

Sub TFTinit
      Dim i As Byte
    
    RST.DigitalWrite(True)    'hardware reset
    Delay(200)
    RST.DigitalWrite(False)
    Delay(10)
    RST.DigitalWrite(True)
    Delay(10)

      command(0x01)    'sw reset
    Delay(200)
     command(0x11)    ' Sleep out
    Delay(200)
    
      command(0x3A)    'color mode
    send_data(0x05)    '16 bits
    'send_data(0x06)    '18 bits

      command(0x36)    'Memory access ctrl (directions)
      send_data(0x60)    '0B1100000=0x60
    'send_data(0x08)    '0x48=left to right,BRG,horizontal   0x40=vertical,RGB
      'command(0x21)    'color inversion on

      command(0x2D)    'color look up table
      send_data(0)
    For i = 1 To 31
        send_data(i * 2)
    Next

      For i = 0 To 63
        send_data(i)
      Next
      send_data(0)
    For i = 1 To 31
    send_data(i * 2)
    Next

      command(0x13)    'Normal display on
    command(0x29)    'Main screen turn on
End Sub

Sub line(x0 As Int, y0 As Int,  x1 As Int, y1 As Int, color As UInt)
  Dim steep As Int '= Abs(y1 - y0) > Abs(x1 - x0)
  Dim dx, dy, err, ystep, t As Int
 
  If Abs(y1 - y0) > Abs(x1 - x0) Then steep=1
 
    If steep=1 Then
        t=x0
        x0=y0
        y0=t
        t=x1
        x1=y1
        y1=t
    End If
 
    If x0 > x1 Then
        t=x0
        x0=x1
        x1=t
        t=y0
        y0=y1
        y1=t
    End If

    dx = x1 - x0
    dy = Abs(y1 - y0)
    err = dx / 2
    If y0 < y1 Then
        ystep = 1
        Else
            ystep = -1
    End If
     Do While x0<=x1+1
        If steep=1 Then
            pixel(y0, x0, color)
            Else
                pixel(x0, y0, color)
        End If
        err=err-dy
        If err < 0 Then
            y0 = y0 + ystep
            err = err + dx
        End If
        x0=x0+1
    Loop

End Sub

Sub area(x0 As Byte, y0 As Byte,  x1 As Byte, y1 As Byte)
  command(0x2A)    'Column addr set
  send_data(0x00)
  send_data(x0)    ' XSTART
  send_data(0x00)
  send_data(x1)    ' XEND

  command(0x2B)    'Row addr set
  send_data(0x00)
  send_data(y0)    ' YSTART
  send_data(0x00)
  send_data(y1)    ' YEND

  command(0x2C)    'write To RAM
End Sub 
 
Sub rectan(x0 As Byte, y0 As Byte,  x1 As Byte, y1 As Byte, color As UInt)
  Dim i As Int
  area(x0,y0,x1,y1)
  For i=(y1 - y0 + 1) * (x1 - x0 + 1) To 0 Step -1   

     DC.DigitalWrite(True)    ' data mode
    CS.DigitalWrite(False)
    spi(color / 256)
    spi(color Mod 256)
    CS.DigitalWrite(True)
   Next
End Sub

Sub pixel(x As Byte, y As Byte, color As UInt)
    area(x,y,x+1,y+1)
    send_data(color / 256)
    send_data(color Mod 256)
End Sub

    #if C
    void spi(B4R::Object* o)
    {   
      SPDR = b4r_main::_spidata;  // Start transmission
      while (!(SPSR & _BV(SPIF)));  // Wait For transmission To complete
      b4r_main::_spires = SPDR;    // received byte
    }

    void set_spi(B4R::Object* o)
    {   
      SPCR = 0B1011100;  // Enable SPI, Master, mode3, set clock rate fck/4 = 4MHz
      //SPSR = 1;    //set clock rate fck/2=2MHz
      
          //ADC set to max speed
      ADCSRA &= ~(_BV(ADPS1)); //set ADC divider to 32 - 250KHz sampling
      ADCSRA |= _BV(ADPS0) | _BV(ADPS2);
    }
    #End if
 

Attachments

  • tft_scope_b4r405.jpg
    tft_scope_b4r405.jpg
    123.2 KB · Views: 38
  • tft_scope.zip
    2.7 KB · Views: 6
  • tft_scope_328.gif
    tft_scope_328.gif
    3.8 KB · Views: 17

Similar Threads

Top