Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 00:25 28 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Getting the best out of Pico ADC

     Page 15 of 17    
Author Message
stanleyella

Guru

Joined: 25/06/2022
Location: United Kingdom
Posts: 2129
Posted: 09:47pm 06 Sep 2023
Copy link to clipboard 
Print this post

  phil99 said  With Beta 15 Math Window now makes Min. and Max. values of the input array available.

In my scope program it can be used to replace this:-
 Math WINDOW samples(), VRes - 1, 0, samples2() 'Make samples fit screen, min at bottom, max at top
 Max = Math(max samples()) : Min = Math(min samples())
 p2p = Max - Min  'peak-to-peak sample values

With this:-
 Math WINDOW samples(), VRes - 1, 0, samples2(), Min, Max 'Make samples fit screen, min at bottom, max at top
 p2p = Max - Min  'peak-to-peak sample values

Thanks Peter

I will try and convert my code to hres and vres and not use 0,0 top/left as 0.
take a while. so many scope codes but use math window. Looks like it make code shorter
which I like.
I tested my scope on ili9341 pins and only gp11 , touch did anything, went from 3.3V to 0V when you touch the screen no clock or data on display pins showed.. which was the point of the scope.
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2136
Posted: 10:08pm 06 Sep 2023
Copy link to clipboard 
Print this post

The frequency of SPI clock and data are way too high for ADC.
Its maximum sample rate is only 500,000 samples/S, they they could be up to 10MHz. The sampling rate would need to be tens of MHz.

Volhout's Logic Analyser uses PIO and can run much faster than ADC.
 
stanleyella

Guru

Joined: 25/06/2022
Location: United Kingdom
Posts: 2129
Posted: 10:49pm 06 Sep 2023
Copy link to clipboard 
Print this post

  phil99 said  The frequency of SPI clock and data are way too high for ADC.
Its maximum sample rate is only 500,000 samples/S, they they could be up to 10MHz. The sampling rate would need to be tens of MHz.

Volhout's Logic Analyser uses PIO and can run much faster than ADC.

er. yes. forget i2c testing also.
 
stanleyella

Guru

Joined: 25/06/2022
Location: United Kingdom
Posts: 2129
Posted: 03:38pm 07 Sep 2023
Copy link to clipboard 
Print this post

NPH . I looked at your old trigger and changed mine and it seems more stable!
a rising edge but my display and 0,0 at top left.
using ili9341 with 0,0 at top left. Moving to bottom left 0,239-y each loop seems waste so turn display board 180 and print text upside down.. no :)

   adc start samples!() 'get new samples
   'trigger
   c%=0
  do:If samples!(c%+1) > 0.1 then if samples!(c%) < 0.2 then exit do
inc c%:loop while c%<240


was If samples!(c%) > 0.1 then if samples!(c%+1) < 0.2 then exit do
As an experiment I tried line in green then plot in white on top.. 2 tone square.

for x%=0 to 238 'screen width
     line x%,239-samples!(x%+c%),x%+1,239-samples!(x%+1+c%),,rgb(green) 'draw new sample from sample(c%)
     pixel x%,239-samples!(x%+c%),rgb(white) 'plot new sample from sample(c%)
   next x%


 
NPHighview

Senior Member

Joined: 02/09/2020
Location: United States
Posts: 200
Posted: 08:25pm 07 Sep 2023
Copy link to clipboard 
Print this post

Stan - I wanted to be able to trigger adaptively and not depend on specific voltage levels to do so, so I used the mean value.

Right now, my dual-trace code only uses GP26 to check for triggers; I'm contemplating altering the trigger advance code (which now cycles through "/" rising edge, "\" falling edge, or "-" free-running) to cycle through both GP26 and GP27 as well. I'll publish it here when I get it working.

Regarding upper left vs. lower left, the Pico variants of MMBasic don't provide a command that's in the Colour Maximite version, namely OPTION Y_AXIS UP (or DOWN). This would solve your problem handily. As it stands, I use a negative scale factor to invert the signal, and a positive offset to move up or down the screen. The additional manipulation is so fast I don't even notice it.

