diff --git a/README.md b/README.md index c2dd5da..cc5b694 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,12 @@ TODO: - rewrite whole thing to C++, so adding new AWGs would be easier - add possibility to configure SSID/PSK + IP without flashing the new SW +Currently supported AWG's: + - FY6800 + - FY6900 + +You can view a video with the SDS-1204X-E and the FY6900 here https://www.youtube.com/watch?v=3_4DelT9P2A + **!WARNING! FY6800 VCC level is 5V, so it has to be dropped somehow to 3.3V ESP may release the magic smoke otherwise.** ![image test](img/connection.png) diff --git a/espBode.ino b/espBode.ino index f20a664..45a3b3e 100644 --- a/espBode.ino +++ b/espBode.ino @@ -1,15 +1,27 @@ #include #include "esp_network.h" #include "esp_config.h" -#include "esp_fy6800.h" + +#include "ESPTelnet.h" + +#if AWG == FY6800 + #include "esp_fy6800.h" +#elif AWG == FY6900 + #include "esp_fy6900.h" +#else + #error "Please select an AWG in esp_config.h" +#endif WiFiServer rpc_server(RPC_PORT); WiFiServer lxi_server(LXI_PORT); +ESPTelnet telnet; void setup() { Serial.begin(115200); + pinMode(LED_BUILTIN, OUTPUT); + // We start by connecting to a WiFi network DEBUG("Connecting to "); DEBUG(WIFI_SSID); @@ -33,11 +45,14 @@ void setup() { while (WiFi.status() != WL_CONNECTED) { delay(500); DEBUG("."); + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); } DEBUG("WiFi connected"); DEBUG("IP address: "); - DEBUG(WiFi.localIP()); + DEBUG(WiFi.localIP().toString()); + + telnet.begin(); rpc_server.begin(); lxi_server.begin(); @@ -68,12 +83,15 @@ void loop() { while(1) { + telnet.loop(); if(0 != handlePacket(lxi_client)) { lxi_client.stop(); DEBUG("RESTARTING"); return; + }else{ + // Lets give the user some feedback + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); } - } + } } - diff --git a/esp_config.h b/esp_config.h index c0fb31c..ac05d09 100644 --- a/esp_config.h +++ b/esp_config.h @@ -1,6 +1,15 @@ #ifndef _ESP_CONFIG_H_ #define _ESP_CONFIG_H_ +#include "ESPTelnet.h" +extern ESPTelnet telnet; + +#define FY6800 1 +#define FY6900 2 + +/* Select the FY6900 or FY6800 AWG*/ +#define AWG FY6900 + /* Select either AP or CLIENT mode: - AP - creates new network that oscilloscope can connect to - CLIENT - joins existing network @@ -13,7 +22,7 @@ #define WIFI_PSK "wlan_key" /* Comment this for DHCP. However you'll need to obtain IP somehow. */ -#define STATIC_IP +//#define STATIC_IP /* Static ip configuration */ #ifdef STATIC_IP @@ -46,7 +55,7 @@ #ifdef DEBUG_PRINTS #define DEBUG(TEXT) Serial.println(TEXT); #else - #define DEBUG(TEXT) + #define DEBUG(TEXT) telnet.println(TEXT); #endif #endif /* _ESP_CONFIG_H_ */ diff --git a/esp_fy6800.cpp b/esp_fy6800.cpp index 8a2d802..511c8cb 100644 --- a/esp_fy6800.cpp +++ b/esp_fy6800.cpp @@ -1,13 +1,18 @@ -#include "esp_fy6800.h" +#include "esp_config.h" #include +#if AWG == FY6800 +#warning Compiling for FY6800 + +#include "esp_fy6800.h" + volatile SDeviceState gDeviceState; void fy6800_write(char* data, uint8_t len) { uint32_t timeout = 0; Serial.write((uint8_t*)data, len); - while(0 == Serial.available()) + while(!Serial.available()) { delay(1); if(timeout++>1000) return; @@ -36,12 +41,12 @@ void setCh1Output(uint32_t output) if(output) { gDeviceState.ch1Output = 1; - fy6800_write("WMN1\n", 5); + fy6800_write((char*)"WMN1\n", 5); } else { gDeviceState.ch1Output = 0; - fy6800_write("WMN0\n", 5); + fy6800_write((char*)"WMN0\n", 5); } } @@ -50,12 +55,12 @@ void setCh2Output(uint32_t output) if(output) { gDeviceState.ch2Output = 1; - fy6800_write("WFN1\n", 5); + fy6800_write((char*)"WFN1\n", 5); } else { gDeviceState.ch2Output = 0; - fy6800_write("WFN0\n", 5); + fy6800_write((char*)"WFN0\n", 5); } } @@ -97,7 +102,7 @@ void setCh2Ampl(uint32_t ampl) /* Phase is in 0.1deg: 12.5deg = 125 */ void setCh1Phase(uint32_t phase) { - char command[] = "WMA00.000\n"; + char command[] = "WMP00.000\n"; snprintf(command, 11, "WMP%02u.%01u\n", phase/1000, (phase%1000)/100); gDeviceState.ch1Phase = phase; fy6800_write(command, 10); @@ -105,7 +110,7 @@ void setCh1Phase(uint32_t phase) void setCh2Phase(uint32_t phase) { - char command[] = "WFA00.000\n"; + char command[] = "WFP00.000\n"; snprintf(command, 11, "WFP%02u.%01u\n", phase/1000, (phase%1000)/100); gDeviceState.ch2Phase = phase; fy6800_write(command, 10); @@ -160,3 +165,5 @@ void initDevice(void) setCh2Offset(0); } + +#endif diff --git a/esp_fy6800.h b/esp_fy6800.h index 775b32a..b663b09 100644 --- a/esp_fy6800.h +++ b/esp_fy6800.h @@ -1,3 +1,5 @@ +#if AWG == FY6800 + #ifndef _ESP_FY6800_H_ #define _ESP_FY6800_H_ @@ -88,4 +90,6 @@ void setCh2Offset(int32_t offset); /* Can be used to set some default parameters */ void initDevice(void); -#endif _ESP_FY6800_H_ +#endif //_ESP_FY6800_H_ + +#endif diff --git a/esp_fy6900.cpp b/esp_fy6900.cpp new file mode 100644 index 0000000..9330c6f --- /dev/null +++ b/esp_fy6900.cpp @@ -0,0 +1,161 @@ +#include "esp_config.h" +#include + +#if AWG == FY6900 +#warning Compiling for FY6900 + +#include "esp_fy6900.h" + +volatile SDeviceState gDeviceState; + +bool fy6900_write(char* data, uint8_t len) +{ + uint32_t timeout = 0; + Serial.write((uint8_t*)data, len); + telnet.println("["); + telnet.print(data); + telnet.println("]"); + while(!Serial.available()) + { + delay(1); + if(timeout++>1000) return false; + } + bool ok = false; + ok = (Serial.read() == 0x0a); // 0x0a == \n + + if(!ok){ + telnet.println("Invalid response for command"); + } + return ok; +} + +void setCh1Wave(EWaveType wave) +{ + char command[] = "WMW00\n"; + snprintf(command, 7, "WMW%02u\n", wave); + gDeviceState.ch1Wave = wave; + fy6900_write(command, 6); +} + +void setCh2Wave(EWaveType wave) +{ + char command[] = "WFW00\n"; + snprintf(command, 7, "WFW%02u\n", wave); + gDeviceState.ch2Wave = wave; + fy6900_write(command, 6); +} + +void setCh1Output(uint32_t output) +{ + gDeviceState.ch1Output = output; + fy6900_write((char*)(output ? "WMN1\n" : "WMN0\n"), 5); +} + +void setCh2Output(uint32_t output) +{ + gDeviceState.ch2Output = output; + fy6900_write((char*)(output ? "WFN1\n" : "WFN0\n"), 5); +} + +/* Set frequency in Hz */ +void setCh1Freq(uint32_t frequency) +{ + char command[] = "WMF00000000000000\n"; + snprintf(command, 19, "WMF%08lu000000\n", frequency); + gDeviceState.ch1Freq = frequency; + fy6900_write(command, 18); +} + +/* Set frequency in Hz */ +void setCh2Freq(uint32_t frequency) +{ + char command[] = "WFF00000000000000\n"; + snprintf(command, 19, "WFF%08lu000000\n", frequency); + gDeviceState.ch2Freq = frequency; + fy6900_write(command, 18); +} + +/* Ampl is in mV: 12.345V = 12345 */ +void setCh1Ampl(uint32_t ampl) +{ + char command[] = "WMA00.000\n"; + snprintf(command, 11, "WMA%02u.%03u\n", ampl/1000, ampl%1000); + gDeviceState.ch1Ampl = ampl; + fy6900_write(command, 10); +} + +void setCh2Ampl(uint32_t ampl) +{ + char command[] = "WFA00.000\n"; + snprintf(command, 11, "WFA%02u.%03u\n", ampl/1000, ampl%1000); + gDeviceState.ch2Ampl = ampl; + fy6900_write(command, 10); +} + +/* Phase is in 0.1deg: 12.5deg = 125 */ +void setCh1Phase(uint32_t phase) +{ + char command[] = "WMP000.000\n"; + snprintf(command, 12, "WMP%03u.%03u\n", phase/1000, (phase%1000)/100); + gDeviceState.ch1Phase = phase; + fy6900_write(command, 11); +} + +void setCh2Phase(uint32_t phase) +{ + char command[] = "WFP000.000\n"; + snprintf(command, 12, "WFP%03u.%03u\n", phase/1000, (phase%1000)/100); + gDeviceState.ch2Phase = phase; + fy6900_write(command, 11); +} + +void setCh1Offset(int32_t offset) +{ + char command[] = "WMO00.00\n"; + gDeviceState.ch1Offset = offset; + if(offset>=0) + { + snprintf(command, 10, "WMO%02u.%02u\n", offset/1000, offset%1000); + fy6900_write(command, 9); + } + else + { + snprintf(command, 11, "WMO-%02u.%02u\n", -offset/1000, -offset%1000); + fy6900_write(command, 10); + } +} + +void setCh2Offset(int32_t offset) +{ + char command[] = "WFO00.00\n"; + gDeviceState.ch2Offset = offset; + if(offset>=0) + { + snprintf(command, 10, "WFO%02u.%02u\n", offset/1000, offset%1000); + fy6900_write(command, 9); + } + else + { + snprintf(command, 11, "WFO-%02u.%02u\n", -offset/1000, -offset%1000); + fy6900_write(command, 10); + } +} + +void initDevice(void) +{ + Serial.write((uint8_t*)"\n", 1); + + setCh1Output(0); + setCh1Wave(EWaveType_Sine); + setCh1Freq(1000); + setCh1Ampl(1000); + setCh1Offset(0); + + setCh2Output(0); + setCh2Wave(EWaveType_Sine); + setCh2Freq(1000); + setCh2Ampl(1000); + setCh2Offset(0); +} + +#endif diff --git a/esp_fy6900.h b/esp_fy6900.h new file mode 100644 index 0000000..264b3bf --- /dev/null +++ b/esp_fy6900.h @@ -0,0 +1,97 @@ +#if AWG == FY6900 + +#ifndef _ESP_FY6900_H_ +#define _ESP_FY6900_H_ + +#include + +typedef enum +{ + EWaveType_Sine = 0, + EWaveType_Square = 1, + EWaveType_Rectangle = 2, + EWaveType_Trapezoid = 3, + EWaveType_CMOS = 4, + EWaveType_AdjPulse = 5, + EWaveType_DC = 6, + EWaveType_Triangle = 7, + EWaveType_PosRamp = 8, + EWaveType_NegRamp = 9, + EWaveType_StairTrng = 10, + EWaveType_PosStair = 11, + EWaveType_NegStair = 12, + EWaveType_PosExp = 13, + EWaveType_NegExp = 14, + EWaveType_PosFallExp = 15, + EWaveType_NegFallExp = 16, + EWaveType_PosLog = 17, + EWaveType_NegLog = 18, + EWaveType_PosFallLog = 19, + EWaveType_NegFallLog = 20, + EWaveType_PosFullSin = 21, + EWaveType_NegFullSin = 22, + EWaveType_PosHalfSin = 23, + EWaveType_NegHalfSin = 24, + EWaveType_Lorentz = 25, + EWaveType_Multitone = 26, + EWaveType_Noise = 27, + EWaveType_ECG = 28, + //EWaveType_Trapezoid = 29, + EWaveType_SincPulse = 30, + EWaveType_Impulse = 31, + EWaveType_AWGN = 32, + EWaveType_AM = 33, + EWaveType_FM = 34, + EWaveType_Chirp = 35, + //EWaveType_Impulse = 36 + EWaveType_Last +}EWaveType; + +typedef struct +{ + uint8_t ch1Output; + uint8_t ch2Output; + EWaveType ch1Wave; + EWaveType ch2Wave; + uint32_t ch1Freq; + uint32_t ch2Freq; + uint32_t ch1Ampl; + uint32_t ch2Ampl; + uint32_t ch1Phase; + uint32_t ch2Phase; + uint32_t ch1Offset; + uint32_t ch2Offset; + +}SDeviceState; + +extern volatile SDeviceState gDeviceState; + +void setCh1Wave(EWaveType wave); +void setCh2Wave(EWaveType wave); + +/* 0 - off; 1 - on */ +void setCh1Output(uint32_t output); +void setCh2Output(uint32_t output); + +/* Set frequency in Hz */ +void setCh1Freq(uint32_t frequency); +void setCh2Freq(uint32_t frequency); + +/* Ampl is in mV: 12.345V = 12345 */ +void setCh1Ampl(uint32_t ampl); +void setCh2Ampl(uint32_t ampl); + +/* Phase is in 0.1deg: 12.5deg = 125 */ +void setCh1Phase(uint32_t phase); +void setCh2Phase(uint32_t phase); + +/* Offset is in mV: 12.345V = 12345 */ +void setCh1Offset(int32_t offset); +void setCh2Offset(int32_t offset); + +/* Can be used to set some default parameters */ +void initDevice(void); + +#endif //_ESP_FY6900_H_ + +#endif diff --git a/esp_parser.cpp b/esp_parser.cpp index 9a160d0..43efa59 100644 --- a/esp_parser.cpp +++ b/esp_parser.cpp @@ -1,5 +1,10 @@ #include "esp_parser.h" -#include "esp_fy6800.h" + +#if AWG == FY6800 + #include "esp_fy6800.h" +#elif AWG == FY6900 + #include "esp_fy6900.h" +#endif volatile char *gReadBuffer = NULL; diff --git a/esp_parser.h b/esp_parser.h index 9857c4a..d8fe86b 100644 --- a/esp_parser.h +++ b/esp_parser.h @@ -2,7 +2,6 @@ #define _ESP_PARSER_H_ #include -#include "esp_fy6800.h" #include "esp_config.h" extern volatile char *gReadBuffer;