專案

一般

配置概況

Feature #52 » myLCD_NSP32.ino.ino

慶瑋 陳, 2023-11-12 10:59

 
#include "FS.h"
#include "ArduinoAdaptor.h"
#include <ESP32Time.h>
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
//#include "SD.h"
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
#include <NSP32.h>
#include <string.h>

ESP32Time rtc;
using namespace NanoLambdaNSP32;
//**********************************************
//壓感pin
int ADC_data=0;
#define ADC_PIN 35
//**********************************************
//SD CARD PIN 改 NSP32
#define VSPI_MISO 19
#define VSPI_MOSI 23
#define VSPI_SCLK 18
//#define VSPI_SS 5

const unsigned int PinRst = 21;
const unsigned int PinReady = 17;

ArduinoAdaptor adaptor(PinRst); // master MCU adaptor
NSP32 nsp32(&adaptor, NSP32::ChannelSpi); // NSP32 (using SPI channel)

int NOP = 0; // number of points

void PinReadyTriggerISR() {
// make sure to call this function when receiving a ready trigger from NSP32
nsp32.OnPinReadyTriggered();
}
/**********************************************
//for data file
File dataFile;
char* line[157];
String lines[150] ={};
int lineNum = 0;
int lines_to_read = 121;//想讀取的列數
**********************************************/

TFT_eSPI tft = TFT_eSPI(); // Invoke custom library

// This is the file name used to store the calibration data
// You can change this to create new calibration files.
// The SPIFFS file name must start with "/".
#define CALIBRATION_FILE "/TouchCalData1"

// Set REPEAT_CAL to true instead of false to run calibration
// again, otherwise it will only be done once.
// Repeat calibration if you change the screen rotation.
#define REPEAT_CAL false

#define KEY_X 40 //按鍵位置
#define KEY_Y 240 //按鍵位置
#define KEY_W 72 //按鍵寬度
#define KEY_H 32 //按鍵高度
#define KEY_SPACING_X 5 // 按鍵間距
#define KEY_SPACING_Y 20 // 按鍵間距
#define KEY_TEXTSIZE 1 // Font size multiplier

// Using two fonts since numbers are nice when bold
#define LABEL1_FONT &FreeSansOblique12pt7b // Key label font 1
#define LABEL2_FONT &FreeSansBold12pt7b // Key label font 2

#define DISP_X 20 //示波畫面左上角X位置
#define DISP_Y 10 //示波畫面左上角y位置
#define DISP_W 182 //示波畫面寬度
#define DISP_H 180 //示波畫面高度
#define DISP_TSIZE 10 //暫時不知道
#define DISP_TCOLOR TFT_RED //畫面圖的顏色

// Number length, buffer for storing it and character index
#define NUM_LEN 12
char numberBuffer[NUM_LEN + 1] = "";
uint8_t numberIndex = 0;

// We have a status line for messages
#define STATUS_X 120 // Centred on this
#define STATUS_Y 65

// Create 3 keys for the keypad

char keyLabel[3][7] = {"Start", "On", "Detect"};
uint16_t keyColor[3] = {TFT_DARKGREY, TFT_DARKGREY, TFT_DARKGREY};

// Invoke the TFT_eSPI button class and create all the button objects
TFT_eSPI_Button key[3];

//校正螢幕範圍