If we take Mick's advice, and protect the ADC input through some buffering, I suppose we could use the inverting input of a unity-gain Op Amp circuit to flip the display :-)

- Steve
Live in the Future. It's Just Starting Now!
 
NPHighview

Senior Member

Joined: 02/09/2020
Location: United States
Posts: 200
Posted: 09:06pm 07 Sep 2023
Copy link to clipboard 
Print this post

Stan - I've just changed the code to trigger either on channel 1 (GP26, pin 31) or channel 2 (GP27, pin 32) by repeatedly pressing the "trigger" button. You'll notice two things: The trigger symbol ("/", "\", "-") is shown in the color corresponding to the channel being used as a trigger source, and the terminal (if present) shows the transitions for trigger, voltage, and timing.



I'm feeding GP27 (pin 32, "channel 2") a 1 KHz sinewave I generated as an MP3 file, and downloaded to an ancient iPod. It gets to GP27 through a 47uF capacitor and 10K resistors between ground and pin 32 and between pin 32 and the 3.3 reference voltage on pin 35, as per Mick's recommendation.

Here's the code that accomplishes this:

' TwoTrace - a 2-channel oscilloscope on the RP2040-LCD-0.96
' Steve Johnson  September, 2023
'
' Analog Signal input 1    on GP26 / Pin 31 - trace 1 / trigger
' Analog Signal input 2    on GP27 / Pin 32 - trace 2 / trigger
' Test   Signal output     on GP18 / Pin 24 - 1 KHz square wave
'
' Scope controls via momentary contact switches to ground
'   Vertical Scale switch on GP13 / Pin 17
'   Trigger Select switch on GP14 / Pin 19
'   Time Scale     switch on GP15 / Pin 20
'
' Scope Controls (via serial input from terminal emulator):
'   Voltage: 0, 1, 2         to change vertical scale
'   Time:    Faster, Slower  to change horizontal scale
'   Trigger: Up, Down, None  to change trigger criteria
'
' Sampling, Test Signal, Triggering, Framebuffers from stanleyella
' Math & Memory Copy from matherp
' Ganssle's switch debounce routine from CaptainBoing and Steve Johnson
' Graticules, Array Drawing, variable scales & triggering from Steve Johnson
' Interrupt Service Routines from Steve Johnson

Option EXPLICIT
Option Base 0

' Specifically For Waveshare RP2040-LCD-0.96

Const Hres       = MM.HRes        ' Horizontal screen resolution
Const Vres       = MM.VRes        ' Vertical   screen resolution

Const Major      = Vres/4         ' Major tic mark pixel spacing
Const Minor      = Major/4        ' Minor tic mark pixel spacing

Const PWM_Pin    = MM.Info(PINNO GP18) ' Pin 24 - PWM Test signal output pin
Const ADC1_Pin   = MM.Info(PINNO GP26) ' Pin 31 - Analog to Digital Converter 1
Const ADC2_Pin   = MM.Info(PINNO GP27) ' Pin 32 - Analog to Digital Converter 2

Const V_sw       = MM.Info(PINNO GP13) ' Pin 17 - Vertical Scale pushbutton switch
Const T_sw       = MM.Info(PINNO GP14) ' Pin 19 - Trigger Select pushbutton switch
Const A_sw       = MM.Info(PINNO GP15) ' Pin 20 - Time Scale     pushbutton switch

Const PWM_Freq   = 1000           ' Frequency for Test Signal on Pin 24
Const PWM_Duty   =   50           ' Base duty cycle for test signal PWM in %
Const PWM_Jitter =    0           ' Jitter in % for test signal PWM
Const Debounce   =  200           ' Debounce delay in mSec for front panel switches

' Generic to all displays - calculations done off screen dimensions

Const HMajor     = Hres/Major     ' How many Horiz Major Tic marks
Const VMajor     = Vres/Major     ' How many Vert  Major Tic marks
Const HMinor     = Hres/Minor     ' How many Horiz Minor Tic marks
Const VMinor     = Vres/Minor     ' How many Vert  Minor Tic marks

Const Background = RGB(32,64,32)  ' Color for Display background, a la Tektronix scopes
Const GMajor     = RGB(black)     ' Color for Major tic marks
Const GMinor     = RGB(black)     ' Color for Minor tic marks
Const T1_color   = RGB(yellow)    ' Color for displayed Trace1
Const T2_color   = RGB(cyan)      ' Color for displayed Trace2
Const TxtColor   = RGB(white)     ' Color for displayed text
Const ShadColor  = RGB(black)     ' Color for text shadows

Const Trig_None_1  = 0
Const Trig_Down_1  = 1              ' Enumerate possible trigger conditions for GP26
Const Trig_Up_1    = 2
Const Trig_None_2  = 3
Const Trig_Down_2  = 4              ' Enumerate possible trigger conditions for GP27
Const Trig_Up_2    = 5

Const ADC_Max    = 7              ' Maximum index into ADC Time Scale array (0-7)
Const V_Max      = 3              ' Maximum index into Voltage  Scale array (0-3)
Const Trig_Max   = 5

' Declare storage

Dim INTEGER c, n, x, y, trigger, trigger_timeout, Vselect, Trig_Type, ADC_select
Dim INTEGER v_time, v_diff, v_state, v_old, v_press ' Volts   scale button debouncing and status
Dim INTEGER t_time, t_diff, t_state, t_old, t_press ' Trigger type  button debouncing and status
Dim INTEGER a_time, a_diff, a_state, a_old, a_press ' ADC frequency button debouncing and status

Dim INTEGER Horizontal(Hres)      ' Horizontal coordinate buffer for fast graticule and buffer draw
Dim FLOAT   trace1(2*Hres)        ' Extra size to hopefully pick up a trigger event
Dim FLOAT   trace2(2*Hres)        ' Extra size to hopefully pick up a trigger event
Dim FLOAT   buffer1(Hres)         ' Display buffer for screen output
Dim FLOAT   buffer2(Hres)         ' Display buffer for screen output
Dim INTEGER addr.trace1, addr.trace2, addr.buffer1, addr.buffer2

Dim INTEGER HMajorX1(HMajor+1), HMajory1(HMajor+1), HMajory2(HMajor+1) ' For Horizontal Major Axes
Dim INTEGER VMajorX1(VMajor+1), VMajorx2(VMajor+1), VMajory1(VMajor+1) ' For Vertical   Major Axes
Dim INTEGER HMinorX1(HMinor+1), HMinory1(HMinor+1), HMinory2(HMinor+1) ' For Horizontal Minor Axes
Dim INTEGER VMinorX1(VMinor+1), VMinorx2(VMinor+1), VMinory1(VMinor+1) ' For Vertical   Minor Axes

Dim Float   V.Scale(10), V.Offset(10), V.MajVolts(10)
Dim Float   H.Freq(10),  H.Seconds(10)

Dim String  H.Units$(10), keypress$

' ========================== Initialization =================================
Timer = 0
Initialize_Arrays
Initialize_Hardware
Display_Instructions
Draw_Graticules

' ========================== Processing Loop ================================
Do
 Randomize_Test_Signal
 trigger_timeout = Timer
 Do
   Handle_Keypresses
   Handle_Switches
   trigger = -1
   Get_Samples
   trigger = find_trigger(Trig_Type)
   If Timer-trigger_timeout > 2500 Then Display_No_Trigger ' Waiting too long for a trigger.
 Loop Until trigger >= 0
 If Timer-trigger_timeout > 2500 Then Draw_Graticules      ' OK, we've got a trigger. Clear message.
 Scale_Samples
 Update_Display
Loop

' ========================== Interrupt Service Routines ====================

Sub V_ISR ' Interrupt Service Routine for Voltage SPST Button
 If v_press = 0 Then ' Ignore further  button presses until handled in main loop
   If (Timer - v_time) > debounce Then v_press = 1 : v_time = Timer
 EndIf
End Sub

Sub T_ISR ' Interrupt Service Routine for Trigger SPST Button
 If t_press = 0 Then ' Ignore further  button presses until handled in main loop
   If (Timer - t_time) > debounce Then t_press = 1 : t_time = Timer
 EndIf
End Sub

Sub A_ISR ' Interrupt Service Routine for ADC Frequency SPST Button
 If a_press = 0 Then ' Ignore further  button presses until handled in main loop
   If (Timer - a_time) > debounce Then a_press = 1 : a_time = Timer
 EndIf
End Sub

' ========================== Subs and Functions ============================

Sub Handle_Keypresses
 keypress$ = Inkey$
 Select Case keypress$
   Case "0"      : Vselect = 0
   Case "1"      : Vselect = 1
   Case "2"      : Vselect = 2
   Case "3"      : Vselect = 3
   Case "u", "U" : Trig_Type  = Trig_Up
   Case "d", "D" : Trig_Type  = Trig_Down
   Case "n", "N" : Trig_Type  = Trig_None
   Case "f", "F" : ADC_select = Min(ADC_select+1, ADC_Max) : Set_ADC_Timing
   Case "s", "S" : ADC_select = Max(ADC_select-1, 0) : Set_ADC_Timing
   Case "" : Exit Sub               ' No key pressed. No change.
   Case Else : Display_Instructions ' Unknown key pressed.
 End Select
 Draw_Graticules
End Sub

Sub Handle_Switches ' switch press detection done in Interrupt Service Routines
 Local INTEGER V, T, A

 If v_press = 1 Then
   v_press = 0
   Print "Voltage: ", V.MajVolts(Vselect);" -> ";
   Vselect = (Vselect+1) Mod (V_Max+1)
   Print V.MajVolts(Vselect);" V/div"
 EndIf

 If t_press = 1 Then
   t_press = 0
   Select Case Trig_Type
     Case Trig_Up_1:   Print "Trigger: ", " Trig_Up_1   -> Trig_Down_1" : Trig_Type = Trig_Down_1
     Case Trig_Down_1: Print "Trigger: ", " Trig_Down_1 -> Trig_None_1" : Trig_Type = Trig_None_1
     Case Trig_None_1: Print "Trigger: ", " Trig_None_1 -> Trig_Up_2"   : Trig_Type = Trig_Up_2
     Case Trig_Up_2:   Print "Trigger: ", " Trig_Up_2   -> Trig_Down_2" : Trig_Type = Trig_Down_2
     Case Trig_Down_2: Print "Trigger: ", " Trig_Down_2 -> Trig_None_2" : Trig_Type = Trig_None_2
     Case Trig_None_2: Print "Trigger: ", " Trig_None_2 -> Trig_Up_1"   : Trig_Type = Trig_Up_1
     Case Else :       Print "Trigger: ", " *Unknown*   -> Trig_Up_1"   : Trig_Type = Trig_Up_1
   End Select
 EndIf

 If a_press = 1 Then
   a_press = 0
   Print "Timebase: ", ADC_select;" ";H.seconds(ADC_select);" ";H.units(ADC_select); " -> ";
   ADC_select = (ADC_select+1) Mod (ADC_Max+1) : Set_ADC_Timing
   Print ADC_select;" ";H.seconds(ADC_select);" ";H.units(ADC_select)
 EndIf

 Draw_Graticules

End Sub

Function find_trigger(a)
 Local median = Math(MEAN trace1())

 Select Case a
   Case Trig_Down_1
     median = Math(MEAN trace1())
     For c = 0 To Hres-1
       If trace1(c) > median+0.1 And trace1(c+1) < median+0.2 Then find_trigger = c : Exit Function
     Next
     find_trigger = -1 : Exit Function
   Case Trig_Up_1
     median = Math(MEAN trace1())
     For c = 0 To Hres-1
       If trace1(c+1) > median+0.1 And trace1(c) < median+0.2 Then find_trigger = c : Exit Function
     Next
     find_trigger = -1 : Exit Function
   Case Trig_Down_2
     median = Math(MEAN trace2())
     For c = 0 To Hres-1
       If trace2(c) > median+0.1 And trace2(c+1) < median+0.2 Then find_trigger = c : Exit Function
     Next
     find_trigger = -1 : Exit Function
   Case Trig_Up_2
     median = Math(MEAN trace2())
     For c = 0 To Hres-1
       If trace2(c+1) > median+0.1 And trace2(c) < median+0.2 Then find_trigger = c : Exit Function
     Next
     find_trigger = -1 : Exit Function
   Case Else
     find_trigger = 0 : Exit Function
 End Select
End Function

Sub Display_Instructions
 Local i, j
 FRAMEBUFFER WRITE L
 CLS Background
 Text   6, Vres/2, "Pico", CMV, 1, 1, T1_Color, Background
 Text   Hres-6, Vres/2, "Scope", CMV, 1, 1, T2_Color, Background
 Text   18,  3,     "Keyboard:", LT, 7, 1, TxtColor, Background
 Text   25, 15,     "Volt: 0, 1, 2, 3", LT, 7, 1, TxtColor, Background
 Text   25, 27,     "Time: Faster, Slower", LT, 7, 1, TxtColor, Background
 Text   25, 39,     "Trig: Up, Dn, None", LT, 7, 1, TxtColor, Background
 Text   25, 51,     "Pin 24: Test Signal", LT, 7, 1, TxtColor, Background
 FRAMEBUFFER COPY L, F
 FRAMEBUFFER COPY F,N
 Pause 4000

 Select Case Trig_Type
   Case Trig_Up_1, Trig_Down_1, Trig_None_1: Text 20, 79, "Waiting for Trigger, Ch 1", LB, 7, 1, T1_Color, Background
   Case Trig_Up_2, Trig_Down_2, Trig_None_2: Text 20, 79, "Waiting for Trigger, Ch 2", LB, 7, 1, T2_Color, Background
 End Select

 FRAMEBUFFER COPY L, F
 FRAMEBUFFER COPY F,N
End Sub

Sub Display_No_Trigger
 FRAMEBUFFER WRITE L
 Select Case Trig_Type
   Case Trig_Up_1, Trig_Down_1, Trig_None_1: Text Hres/2, Vres/2, "Waiting for Trigger, Ch 1", CM, 7, 1, T1_Color, Background
   Case Trig_Up_2, Trig_Down_2, Trig_None_2: Text Hres/2, Vres/2, "Waiting for Trigger, Ch 2", CM, 7, 1, T2_Color, Background
 End Select
 FRAMEBUFFER COPY L, F
 FRAMEBUFFER COPY F,N
End Sub

Sub Initialize_Arrays
 addr.trace1  = Peek(varaddr trace1())
 addr.trace2  = Peek(varaddr trace2())
 addr.buffer1 = Peek(varaddr buffer1())
 addr.buffer2 = Peek(varaddr buffer2())

 Math Set 0, HMajory1() : Math Set Vres, HMajory2()  ' Set Arrays for Time  Major Axis
 Math Set 0, VMajorX1() : Math Set Hres, VMajorx2()  ' Set Arrays for Volts Major Axis

 Math Set 3*Vres/4+Minor/2, HMinory1()
 Math Set 3*Vres/4-Minor/2, HMinory2() ' Set Arrays for Time  Minor Axis
 Math Set Hres/2+Minor/2,   VMinorx1()
 Math Set Hres/2-Minor/2,   VMinorx2() ' Set Arrays for Volts Minor Axis

 For x = 0 To Hres-1 : Horizontal(x) = x     : Next ' used in array graphics
 For x = 0 To HMajor : HMajorx1(x) = x*Major : Next ' for Time  Major Axis graticule
 For y = 0 To VMajor : VMajory1(y) = y*Major : Next ' for Volts Major Axis graticule
 For x = 0 To HMinor : HMinorx1(x) = x*Minor : Next ' for Time  Minor Axis graticule
 For y = 0 To VMinor : VMinory1(y) = y*Minor : Next ' for Volts Minor Axis graticule

 ' RP2040-LCD-0.96 - specific values here.
 '
 ' For Voltage, Zero is at pixel 60, 3/4 down the display
 V.Scale(0)= -4.0 : V.Offset(0)=60 : V.MajVolts(0) = 5.000 ' 5.000 Volts per Major Division
 V.Scale(1)= -8.0 : V.Offset(1)=60 : V.MajVolts(1) = 2.500 ' 2.500 Volts per Major Division
 V.Scale(2)=-16.0 : V.Offset(2)=60 : V.MajVolts(2) = 1.250 ' 1.250 Volts per Major Division
 V.Scale(3)=-32.0 : V.Offset(3)=60 : V.MajVolts(3) = 0.675 ' 0.675 Volts per Major Division

 ' For Time,

 H.Freq(0) =   1000 : H.Units(0)="mSec" : H.Seconds(0) = 20.0
 H.Freq(1) =   2000 : H.Units(1)="mSec" : H.Seconds(1) = 10.0
 H.Freq(2) =   4000 : H.Units(2)="mSec" : H.Seconds(2) = 5.0
 H.Freq(3) =  10000 : H.Units(3)="mSec" : H.Seconds(3) = 2.0
 H.Freq(4) =  20000 : H.Units(4)="mSec" : H.Seconds(4) = 1.0
 H.Freq(5) =  40000 : H.Units(5)="uSec" : H.Seconds(5) = 500.0
 H.Freq(6) = 100000 : H.Units(6)="uSec" : H.Seconds(6) = 200.0
 H.Freq(7) = 200000 : H.Units(7)="uSec" : H.Seconds(7) = 100.0
'  H.Freq(8) = 400000 : H.Units(8)="uSec" : H.Seconds(8) = 50.0 - too fast for 2 channels

 ADC_select = 3              ' Select from a number of time scales
 Vselect    = 1              ' Select from a number of Scale factors and offsets for volts
 Trig_Type  = Trig_Down_1    ' Select from a number of trigger types

End Sub

Sub Initialize_Hardware
 SetPin V_SW, INTL, V_ISR, PULLUP ' Switch to cycle through Voltage scales
 SetPin T_SW, INTL, T_ISR, PULLUP ' Switch to cycle through Trigger types
 SetPin A_SW, INTL, A_ISR, PULLUP ' Switch to cycle through ADC Frequency (Time) scales
 SetPin GP18, PWM1A               ' Set up pin 24 for PWM test signal output
 PWM 1, PWM_Freq, PWM_Duty        ' Square wave on Pin 24
 SetPin ADC1_Pin, AIn             ' ADC input on Pin 31
 SetPin ADC2_Pin, AIn
 ADC open H.Freq(ADC_Select), 2   ' Sample at specified frequency

 FRAMEBUFFER CREATE F
 FRAMEBUFFER LAYER  L
End Sub

Sub Set_ADC_Timing
 ADC FREQUENCY H.Freq(ADC_Select)
End Sub

Sub Draw_Graticules
 Local STRING T$, V$, A$
 FRAMEBUFFER WRITE L
 CLS Background
 Line HMinorx1(), HMinory1(), HMinorx1(), HMinory2(), 1, GMinor ' Draw minor horiz graticules
 Line VMinorx1(), VMinory1(), VMinorx2(), VMinory1(), 1, GMinor ' Draw minor vert  graticules
 Line HMajorx1(), HMajory1(), HMajorx1(), HMajory2(), 1, GMajor ' Draw major horiz graticules
 Line VMajorx1(), VMajory1(), VMajorx2(), VMajory1(), 1, GMajor ' Draw major vert  graticules

 A$ = Str$(H.Seconds(ADC_Select),3,0) + " " + H.Units(ADC_Select)
 Text    0, Vres, A$, LB, 7, 1, TxtColor, Background     ' Draw Time Scale at Lower Left
 V$ = Str$(V.MajVolts(Vselect), 2, 2)+" V"
 Text Hres, Vres, V$, RB, 7, 1, TxtColor, Background     ' Draw Volts Scale at Lower Right
 Select Case Trig_Type
   Case Trig_Up_1:   Text Hres/2, Vres, "/", CB, 7, 1, T1_Color, Background
   Case Trig_Down_1: Text Hres/2, Vres, "\", CB, 7, 1, T1_Color, Background
   Case Trig_None_1: Text Hres/2, Vres, "-", CB, 7, 1, T1_Color, Background
   Case Trig_Up_2:   Text Hres/2, Vres, "/", CB, 7, 1, T2_Color, Background
   Case Trig_Down_2: Text Hres/2, Vres, "\", CB, 7, 1, T2_Color, Background
   Case Trig_None_2: Text Hres/2, Vres, "-", CB, 7, 1, T2_Color, Background
   Case Else :       Text Hres/2, Vres, " ", CB, 7, 1, T1_Color, Background
 End Select
End Sub

Sub Randomize_Test_Signal
 PWM 1, PWM_Freq, PWM_Duty+PWM_Jitter*Rnd  ' Randomize duty cycle to ensure displayed signal is refreshing
End Sub

Sub Get_Samples               ' Load ADC inputs into sample() array
 trace1(2*Hres-1) = -1       ' Samples will never be < 0
 ADC start trace1(), trace2()
 Do While trace1(2*Hres-1) < 0 : Loop
End Sub

Sub Scale_Samples
 Memory copy FLOAT addr.trace1 + trigger*8, addr.buffer1, Hres
 Memory copy FLOAT addr.trace2 + trigger*8, addr.buffer2, Hres
 Math Scale buffer1!(), V.Scale(Vselect),  buffer1!()  ' Scale samples to fit vertically
 Math Scale buffer2!(), V.Scale(Vselect),  buffer2!()  ' Scale samples to fit vertically
 Math Add   buffer1!(), V.Offset(Vselect), buffer1!()  ' Offset to bottom of screen (positive is up)
 Math Add   buffer2!(), V.Offset(Vselect), buffer2!()  ' Offset to bottom of screen (positive is up)
End Sub


Sub Update_Display
 FRAMEBUFFER COPY L, F
 FRAMEBUFFER WRITE F : Pixel Horizontal(), buffer1!(), T1_color
 FRAMEBUFFER WRITE F : Pixel Horizontal(), buffer2!(), T2_color
 FRAMEBUFFER COPY F,N
End Sub

Edited 2023-09-08 07:07 by NPHighview
Live in the Future. It's Just Starting Now!
 
stanleyella

Guru

Joined: 25/06/2022
Location: United Kingdom
Posts: 2129
Posted: 10:09pm 07 Sep 2023
Copy link to clipboard 
Print this post

Very tidy code. I just got to find frequency and the a way to get it to how many cycles by changing sample rate, 4 is nice cycles using ili9341 but frame layer L is fine, I wouldn't bother with what looks like a hospital "scope"

 SetPin GP2,pwm1A 'this optional test signal comment out
 PWM 1,1000,30  'square wave ,this optional test signal comment out
 dim c%,x%,samples!(480)
 SETPIN (31), AIn 'this is adc input pin
 adc open 50000,1 'this is sampling rate
 FRAMEBUFFER CREATE F:FRAMEBUFFER LAYER L:FRAMEBUFFER WRITE L 'all graphics to layer L
 line 119,0,119,239,,rgb(blue):line 0,119,239,119,,rgb(blue) 'draw cross to layer L
 FRAMEBUFFER WRITE F 'all graphics to framebuffer
 
 do
   adc start samples!() 'get new samples
   'trigger
   c%=0
   do:If samples!(c%+1) > 0.1 then if samples!(c%) < 0.2 then exit do
   inc c%:loop while c%<240

math scale samples!(),199/3.3,samples!():math add samples!(),20,samples!():FRAMEBUFFER COPY L,F 'copy cross on layer L to framebuffer
for x%=0 to 238 'screen width
     line x%,239-samples!(x%+c%),x%+1,239-samples!(x%+1+c%),,rgb(red)  'draw new sample from sample(c%)
     pixel x%,239-samples!(x%+c%),rgb(white) 'plot new sample from sample(c%)
   next x%
FRAMEBUFFER COPY F,N 'copy frame buffer to display
loop

 
stanleyella

Guru

Joined: 25/06/2022
Location: United Kingdom
Posts: 2129
Posted: 03:08pm 08 Sep 2023
Copy link to clipboard 
Print this post

@NPH, I just seen your latest code and the image looks impressive. You really got it sorted. Excellent work. Lots of new stuff me to learn ,memory copy, peek ,math mean. stan.
 
stanleyella

Guru

Joined: 25/06/2022
Location: United Kingdom
Posts: 2129
Posted: 07:41pm 08 Sep 2023
Copy link to clipboard 
Print this post

it's one's learning new stuff elevates from noob to confused noob :)
sorry, me
Edited 2023-09-09 05:44 by stanleyella
 
