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.
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