A simple oscilloscope using Adafruit 2.8" TFT with touch. Runs on FRDM-KL25Z, FRDM-K22F, FRDM-K64F, NUCLEO-F411RE. 2 channel analog inputs with 4 trigger modes and time division.

Dependencies:   SPI_STMPE610 UniGraphic mbed vt100

My first attempt of implementing an oscilloscope using FRDM-KL25Z and Adafruit 2.8" TFT with touch.

FRDM-KL25Z と Adafruit 2.8" TFT with touch を使用して作ってみた最初のオシロスコープです。

On 25-Sep-2017, wrong calculation of trigger pos/val fixed.
On 25-Nov-2015, FRDM-K64F and NUCLEO-F411RE platforms were added.
On 26-Nov-2015, FRDM-K22F is added (tested).
Note: Now ch2 is A2 instead of A1!

25-Sep-2017, トリガー値と位置の計算の誤りを修正しました。
25-Nov-2015, FRDM-K64F と NUCLEO-F411RE でも動くようになりました。
26-Nov-2015, FRDM-K22F でも動作確認が出来ました。 ※一身上の都合で、アナログ入力の ch2 は A1 から A2 に変更しましたので、ご注意ください。m(_ _)m

/media/uploads/Rhyme/oscillo_top.jpg

This supports two analog inputs A0 for channel 1 and A2 for channel 2
and four trigger modes (NONE, RISE, FALL, LEVEL),
time division is 30us to 20ms per pixel which will make 300us/div to 200.0ms/div (as 10 pixels per div)

A0と A2 のアナログ2入力にて、
4種類のトリガーモード(NONE: フリーラン RISE: 立ち上がりエッジ、FALL: 立下りエッジ、LEVEL: レベル) 。
サンプリングは30us から 20ms, チャートの1メモリが10ピクセルなので、300us/dev から 200.0ms/div となっています。

The analog signals and gnd was picked at the pins in the picture above.
Note: now you need to pick A0 and A2 instead of A0 and A1.

信号は上記の写真のように、Adafruit のピンからつまみました。
変更により、A0とA2が入力となります。

/media/uploads/Rhyme/freerunmode.jpg

When powered on or reset, the program starts in Trigger Mode = NONE (Free Run Mode)

電源投入、リセット後 プログラムはトリガーモード NONE (フリーランモード) で起動します。

To change trigger mode and/or time division, press run/stop button.

トリガーモードを変えたり、サンプリング時間を変えるのには run/stop ボタンを押してください。

Each time you push Trig button, the trigger mode changes
NONE -> RISE -> FALL -> LEVEL ( -> NONE).

トリガーボタンを押すたびにトリガーモードは
NONE(フリーラン) -> RISE (立ち上がりエッジ) -> FALL (立下りエッジ) -> LEVEL (レベル)
と変化します。

When trigger mode is not NONE,
to specify the trigger position, level and channel, push inside the wave frame.
Then green trigger marks will be shown and value of trigger position and voltage will be printed.

トリガーモードが NONE でないときに、チャネルの枠内をタッチしますと、
その位置がトリガーのポジション、レベル、チャネルになります。 そして、緑色のトリガーマークが表示され、下部にはトリガーの具体的なポジションとボルテージが表示されます。

/media/uploads/Rhyme/usage_screen1.jpg

To change time division push "1/2" to Zoom Out (sampling interval will be bigger) or
"x2" to Zoom In (Sampling interval will be smaller).

サンプリングタイムを変更するのには
"1/2" ズームアウト (サンプリング間隔が長くなります) か
"x2" ズームイン (サンプリング間隔が短くなります。) を押してください。

/media/uploads/Rhyme/helps.jpg

On 7-Mar-2015 updated to UniGraphic library version!

2015年3月7日 UniGraphic ライブラリ使用版にアップデートしました。