NPHighview

Senior Member

Joined: 02/09/2020
Location: United States
Posts: 200
Posted: 10:17pm 08 Sep 2023
Copy link to clipboard 
Print this post

Stan - Thanks. Never too late for me to learn something, for sure.

I was skimming my code and realized that I was regenerating graticules every time the main loop handled switch presses. Making that conditional on debounced keys cut the execution time by 15% :-)

Now, to look at this with two new Waveshare display boards, each with 2 or more integral switches, a joystick, and a MicroSD socket. Just ordered; should be here in 2-3 weeks.

- Steve
Live in the Future. It's Just Starting Now!
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2136
Posted: 12:35am 09 Sep 2023
Copy link to clipboard 
Print this post

Some minor improvement to my last scope program.
When in the trigger level was set to a fixed value and the input changed so it no longer crossed that value it would loose track of the frequency. And not recover when the input was restored. Now fixed, along with the previous issue.

Scope_Auto F & V4.zip

 
NPHighview

Senior Member

Joined: 02/09/2020
Location: United States
Posts: 200
Posted: 12:39am 09 Sep 2023
Copy link to clipboard 
Print this post

Very nice! Is the blue line at the trigger level?
Live in the Future. It's Just Starting Now!
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2136
Posted: 12:59am 09 Sep 2023
Copy link to clipboard 
Print this post