void setup() {

// Use serial port
pinMode(5,OUTPUT);
pinMode(15,OUTPUT);
pinMode(16,OUTPUT);
digitalWrite(5, HIGH);
digitalWrite(15, HIGH);
digitalWrite(16, HIGH);
Serial.begin(115200);
Serial.println("Ready");
//******************NSP32***********************
// initialize "ready trigger" pin for accepting external interrupt (falling edge trigger)
pinMode(PinReady, INPUT_PULLUP); // use pull-up
attachInterrupt(digitalPinToInterrupt(PinReady), PinReadyTriggerISR, FALLING); // enable interrupt for falling edge

// initialize NSP32
nsp32.Init();
// initialize serial port for "Serial Monitor"
// Initialise the TFT screen
tft.init();

rtc.setTime(0, 50, 21, 23, 5, 2023);

// =============== standby ===============
nsp32.Standby(0);
Serial.println("Standby");
tft.fillScreen(ILI9341_BLUE);
// =============== wakeup ===============
nsp32.Wakeup();
Serial.println("Wakeup");
tft.fillScreen(ILI9341_RED);
// =============== hello ===============
nsp32.Hello(0);
Serial.println("Hello");
tft.fillScreen(ILI9341_GREEN);
// =============== get sensor id ===============
Serial.println("e04");
tft.fillScreen(ILI9341_YELLOW);


char szSensorId[15]; // sensor id string buffer
nsp32.ExtractSensorIdStr(szSensorId); // now we have sensor id string in szSensorId[]

Serial.print(F("sensor id = "));
Serial.println(szSensorId);

// =============== get wavelength ===============
nsp32.GetWavelength(0);

WavelengthInfo infoW;
nsp32.ExtractWavelengthInfo(&infoW); // now we have all wavelength info in infoW, we can use e.g. "infoW.Wavelength" to access the wavelength data array
NOP = infoW.NumOfPoints;

Serial.printf("Number of points = %d\n", NOP);

Serial.println(F("Elements of wavelength = "));
for(int i = 0; i < NOP; i++){
Serial.printf("%d ",infoW.Wavelength[i]);
}
Serial.print("\n");
//**********************************************
//******************壓感*************************

pinMode(ADC_PIN,INPUT);
//**********************************************

// Set the rotation before we calibrate
tft.setRotation(0);

// Calibrate the touch screen and retrieve the scaling factors
touch_calibrate();

// Clear the screen
//tft.fillScreen(TFT_BLACK);

// Draw keypad
drawKeypad();
//顯示文字
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString("spectrum", 20, 200, 2);

tft.setTextSize(1);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString("RESULT:", 5, 260, 4);
//示波視窗
tft.fillRect(DISP_X, DISP_Y, DISP_W, DISP_H, TFT_BLACK);
tft.drawRect(DISP_X, DISP_Y, DISP_W, DISP_H, TFT_WHITE);
//tft.drawFastVLine(DISP_X+DISP_W/2,DISP_Y,DISP_H, TFT_LIGHTGREY);
//tft.drawFastHLine(DISP_X,DISP_Y+DISP_H/2,DISP_W, TFT_LIGHTGREY);

}
//------------------------------------------------------------------------------------------

void loop(void) {
//顯示壓力
ADC_data=analogRead(ADC_PIN);
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE, TFT_RED);
tft.drawString("FSR:", 10, 290, 2);
tft.setTextPadding(30);
tft.drawNumber( ADC_data, 50, 290, 2);
uint16_t t_x = 0, t_y = 0; // To store the touch coordinates

// Pressed will be set true is there is a valid touch on the screen
bool pressed = tft.getTouch(&t_x, &t_y);

// / Check if any key coordinate boxes contain the touch coordinates
//可按按鍵數
for (uint8_t b = 0; b < 3; b++) {
if (pressed && key[b].contains(t_x, t_y)) {
key[b].press(true); // tell the button it is pressed
} else {
key[b].press(false); // tell the button it is NOT pressed
}
}
// Check if any key has changed state
for (uint8_t b = 0; b < 3; b++) {

if (key[b].justReleased()) key[b].drawButton(); // draw normal

if (key[b].justPressed()) {
key[b].drawButton(true); // draw invert

// Del button, so delete last char 按鍵功能

if (b == 0) {
Serial.println("START");
}
if (b == 1) {
Serial.println("ON");
}

if (b == 2) {
Serial.println("DETECT");
}

delay(10); // UI debouncing
}
}
//*******************NSP32*************************
int timer = rtc.getSecond();


// =============== spectrum acquisition ===============
nsp32.AcqSpectrum(0, 32, 3, false); // integration time = 32; frame avg num = 3; disable AE