/media/uploads/Rhyme/frdm-kl25z-ss.jpg FRDM-KL25Z
/media/uploads/Rhyme/frdm-k64f-ss.jpg FRDM-K64F
/media/uploads/Rhyme/nucleo-f411re-ss.jpg NUCLEO-F411RE

Committer:
Rhyme
Date:
Mon Sep 25 02:09:53 2017 +0000
Revision:
10:bd3d8d71ee73
Parent:
3:ea0c3cffa988
miss calc of trigger value/pos fixed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Rhyme 0:2b9a6c5fcd52 1 /** mbed oscilloscope my implementation of a oscillo scope
Rhyme 0:2b9a6c5fcd52 2 * Copyright (c) 2014, 2015 Motoo Tanaka @ Design Methodology Lab
Rhyme 0:2b9a6c5fcd52 3 *
Rhyme 0:2b9a6c5fcd52 4 * TFTMenu.cpp
Rhyme 0:2b9a6c5fcd52 5 *
Rhyme 0:2b9a6c5fcd52 6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Rhyme 0:2b9a6c5fcd52 7 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Rhyme 0:2b9a6c5fcd52 8 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Rhyme 0:2b9a6c5fcd52 9 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Rhyme 0:2b9a6c5fcd52 10 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Rhyme 0:2b9a6c5fcd52 11 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
Rhyme 0:2b9a6c5fcd52 12 * THE SOFTWARE.
Rhyme 0:2b9a6c5fcd52 13 */
Rhyme 0:2b9a6c5fcd52 14 #include "mbed.h"
Rhyme 3:ea0c3cffa988 15 #include <ILI9341.h>
Rhyme 0:2b9a6c5fcd52 16 #include "SPI_STMPE610.h"
Rhyme 0:2b9a6c5fcd52 17 #include "Arial12x12.h"
Rhyme 0:2b9a6c5fcd52 18 #include "Arial24x23.h"
Rhyme 0:2b9a6c5fcd52 19 #include "Arial28x28.h"
Rhyme 3:ea0c3cffa988 20 #include "Arial43x48_numb.h"
Rhyme 0:2b9a6c5fcd52 21 #include "vt100.h"
Rhyme 0:2b9a6c5fcd52 22 #include <string.h>
Rhyme 0:2b9a6c5fcd52 23
Rhyme 0:2b9a6c5fcd52 24 #include "TFTMenu.h"
Rhyme 0:2b9a6c5fcd52 25
Rhyme 3:ea0c3cffa988 26 extern ILI9341 TFT ;
Rhyme 0:2b9a6c5fcd52 27 extern SPI_STMPE610 TSC ;
Rhyme 0:2b9a6c5fcd52 28 extern vt100 *tty ;
Rhyme 0:2b9a6c5fcd52 29
Rhyme 0:2b9a6c5fcd52 30
Rhyme 0:2b9a6c5fcd52 31 TFTMenuItem::TFTMenuItem(int x1, int y1, int x2, int y2, FuncPtr fnc,
Rhyme 0:2b9a6c5fcd52 32 char *name, uint16_t mcolor, uint16_t fcolor )
Rhyme 0:2b9a6c5fcd52 33 {
Rhyme 0:2b9a6c5fcd52 34 left = x1 ;
Rhyme 0:2b9a6c5fcd52 35 right = x2 ;
Rhyme 0:2b9a6c5fcd52 36 top = y1 ;
Rhyme 0:2b9a6c5fcd52 37 bottom = y2 ;
Rhyme 0:2b9a6c5fcd52 38 if (name) {
Rhyme 0:2b9a6c5fcd52 39 label = new char[strlen(name)+1] ;
Rhyme 0:2b9a6c5fcd52 40 strcpy(label, name) ;
Rhyme 0:2b9a6c5fcd52 41 font_color = fcolor ;
Rhyme 0:2b9a6c5fcd52 42 }
Rhyme 0:2b9a6c5fcd52 43 menu_color = mcolor ;
Rhyme 0:2b9a6c5fcd52 44
Rhyme 0:2b9a6c5fcd52 45 left_margin = 7 ;
Rhyme 0:2b9a6c5fcd52 46 top_margin = 10 ;
Rhyme 0:2b9a6c5fcd52 47 func = fnc ;
Rhyme 0:2b9a6c5fcd52 48 }
Rhyme 0:2b9a6c5fcd52 49
Rhyme 0:2b9a6c5fcd52 50 TFTMenuItem::~TFTMenuItem()
Rhyme 0:2b9a6c5fcd52 51 {
Rhyme 0:2b9a6c5fcd52 52 left = 0 ;
Rhyme 0:2b9a6c5fcd52 53 right = 0 ;
Rhyme 0:2b9a6c5fcd52 54 top = 0 ;
Rhyme 0:2b9a6c5fcd52 55 bottom = 0 ;
Rhyme 0:2b9a6c5fcd52 56 if (label) {
Rhyme 0:2b9a6c5fcd52 57 free(label) ;
Rhyme 0:2b9a6c5fcd52 58 }
Rhyme 0:2b9a6c5fcd52 59 }
Rhyme 0:2b9a6c5fcd52 60
Rhyme 0:2b9a6c5fcd52 61 TFTRadioButton::TFTRadioButton(int x1, int y1, int x2, int y2, FuncPtr fnc,
Rhyme 0:2b9a6c5fcd52 62 char *name, uint16_t mcolor, uint16_t fcolor,
Rhyme 0:2b9a6c5fcd52 63 char *altname, uint16_t altmcolor, uint16_t altfcolor,
Rhyme 0:2b9a6c5fcd52 64 bool sel) : TFTMenuItem(x1,y1,x2,y2,fnc,name,mcolor,fcolor)
Rhyme 0:2b9a6c5fcd52 65 {
Rhyme 0:2b9a6c5fcd52 66 if (altname) {
Rhyme 0:2b9a6c5fcd52 67 alt_label = new char[strlen(altname) + 1] ;
Rhyme 0:2b9a6c5fcd52 68 strcpy(alt_label, altname) ;
Rhyme 0:2b9a6c5fcd52 69 } else {
Rhyme 0:2b9a6c5fcd52 70 alt_label = 0 ;
Rhyme 0:2b9a6c5fcd52 71 }
Rhyme 0:2b9a6c5fcd52 72 alt_font_color = altfcolor ;
Rhyme 0:2b9a6c5fcd52 73 alt_menu_color = altmcolor ;
Rhyme 0:2b9a6c5fcd52 74 selected = sel ;
Rhyme 0:2b9a6c5fcd52 75 }
Rhyme 0:2b9a6c5fcd52 76
Rhyme 0:2b9a6c5fcd52 77 TFTRadioButton::~TFTRadioButton()
Rhyme 0:2b9a6c5fcd52 78 {
Rhyme 0:2b9a6c5fcd52 79 left = 0 ;
Rhyme 0:2b9a6c5fcd52 80 right = 0 ;
Rhyme 0:2b9a6c5fcd52 81 top = 0 ;
Rhyme 0:2b9a6c5fcd52 82 bottom = 0 ;
Rhyme 0:2b9a6c5fcd52 83 if (label) {
Rhyme 0:2b9a6c5fcd52 84 delete label ;
Rhyme 0:2b9a6c5fcd52 85 }
Rhyme 0:2b9a6c5fcd52 86 if (alt_label) {
Rhyme 0:2b9a6c5fcd52 87 delete alt_label ;
Rhyme 0:2b9a6c5fcd52 88 }
Rhyme 0:2b9a6c5fcd52 89 }
Rhyme 0:2b9a6c5fcd52 90
Rhyme 0:2b9a6c5fcd52 91 bool TFTRadioButton::hit(int x, int y)
Rhyme 0:2b9a6c5fcd52 92 {
Rhyme 0:2b9a6c5fcd52 93 bool result = false ;
Rhyme 0:2b9a6c5fcd52 94 if ((left <= x)&&(x <= right)&&(top <= y)&&(y <= bottom)) {
Rhyme 0:2b9a6c5fcd52 95 result = true ;
Rhyme 0:2b9a6c5fcd52 96 if (selected) {
Rhyme 0:2b9a6c5fcd52 97 selected = false ;
Rhyme 0:2b9a6c5fcd52 98 } else {
Rhyme 0:2b9a6c5fcd52 99 selected = true ;
Rhyme 0:2b9a6c5fcd52 100 }
Rhyme 0:2b9a6c5fcd52 101 draw() ;
Rhyme 0:2b9a6c5fcd52 102 }
Rhyme 0:2b9a6c5fcd52 103 return( result ) ;
Rhyme 0:2b9a6c5fcd52 104 }
Rhyme 0:2b9a6c5fcd52 105
Rhyme 0:2b9a6c5fcd52 106 void TFTRadioButton::select(bool value)
Rhyme 0:2b9a6c5fcd52 107 {
Rhyme 0:2b9a6c5fcd52 108 selected = value ;
Rhyme 0:2b9a6c5fcd52 109 }
Rhyme 0:2b9a6c5fcd52 110
Rhyme 0:2b9a6c5fcd52 111 uint16_t TFTMenuItem::getColor(void)
Rhyme 0:2b9a6c5fcd52 112 {
Rhyme 0:2b9a6c5fcd52 113 return(menu_color) ;
Rhyme 0:2b9a6c5fcd52 114 }
Rhyme 0:2b9a6c5fcd52 115
Rhyme 0:2b9a6c5fcd52 116 bool TFTMenuItem::hit(int x, int y)
Rhyme 0:2b9a6c5fcd52 117 {
Rhyme 0:2b9a6c5fcd52 118 bool result = false ;
Rhyme 0:2b9a6c5fcd52 119 if ((left <= x)&&(x <= right)&&(top <= y)&&(y <= bottom)) {
Rhyme 0:2b9a6c5fcd52 120 result = true ;
Rhyme 0:2b9a6c5fcd52 121 draw() ;
Rhyme 0:2b9a6c5fcd52 122 }
Rhyme 0:2b9a6c5fcd52 123 // draw() ;
Rhyme 0:2b9a6c5fcd52 124 return( result ) ;
Rhyme 0:2b9a6c5fcd52 125 }
Rhyme 0:2b9a6c5fcd52 126
Rhyme 0:2b9a6c5fcd52 127 void TFTMenuItem::doIt(void)
Rhyme 0:2b9a6c5fcd52 128 {
Rhyme 0:2b9a6c5fcd52 129 if (func) {
Rhyme 0:2b9a6c5fcd52 130 func() ;
Rhyme 0:2b9a6c5fcd52 131 }
Rhyme 0:2b9a6c5fcd52 132 }
Rhyme 0:2b9a6c5fcd52 133
Rhyme 0:2b9a6c5fcd52 134 void TFTMenuItem::draw(int offset_x, int offset_y)
Rhyme 0:2b9a6c5fcd52 135 {
Rhyme 3:ea0c3cffa988 136 TFT.BusEnable(true) ;
Rhyme 0:2b9a6c5fcd52 137 TFT.fillrect(left+offset_x, top+offset_y, right+offset_x, bottom+offset_y, Black) ;
Rhyme 0:2b9a6c5fcd52 138 TFT.fillrect(left+offset_x, top+offset_y, right+offset_x, bottom+offset_y, menu_color) ;
Rhyme 0:2b9a6c5fcd52 139 wait(0.1) ;
Rhyme 0:2b9a6c5fcd52 140 TFT.locate(left+offset_x+left_margin, top+offset_y+top_margin) ;
Rhyme 0:2b9a6c5fcd52 141 TFT.foreground(font_color) ;
Rhyme 0:2b9a6c5fcd52 142 TFT.background(menu_color) ;
Rhyme 0:2b9a6c5fcd52 143 TFT.set_font((unsigned char *)Arial12x12) ;
Rhyme 0:2b9a6c5fcd52 144 wait(0.1) ;
Rhyme 0:2b9a6c5fcd52 145 TFT.printf(label) ;
Rhyme 3:ea0c3cffa988 146 TFT.BusEnable(false) ;
Rhyme 0:2b9a6c5fcd52 147 }
Rhyme 0:2b9a6c5fcd52 148
Rhyme 0:2b9a6c5fcd52 149 void TFTRadioButton::draw(int offset_x, int offset_y)
Rhyme 0:2b9a6c5fcd52 150 {
Rhyme 3:ea0c3cffa988 151 TFT.BusEnable(true) ;
Rhyme 0:2b9a6c5fcd52 152 if (selected) {
Rhyme 0:2b9a6c5fcd52 153 TFT.fillrect(left+offset_x, top+offset_y, right+offset_x, bottom+offset_y, Black) ;
Rhyme 0:2b9a6c5fcd52 154 TFT.fillrect(left+offset_x, top+offset_y, right+offset_x, bottom+offset_y, alt_menu_color) ;
Rhyme 0:2b9a6c5fcd52 155 wait(0.1) ;
Rhyme 0:2b9a6c5fcd52 156 TFT.locate(left+offset_x+left_margin, top+offset_y+top_margin) ;
Rhyme 0:2b9a6c5fcd52 157 TFT.foreground(alt_font_color) ;
Rhyme 0:2b9a6c5fcd52 158 TFT.background(alt_menu_color) ;
Rhyme 0:2b9a6c5fcd52 159 TFT.set_font((unsigned char *)Arial12x12) ;
Rhyme 0:2b9a6c5fcd52 160 wait(0.1) ;
Rhyme 0:2b9a6c5fcd52 161 TFT.printf(alt_label) ;
Rhyme 0:2b9a6c5fcd52 162 } else {
Rhyme 0:2b9a6c5fcd52 163 TFTMenuItem::draw(offset_x, offset_y) ;
Rhyme 0:2b9a6c5fcd52 164 }
Rhyme 3:ea0c3cffa988 165 TFT.BusEnable(false) ;
Rhyme 0:2b9a6c5fcd52 166 }
Rhyme 0:2b9a6c5fcd52 167
Rhyme 0:2b9a6c5fcd52 168
Rhyme 0:2b9a6c5fcd52 169 void TFTMenuItem::highlight(int offset_x, int offset_y)
Rhyme 0:2b9a6c5fcd52 170 {
Rhyme 3:ea0c3cffa988 171 TFT.BusEnable(true) ;
Rhyme 0:2b9a6c5fcd52 172 TFT.rect(left+offset_x, top+offset_y, right+offset_x, bottom+offset_y, font_color) ;
Rhyme 3:ea0c3cffa988 173 TFT.BusEnable(false) ;
Rhyme 0:2b9a6c5fcd52 174 /*
Rhyme 0:2b9a6c5fcd52 175 TFT.fillrect(left+offset_x, top+offset_y, right+offset_x, bottom+offset_y, font_color) ;
Rhyme 0:2b9a6c5fcd52 176 wait(0.1) ;
Rhyme 0:2b9a6c5fcd52 177 TFT.locate(left+offset_x+left_margin, top+offset_y+top_margin) ;
Rhyme 0:2b9a6c5fcd52 178 TFT.foreground(menu_color) ;
Rhyme 0:2b9a6c5fcd52 179 TFT.background(font_color) ;
Rhyme 0:2b9a6c5fcd52 180 TFT.set_font((unsigned char *)Arial12x12) ;
Rhyme 0:2b9a6c5fcd52 181 wait(0.1) ;
Rhyme 0:2b9a6c5fcd52 182 TFT.printf(label) ;
Rhyme 0:2b9a6c5fcd52 183 */
Rhyme 0:2b9a6c5fcd52 184 }