Yes, and though not easily visible in the pic. at the right is it's voltage.
 
stanleyella

Guru

Joined: 25/06/2022
Location: United Kingdom
Posts: 2129
Posted: 03:08pm 09 Sep 2023
Copy link to clipboard 
Print this post

Nice phil99. works on 1l19341.
 
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 396
Posted: 06:21pm 09 Sep 2023
Copy link to clipboard 
Print this post

phil99, I tested your scope program and I am really amazed what can be done with MMBASIC and the pico. Just wonderful, there is so much to learn!

Greetings
Daniel
 
stanleyella

Guru

Joined: 25/06/2022
Location: United Kingdom
Posts: 2129
Posted: 08:59pm 09 Sep 2023
Copy link to clipboard 
Print this post

Daniel. Dunno how this scope idea started but it's been a learn as needed and I am learning so much more stuff I wouldn't have thought of using without a "target" to reach.
I'm a noob as I need the manual and forum help then I'm a more clever noob.
I suggest get any display running and then display something. first time is cool if it works. then display something like sprites. more fun than flashing leds
 
stanleyella

Guru

Joined: 25/06/2022
Location: United Kingdom
Posts: 2129
Posted: 04:20pm 10 Sep 2023
Copy link to clipboard 
Print this post

I tried
[17] Math (MIN samples!(), c%)
Error : Syntax
MATH(MIN a(), [index%])
Returns the minimum of all values in the a() array, a() can have any number
of dimensions. If the integer variable is specified then it will be updated
with the index of the maximum value in the array. This is only available on
one-dimensional arrays.
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2136
Posted: 10:44pm 10 Sep 2023
Copy link to clipboard 
Print this post

[17] Math (MIN samples!(), c%) <-------space Math  (
Error : Syntax
MATH(MIN a(), [index%]) <-------no space Math(
 
stanleyella

Guru

Joined: 25/06/2022
Location: United Kingdom
Posts: 2129
Posted: 01:10pm 11 Sep 2023
Copy link to clipboard 
Print this post


   adc start samples!() 'get new samples

Math(MIN samples!(), c%)
print c%


>
RUN
[19] Math (MIN samples!(), c%)
Error : Syntax
>
>It's not the space phil99
also, " If the integer variable is specified then it will be updated
with the index of the maximum value in the array."
I was expecting math min to show the lowest value as element c% not the maximum??
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9126
Posted: 01:26pm 11 Sep 2023
Copy link to clipboard 
Print this post

MATH(MIN ...)  is a function, NOT a command
 
     Page 15 of 17    
Print this page
© JAQ Software 2024