// "AcqSpectrum" command takes longer time to execute, the return packet is not immediately available
// when the acquisition is done, a "ready trigger" will fire, and nsp32.GetReturnPacketSize() will be > 0
while (nsp32.GetReturnPacketSize() <= 0) {
// TODO: can go to sleep, and wakeup when "ready trigger" interrupt occurs

nsp32.UpdateStatus(); // call UpdateStatus() to check async result
}

SpectrumInfo infoS;
nsp32.ExtractSpectrumInfo(&infoS); // now we have all spectrum info in infoW, we can use e.g. "infoS.Spectrum" to access the spectrum data array

Serial.println(F("Elements of spectrum = "));
for(int i = 0; i < NOP; i++){
Serial.printf("%.6f ", infoS.Spectrum[i], 6);
}
Serial.print("\n");

//counter++;

//Serial.printf("count: %d\n", counter);

Serial.print(rtc.getTime("%A, %B %d %Y %H:%M:%S:"));
Serial.println(rtc.getMillis());
//*************************************************
//示波
tft.fillRect(DISP_X, DISP_Y, DISP_W, DISP_H, TFT_BLACK);
tft.drawRect(DISP_X, DISP_Y, DISP_W, DISP_H, TFT_WHITE);
for(int x=0;x<60;x++){
double y = infoS.Spectrum[2*x]*2000;
//tft.drawFastVLine(x距, y距, 長度, TFT_LIGHTGREY);
tft.drawFastVLine(DISP_X+3*x, (DISP_Y+DISP_H)-y, y, TFT_RED);
tft.drawFastVLine(DISP_X+3*x+1, (DISP_Y+DISP_H)-y, y, TFT_GREEN);
tft.drawFastVLine(DISP_X+3*x+2, (DISP_Y+DISP_H)-y, y, TFT_BLUE);
tft.fillCircle(DISP_X+3*x+1, (DISP_Y+DISP_H)-y, 1, TFT_RED);
}
delay(2000);
}
//***************************************************
void touch_calibrate()
{
uint16_t calData[5];
uint8_t calDataOK = 0;

// check file system exists
if (!SPIFFS.begin()) {
Serial.println("Formating file system");
SPIFFS.format();
SPIFFS.begin();
}

// check if calibration file exists and size is correct
if (SPIFFS.exists(CALIBRATION_FILE)) {
if (REPEAT_CAL)
{
// Delete if we want to re-calibrate
SPIFFS.remove(CALIBRATION_FILE);
}
else
{
File f = SPIFFS.open(CALIBRATION_FILE, "r");
if (f) {
if (f.readBytes((char *)calData, 14) == 14)
calDataOK = 1;
f.close();
}
}
}

if (calDataOK && !REPEAT_CAL) {
// calibration data valid
tft.setTouch(calData);
} else {
// data not valid so recalibrate
tft.fillScreen(TFT_BLACK);
tft.setCursor(20, 0);
tft.setTextFont(2);
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE, TFT_BLACK);

tft.println("Touch corners as indicated");

tft.setTextFont(1);
tft.println();

if (REPEAT_CAL) {
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.println("Set REPEAT_CAL to false to stop this running again!");
}

tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);

tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.println("Calibration complete!");

// store data
File f = SPIFFS.open(CALIBRATION_FILE, "w");
if (f) {
f.write((const unsigned char *)calData, 14);
f.close();
}
}
}
void drawKeypad()
{
// Draw the keys
for (uint8_t row = 0; row < 1; row++) {
for (uint8_t col = 0; col < 3; col++) {
uint8_t b = col + row * 3;

tft.setFreeFont(LABEL1_FONT);


key[b].initButton(&tft, KEY_X + col * (KEY_W + KEY_SPACING_X),
KEY_Y + row * (KEY_H + KEY_SPACING_Y), // x, y, w, h, outline, fill, text
KEY_W, KEY_H, TFT_WHITE, keyColor[b], TFT_WHITE,
keyLabel[b], KEY_TEXTSIZE);
key[b].drawButton();
}
}
}
(2-2/2)