clemCH | Bonjour tout le monde, Il y a quelque semaines, j'ai découvert une nouvelle plateforme de développement open-source qui me permettara de remplacer les instruments couteux et volumineux de mon laboratoire, la redptitaya. Je me suis procuré le modèle STEMlab 125-14 qui propose deux entrées de 125Msps 14 bits et de deux sorties 14 bits, un FPGA Xilinx Zynq 7010 couplé à un processeur ARM Cortex-A9 double-coralité et offre un accès à distance, avec une interface utilisateur d'application en ligne accessible via Ethernet ou Wi-Fi. Pour faire fonctionner tout ce petit monde la plateforme à créer un système d'exploitation basé sur un système linux ubuntu (actuellement j’utilise la dernière version du système RedPitaya_OS_2.00-30_stable.img).
![https://redpitaya.com/wp-content/uploads/elementor/thumbs/Red_Pitaya_STEMlab_125-14-p91a8dpiccj0fiqw3w96w8ax4av9fms8og1vxtmhls.jpg https://redpitaya.com/wp-content/uploads/elementor/thumbs/Red_Pitaya_STEMlab_125-14-p91a8dpiccj0fiqw3w96w8ax4av9fms8og1vxtmhls.jpg](https://redpitaya.com/wp-content/uploads/elementor/thumbs/Red_Pitaya_STEMlab_125-14-p91a8dpiccj0fiqw3w96w8ax4av9fms8og1vxtmhls.jpg) Puisque cette carte ne peut pas gérer d'écran, il est essentiel de concevoir une interface utilisateur web fonctionnant sur un navigateur internet pour contrôler l'application back-end, compilé et installé sur le système d'exploitation. Tout ce qui fonctionne dans le navigateur est le frontend. C'est la partie qui permet de visualiser les données à l'écran ou modifier certains paramètres pour ajuster les paramètres à l'intérieur de l'application back-end. La partie front-end de l'application utilise la technologie HTML5, CSS3 et Javascript pour créer l'interface web. La partie back-end est programmé en C ou en C++ et peut nécessité du Vérilog pour manipuler le FPGA. L'échange d'information entre le C++ et le Javascript s’effectue par des fichiers JSON, pour transmettre les valeurs des paramètres ou des signaux échantillonnés et générés. Pour que cela fonctionne un serveur NGINX fonctionne en continue. (Si vous voulez plus d'information surfez sur la documentation de la plateforme au lien suivant: https://redpitaya.readthedocs.io.) Pour me familiariser avec le système, j’essaie de développer une application me permettant de faire un générateur de signaux sur deux sorties DAC 14 bits et oscilloscope sur les deux entrées ADC 14 bits. Mon application devra être capable de configurer la forme, l'amplitude, la fréquence des signaux à générer et d'afficher dans un plot jQuery la forme des signaux échantillonnées et générée. Pour l'instant je me contente de faire rentrer les signaux générés sur les entrées de la carte en connectant une sortie à une entrée par un câble coaxiale. A ce stade du développement, j'ai commencé à réaliser une petite interface web m'affichant un menu dans un bandeau vertical pour choisir et configurer les channels et un plot jQuery pour afficher les signaux. De plus j'ai aussi programmer la partie back-end en C++ pour créer les paramètres nécessaire et des fonctions pour manipuler les convertisseurs 14 bits. Pour plus de simplicité la plateforme possède quelque libraire simplifiant la transmissions et la réception des sockets pour échanger les paramètres et d'autre librairie permettant de configurer et échantillonner les signaux DAC et ADC. Le cœur de mon problème est que l'interface front-end refuse catégoriquement de se connecter à l'interface back-end, ce dont je ne comprend pas, puisque ce processus doit se faire automatiquement par la librairie C++ de la carte. Le code Javascipt doit juste vérifié si le socket a était accpété en le demandant au serveur NGNIX. Cependant le serveur me renvoie continuellement l'erreur suivante: "Can not load application. Error: -1 app.js:120:14" J’espère que quelqu’un connait le système pour me partager ses connaissances sur ce système et que peut-être cela répondra à mon problème. Si vous voulez lire mon code pour trouver peut-être une incohérence, ou tester mon code sur votre redpitaya, le voici ci-dessous: La partie back-end: fichier src/hardwareInfo.h
Code :
- #pragma one
- #include <cstdio>
- #include <cstdlib>
- #include <cstdint>
- #include "rp.h"
- typedef enum {
- RP_125_14,
- RP_250_12,
- RP_125_14_4CH,
- RP_122_16
- } models_t;
- uint8_t getADCChannels();
- uint8_t getDACChannels();
- float getDACGainCh1();
- uint32_t getADCRate();
- // return current CPU clock
- double getClock();
- models_t getModel();
| fichier hardwareInfo.cpp
Code :
- #include <ctime>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/sysinfo.h>
- #include <string>
- #include "hardwareInfo.h"
- #include "rp.h"
- #include "rp_hw-calib.h"
- #include "log.h"
- uint8_t getADCChannels() {
- uint8_t c = 0;
- if (rp_HPGetFastADCChannelsCount(&c) != RP_HP_OK){
- Error("Can't get fast ADC channels count\n" );
- exit(-1);
- }
- return c;
- }
- uint8_t getDACChannels() {
- uint8_t c = 0;
- if (rp_HPGetFastDACChannelsCount(&c) != RP_HP_OK){
- Error("Can't get fast DAC channels count\n" );
- exit(-1);
- }
- return c;
- }
- float getDACGainCh1() {
- float c = 0;
- if (rp_HPGetFastDACGain(RP_CH_1, &c) != RP_HP_OK){
- Error("Can't get fast DAC gain\n" );
- exit(-1);
- }
- return c;
- }
- uint32_t getADCRate() {
- uint32_t c = 0;
- if (rp_HPGetBaseFastADCSpeedHz(&c) != RP_HP_OK){
- Error("Can't get fast ADC rate\n" );
- exit(-1);
- }
- return c;
- }
- double getClock() {
- struct timespec tp;
- clock_gettime(CLOCK_REALTIME, &tp);
- return ((double)tp.tv_sec * 1000.f) + ((double)tp.tv_nsec / 1000000.f);
- }
- models_t getModel() {
- rp_HPeModels_t c = STEM_125_14_v1_0;
- if (rp_HPGetModel(&c) != RP_HP_OK){
- Error("Can't get board model\n" );
- exit(-1);
- }
- switch (c)
- {
- case STEM_125_10_v1_0:
- case STEM_125_14_v1_0:
- case STEM_125_14_v1_1:
- case STEM_125_14_LN_v1_1:
- case STEM_125_14_Z7020_v1_0:
- case STEM_125_14_Z7020_LN_v1_1:
- return RP_125_14;
- case STEM_122_16SDR_v1_0:
- case STEM_122_16SDR_v1_1:
- return RP_122_16;
- case STEM_125_14_Z7020_4IN_v1_0:
- case STEM_125_14_Z7020_4IN_v1_2:
- case STEM_125_14_Z7020_4IN_v1_3:
- return RP_125_14_4CH;
- case STEM_250_12_v1_0:
- case STEM_250_12_v1_1:
- case STEM_250_12_v1_2:
- case STEM_250_12_v1_2a:
- case STEM_250_12_v1_2b:
- return RP_250_12;
- default:
- Error("Can't get board model\n" );
- exit(-1);
- }
- return RP_125_14;
- }
| fichier src/log.h
Code :
- #pragma once
- #include <string>
- #include <fstream>
- #include <iostream>
- #include <memory>
- #include <stdexcept>
- const std::string log_filename = "/tmp/exemple.txt";
- template<typename ... Args>
- inline std::string string_format( const std::string& format, Args ... args )
- {
- int size_s = std::snprintf( nullptr, 0, format.c_str(), args ... ) + 1; // Extra space for '\0'
- if( size_s <= 0 ){ throw std::runtime_error( "Error during formatting." ); }
- auto size = static_cast<size_t>( size_s );
- std::unique_ptr<char[]> buf( new char[ size ] );
- std::snprintf( buf.get(), size, format.c_str(), args ... );
- return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside
- }
- template<typename ... Args>
- void Log(const std::string& format, Args ... args) {
- std::ofstream file(log_filename.c_str(), std::ios::in | std::ios::out | std::ios::app);
- if (file.is_open()) {
- file << string_format(format, args ...);
- file.close();
- }
- }
- template<typename ... Args>
- void Error(const std::string& format, Args ... args) {
- std::ofstream file(log_filename.c_str(), std::ios::in | std::ios::out | std::ios::app);
- if (file.is_open()) {
- file << "[Error] " << string_format(format, args ...);
- file.close();
- }
- }
| Fichier src/main.h
Code :
- #pragma once
- #include <DataManager.h>
- #include <CustomParameters.h>
- #include "rpApp.h"
- #define SIGNAL_SIZE_DEFAULT 1024 //Signal size
- #define SIGNAL_UPDATE_INTERVAL 1
- #define PARAMS_UPDATE_INTERVAL 1
- #define RW CBaseParameter::RW
- #define RWSA CBaseParameter::RWSA
- #define RO CBaseParameter::RO
- #define FPGA_UPDATE_NONE 0
- #define FPGA_UPDATE 1
- #define SFLOAT(VAR, size, value) CFloatSignal VAR(#VAR, size, value);
- #define SFLOAT2(VAR, size, value) CFloatSignal VAR[2] = {{#VAR "1", size, value}, {#VAR "2", size, value}}
- #define SFLOAT4(VAR, size, value) CFloatSignal VAR[4] = {{#VAR "1", size, value}, {#VAR "2", size, value}, {#VAR "3", size, value}, {#VAR "4", size, value}}
- #define PBOOL(VAR, ...) CBooleanParameter VAR(#VAR, __VA_ARGS__)
- #define PBOOL2(VAR, ...) CBooleanParameter VAR[2] = {{#VAR "1", __VA_ARGS__},{#VAR "2", __VA_ARGS__}}
- #define PBOOL4(VAR, ...) CBooleanParameter VAR[4] = {{#VAR "1", __VA_ARGS__},{#VAR "2", __VA_ARGS__}, {#VAR "3", __VA_ARGS__}, {#VAR "4", __VA_ARGS__}}
- #define PINT(VAR, ...) CIntParameter VAR(#VAR, __VA_ARGS__)
- #define PINT2(VAR, ...) CIntParameter VAR[2] = {{#VAR "1", __VA_ARGS__},{#VAR "2", __VA_ARGS__}}
- #define PINT4(VAR, ...) CIntParameter VAR[2] = {{#VAR "1", __VA_ARGS__},{#VAR "2", __VA_ARGS__}, {#VAR "3", __VA_ARGS__},{#VAR "4", __VA_ARGS__}}
- #define PUINT(VAR, ...) CUIntParameter VAR(#VAR, __VA_ARGS__)
- #define PUINT2(VAR, ...) CUIntParameter VAR[2] = {{#VAR "1", __VA_ARGS__},{#VAR "2", __VA_ARGS__}}
- #define PUINT4(VAR, ...) CUIntParameter VAR[4] = {{#VAR "1", __VA_ARGS__},{#VAR "2", __VA_ARGS__},{#VAR "3", __VA_ARGS__},{#VAR "4", __VA_ARGS__}}
- #define PFLOAT(VAR, ...) CFloatParameter VAR(#VAR, __VA_ARGS__)
- #define PFLOAT2(VAR, ...) CFloatParameter VAR[2] = {{#VAR "1", __VA_ARGS__},{#VAR "2", __VA_ARGS__}}
- #define PFLOAT4(VAR, ...) CFloatParameter VAR[2] = {{#VAR "1", __VA_ARGS__},{#VAR "2", __VA_ARGS__}, {#VAR "3", __VA_ARGS__},{#VAR "4", __VA_ARGS__}}
- #define PDOUBLE(VAR, ...) CDoubleParameter VAR(#VAR, __VA_ARGS__)
- #define PDOUBLE2(VAR, ...) CDoubleParameter VAR[2] = {{#VAR "1", __VA_ARGS__},{#VAR "2", __VA_ARGS__}}
- #define PDOUBLE4(VAR, ...) CDoubleParameter VAR[2] = {{#VAR "1", __VA_ARGS__},{#VAR "2", __VA_ARGS__}, {#VAR "3", __VA_ARGS__},{#VAR "4", __VA_ARGS__}}
- #define PSTRING(VAR, ...) CStringParameter VAR(#VAR, __VA_ARGS__)
- #define PSTRING2(VAR, ...) CStringParameter VAR[2] = {{#VAR "1", __VA_ARGS__},{#VAR "2", __VA_ARGS__}}
- #define PSTRING4(VAR, ...) CStringParameter VAR[2] = {{#VAR "1", __VA_ARGS__},{#VAR "2", __VA_ARGS__},{#VAR "3", __VA_ARGS__},{#VAR "4", __VA_ARGS__}}
- #ifdef __cplusplus
- extern "C" {
- #endif
- /* Parameters description structure - must be the same for all RP controllers */
- typedef struct rp_app_params_s {
- char *name;
- float value;
- int fpga_update;
- int read_only;
- float min_val;
- float max_val;
- } rp_app_params_t;
- //Rp app functions
- const char *rp_app_desc(void);
- int rp_app_init(void);
- int rp_app_exit(void);
- int rp_set_params(rp_app_params_t *p, int len);
- int rp_get_params(rp_app_params_t **p);
- int rp_get_signals(float ***s, int *sig_num, int *sig_len);
- #ifdef __cplusplus
- }
- #endif
| Fichier src/main.cpp
Code :
- #include <fstream>
- #include <math.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <time.h>
- #include <unistd.h>
- #include "rp.h"
- #include "rpApp.h"
- #include "log.h"
- #include "hardwareInfo.h"
- #include "main.h"
- /********************************************************/
- /* Global variables */
- /********************************************************/
- bool g_appState = false;
- rp_acq_decimation_t g_decimation = RP_DEC_8192;
- int g_timeDelay = 1000000; // delay us to start acquiring fresh data
- uint32_t g_buffer_size = ADC_BUFFER_SIZE;
- float *g_buffer = (float *)malloc(g_buffer_size * sizeof(float));
- PBOOL(APP_RUN, RW, true, FPGA_UPDATE_NONE);
- /********************************************************/
- /* Signals variables */
- /********************************************************/
- SFLOAT2(OSC_SIGNAL_CH, SIGNAL_SIZE_DEFAULT, 0.0f);
- SFLOAT2(GEN_SIGNAL_CH, SIGNAL_SIZE_DEFAULT, 0.0f);
- SFLOAT2(MATH_SIGNAL_CH, SIGNAL_SIZE_DEFAULT, 0.0f);
- /********************************************************/
- /* Oscilloscope parameters from here on */
- /********************************************************/
- PFLOAT(TIME_SCALE, RWSA, 0.1, 0, 0, 1000);
- PFLOAT(VOLT_SCALE, RWSA, 0.1, 0, 0, 10);
- PBOOL2(OSC_SHOW_CH, RW, false, FPGA_UPDATE);
- PBOOL2(OSC_INVERT_CH, RW, false, FPGA_UPDATE);
- //User probe attenuation setting for channel 1 & 2:
- // 0 - 1x
- // 1 - 10x
- // 2 - 100x
- PINT2(OSC_PROB_CH, RW, 0, FPGA_UPDATE, 0, 2);
- // User jumper gain setting for channel 1 & 2:
- // 0 - high gain (-1/1 [V] Full-scale)
- // 1 - low gain (-20/20 [V] Full-scale)
- PINT2(OSC_GAIN_CH, RW, 0, FPGA_UPDATE, 0, 1);
- // Trigger mode:
- // 0 - Auto
- // 1 - Normal
- // 2 - Single
- PINT(OSC_TRIGGER_MODE, RW, 0, FPGA_UPDATE, 0, 2);
- // Trigger source:
- // 0 - ChA
- // 1 - ChB
- // 2 - ext
- PINT(OSC_TRIGGER_SOURCE, RW, 0, FPGA_UPDATE, 0, 2);
- // Trigger Edge:
- // 0 - Rising
- // 1 - Falling
- PINT(OSC_TRIGGER_EDGE, RW, 0, FPGA_UPDATE, 0, 1);
- PFLOAT(OSC_TRIGGER_DELAY, RW, 0, FPGA_UPDATE, -1e7, 1e7);
- PFLOAT(OSC_TRIGGER_LEVEL, RW, 0, FPGA_UPDATE, -2, 2);
- PFLOAT2(OSC_MEAS_MIN_CH, RO, 0, FPGA_UPDATE, -1000, 1000);
- PFLOAT2(OSC_MEAS_MAX_CH, RO, 0, FPGA_UPDATE, -1000, 1000);
- PFLOAT2(OSC_MEAS_AMP_CH, RO, 0, FPGA_UPDATE, -1000, 1000);
- PFLOAT2(OSC_MEAS_AVG_CH, RO, 0, FPGA_UPDATE, -1000, 1000); // Average
- PFLOAT2(OSC_MEAS_FREQ_CH, RO, 0, FPGA_UPDATE, -1000, 1000); // Frequency
- PFLOAT2(OSC_MEAS_PER_CH, RO, 0, FPGA_UPDATE, -1000, 1000); // Periode
- /********************************************************/
- /* Generator parameters from here on */
- /********************************************************/
- PBOOL2(GEN_SHOW_CH, RW, false, FPGA_UPDATE_NONE);
- PBOOL2(GEN_ENABLE_CH, RW, false, FPGA_UPDATE);
- PFLOAT2(GEN_AMPLITUDE_CH, RW, 0.8, FPGA_UPDATE, -2.0, 2.0);
- PFLOAT2(GEN_FREQUENCY_CH, RW, 1000, FPGA_UPDATE, 1, 50e6);
- PFLOAT2(GEN_OFFSET_CH, RW, 0, FPGA_UPDATE, -1.0, 1.0);
- PINT2(GEN_WAVEFORM_CH, RW, 0, FPGA_UPDATE, 0, 8);
- PINT2(GEN_MODE_CH, RW, 0, FPGA_UPDATE, 0, 2);
- PFLOAT2(GEN_DUTY_CYCLE_CH, RW, 25.0, FPGA_UPDATE, 0.0, 100.0);
- PFLOAT2(GEN_BURST_COUNT_CH, RW, 1, FPGA_UPDATE, 0, 1000);
- PFLOAT2(GEN_BURST_PER_CH, RW, 1, FPGA_UPDATE, 0, 50e6);
- PFLOAT2(GEN_BURST_REP_CH, RW, 1, FPGA_UPDATE, 0, 1000);
- /********************************************************/
- /* Math parameters from here on */
- /********************************************************/
- PBOOL2(MATH_SHOW_CH, RW, false, FPGA_UPDATE_NONE);
- // Operator
- // 0 - Addition
- // 1 - Soustration
- // 2 - produit
- // 3 - absolute
- // 4 - invert
- PINT2(MATH_OPERATOR_CH, RW, 0, FPGA_UPDATE, 0, 5);
- PINT2(MATH_FIRST_SIGN_CH, RW, 0, FPGA_UPDATE, 0, 3);
- PINT2(MATH_SECOND_SIGN_CH, RW, 0, FPGA_UPDATE, 0, 3);
- PFLOAT2(MATH_CONST_CH, RW, 1.0, FPGA_UPDATE, -10.0, 10.0);
- // Save signals
- // 0 - json format
- // 1 - csv format
- // 2 - wav format
- // 3 - dat format
- PINT2(SAVE_FORMAT, RW, 0, FPGA_UPDATE_NONE, 0, 3);
- // ------------------------------------------------------------
- // Generator functions
- // ------------------------------------------------------------
- int startGenerator(rp_channel_t _channel, rp_waveform_t _wave, float _frequency, float _amplitude, float _offset, float _duty) {
- int ret = RP_OK;
- ret |= rp_GenReset();
- ret |= rp_GenOffset(_channel,_offset);
- ret |= rp_GenAmp(_channel,_amplitude);
- ret |= rp_GenWaveform(_channel,_wave);
- ret |= rp_GenFreq(_channel,_frequency);
- if (_wave == RP_WAVEFORM_PWM)
- rp_GenDutyCycle(_channel, _duty);
- ret |= rp_GenOutEnable(_channel);
- ret |= rp_GenTriggerOnly(_channel);
- return ret;
- }
- bool UpdateGenChParams(uint8_t ch) {
- if (GEN_SHOW_CH[ch].IsNewValue()) {
- GEN_SHOW_CH[ch].Update();
- }
- bool conf_osc = false;
- if (GEN_ENABLE_CH[ch].IsNewValue()) {
- GEN_ENABLE_CH[ch].Update();
- conf_osc = true;
- }
- if (GEN_WAVEFORM_CH[ch].IsNewValue()) {
- GEN_WAVEFORM_CH[ch].Update();
- conf_osc = true;
- }
- if (GEN_FREQUENCY_CH[ch].IsNewValue()) {
- GEN_FREQUENCY_CH[ch].Update();
- conf_osc = true;
- }
- if (GEN_AMPLITUDE_CH[ch].IsNewValue()) {
- GEN_AMPLITUDE_CH[ch].Update();
- conf_osc = true;
- }
- if (GEN_OFFSET_CH[ch].IsNewValue()) {
- GEN_OFFSET_CH[ch].Update();
- conf_osc = true;
- }
- if (GEN_DUTY_CYCLE_CH[ch].IsNewValue()) {
- GEN_DUTY_CYCLE_CH[ch].Update();
- conf_osc = true;
- }
- if (GEN_MODE_CH[ch].IsNewValue()) {
- GEN_MODE_CH[ch].Update();
- conf_osc = true;
- }
- if (g_appState == true) {
- return conf_osc;
- } else {
- return false;
- }
- }
- // Generator configurations
- void configureGenerator() {
- for (uint8_t i = 0; 2; i++) {
- if (UpdateGenChParams(i) && GEN_ENABLE_CH.Value()) {
- bool enable;
- rp_GenOutIsEnabled((rp_channel_t) i, &enable);
- if (!enable) rp_GenOutEnable((rp_channel_t) i);
- if (startGenerator(
- (rp_channel_t) i,
- (rp_waveform_t) GEN_WAVEFORM_CH[i].Value(),
- (float) GEN_FREQUENCY_CH[i].Value(),
- (float) GEN_AMPLITUDE_CH[i].Value(),
- (float) GEN_OFFSET_CH[i].Value(),
- (float) GEN_DUTY_CYCLE_CH[i].Value()) != RP_OK)
- {
- Error("Start generator failed\n" );
- }
- } else {
- bool enable;
- rp_GenOutIsEnabled((rp_channel_t) i, &enable);
- if (enable) rp_GenOutDisable((rp_channel_t) i);
- }
- }
- Log("Generator parameters updated\n" );
- }
- // ------------------------------------------------------------
- // Scope functions
- // ------------------------------------------------------------
- int analyseData(int mul, uint8_t ch) {
- return RP_OK;
- }
- // update signal on channel 1 & 2
- int OscAcquisitionSignal(void)
- {
- int ret = RP_OK;
- auto model = getModel();
- if (model == RP_122_16){
- Error("Not available on 122-16\n" );
- return 0;
- }
- for (uint8_t i=0; i<2; i++) {
- int mul = OSC_PROB_CH[i].Value();
- if (OSC_SHOW_CH[i].Value()) {
- ret |= rp_AcqGetOldestDataV((rp_channel_t) i, &g_buffer_size, g_buffer);
- ret |= analyseData(mul, i);
- for (uint32_t j = 0; j < SIGNAL_SIZE_DEFAULT; j++) {
- if (OSC_SHOW_CH[i].Value()) {
- if (OSC_SIGNAL_CH[i].GetSize() != g_buffer_size)
- OSC_SIGNAL_CH[i].Resize(g_buffer_size);
- OSC_SIGNAL_CH[i][j] = g_buffer[j] * mul; // - (VOLT_SCALE.Value() + OSC_MEAS_AVG_CH[0].Value());
- }
- }
- }
- }
- return ret;
- }
- // ------------------------------------------------------------
- //
- // ------------------------------------------------------------
- // get decimation
- void get_decimation() {
- float cal_dec = (getADCRate() / ADC_BUFFER_SIZE) * TIME_SCALE.Value() / 100; // 100 = 10(whole range)/1000(to second)
-
- /* Find optimal decimation setting */
- if(cal_dec < 1) {
- g_decimation = RP_DEC_1;
- g_timeDelay = 131;
- } else if(cal_dec < 8) {
- g_decimation = RP_DEC_8;
- g_timeDelay = 1048;
- } else if(cal_dec < 64) {
- g_decimation = RP_DEC_64;
- g_timeDelay = 8388;
- } else if(cal_dec < 1024) {
- g_decimation = RP_DEC_1024;
- g_timeDelay = 134200;
- } else if(cal_dec < 8192) {
- g_decimation = RP_DEC_8192;
- g_timeDelay = 1000000;
- } else if(cal_dec < 65536) {
- g_decimation = RP_DEC_65536;
- g_timeDelay = 8589000;
- } else {
- g_decimation = RP_DEC_8192;
- g_timeDelay = 1000000;
- }
- }
- // set acquire
- void set_acquire() {
- rp_AcqReset();
- rp_AcqSetDecimation(g_decimation);
- // rp_AcqSetAveraging(true);
- // rp_AcqSetTriggerLevel(RP_T_CH_1, 0);
- // rp_AcqSetTriggerDelay(ADC_BUFFER_SIZE/2.0);
- for (uint8_t i = 0; i < 2; i++) {
- if(OSC_GAIN_CH[i].Value()) {
- rp_AcqSetGain((rp_channel_t) i, RP_HIGH);
- } else {
- rp_AcqSetGain((rp_channel_t) i, RP_LOW);
- }
- }
- rp_AcqStart();
- /* After acquisition is started some time delay is needed in order to acquire fresh samples in to buffer*/
- /* Here we have used time delay of one second but you can calculate exact value taking in to account buffer*/
- /*length and smaling rate. Time scale/length of a buffer for decimation 8 takes 1.049 ms to full 16 KS in buffer*/
- usleep(g_timeDelay);
- // rp_AcqSetTriggerSrc(RP_TRIG_SRC_CHA_PE);
- }
- // Run or stop APP
- void run_app() {
- // Init generator
- rp_GenReset();
- configureGenerator();
- // Init acquire signal
- get_decimation();
- set_acquire();
- g_appState = true;
- }
- void stop_app() {
- g_appState = false;
- // stop acqusition
- rp_AcqStop();
- // Disabe generator
- for (uint8_t i = 0; i < 2; i++)
- rp_GenOutDisable((rp_channel_t) i);
- }
- // ------------------------------------------------------------
- // RP Application functions
- // ------------------------------------------------------------
- //Application description
- const char *rp_app_desc(void)
- {
- return (const char *)"Red Pitaya scope and genarator application.\n";
- }
- //Application init
- int rp_app_init(void)
- {
- g_appState = false;
- srand(time(0));
- Log("Loading scope and genarator application\n" );
- // Initialization of API
- if (rpApp_Init() != RP_OK) {
- Error("Red Pitaya API init failed!\n" );
- return EXIT_FAILURE;
- } else {
- Log("Red Pitaya API init success!\n" );
- }
- CDataManager::GetInstance()->SetParamInterval(SIGNAL_UPDATE_INTERVAL);
- CDataManager::GetInstance()->SetSignalInterval(PARAMS_UPDATE_INTERVAL);
- CDataManager::GetInstance()->SendAllParams();
- if (APP_RUN.Value() == true) {
- run_app();
- }
- return 0;
- }
- //Application exit
- int rp_app_exit(void)
- {
- stop_app();
- rpApp_Release();
- free(g_buffer);
- Log("Unload Red Pitaya application\n----------------------------------------\n" );
- return 0;
- }
- //Set parameters
- int rp_set_params(rp_app_params_t *p, int len)
- {
- return 0;
- }
- //Get parameters
- int rp_get_params(rp_app_params_t **p)
- {
- return 0;
- }
- //Get signals
- int rp_get_signals(float ***s, int *sig_num, int *sig_len)
- {
- return 0;
- }
- //Update signals
- void UpdateSignals(void)
- {
- if (g_appState == true) {
- OscAcquisitionSignal();
- }
- }
- //Update parameters
- void UpdateParams(void) {}
- void OnNewParams(void)
- {
- APP_RUN.Update();
- // Run or stop APP
- if (APP_RUN.Value() == true) {
- run_app();
- } else {
- stop_app();
- }
- TIME_SCALE.Update();
- bool gain_is_new = false;
- for (uint8_t i = 0; i < 2; i++) {
- OSC_SHOW_CH[i].Update();
- OSC_INVERT_CH[i].Update();
- OSC_PROB_CH[i].Update();
- gain_is_new |= OSC_GAIN_CH[i].IsNewValue();
- }
- // change decimation if needed
- if(g_appState && (TIME_SCALE.IsNewValue() || gain_is_new)) {
-
- VOLT_SCALE.Update();
- rp_acq_decimation_t curr_dec = g_decimation;
- get_decimation();
- if(curr_dec != g_decimation || gain_is_new) {
- for (uint8_t i = 0; i < 2; i++)
- OSC_GAIN_CH[i].Update();
- g_appState = false;
-
- rp_AcqStop();
- set_acquire();
- // rp_AcqSetDecimation(dec);
- g_appState = true;
- }
- }
- configureGenerator();
- }
- void OnNewSignals(void) {}
- void PostUpdateSignals(void) {}
| le fichier de compilation des sources c/c++ [i]Fichier src/Makefile
Code :
- CXX=$(CROSS_COMPILE)g++
- RM=rm
- INSTALL_DIR ?= /opt/redpitaya
- CXXSOURCES=main.cpp
- INCLUDE = -I$(INSTALL_DIR)/include
- INCLUDE += -I$(INSTALL_DIR)/include/api2
- INCLUDE += -I$(INSTALL_DIR)/include/apiApp
- INCLUDE += -I$(INSTALL_DIR)/rp_sdk
- INCLUDE += -I$(INSTALL_DIR)/rp_sdk/libjson
- LIBS = -L$(INSTALL_DIR)/lib
- LIBS += -L$(INSTALL_DIR)/rp_sdk
- COMMON_FLAGS+=-Wall -fPIC -Os -s -w
- CFLAGS+=$(COMMON_FLAGS) $(INCLUDE)
- CXXFLAGS+=$(COMMON_FLAGS) -std=c++11 $(INCLUDE)
- LDFLAGS = -shared $(COMMON_FLAGS) $(LIBS)
- LDFLAGS+= -Wl,--whole-archive,--no-as-needed
- LDFLAGS+= -lcryptopp -lrpapp -lrp_sdk -lrp
- LDFLAGS+= -Wl,--no-whole-archive
- COBJECTS=$(CSOURCES:.c=.o)
- CXXOBJECTS=$(CXXSOURCES:.cpp=.o)
- OBJECTS=$(COBJECTS) $(CXXOBJECTS)
- OUT_DIR=../
- C_OUT_NAME=$(OUT_DIR)controllerhf.so
- all: make_c_app
- clean: clean_c_app
- make_c_app: $(OBJECTS)
- $(CXX) -o $(C_OUT_NAME) $(OBJECTS) $(CFLAGS) $(LDFLAGS)
- clean_c_app:
- $(RM) -f $(C_OUT_NAME) $(OBJECTS)
| La partie front-end Fichier index.html
Fichier css/style.css
Fichier js/app.js
Code :
- // Frozen enum - Immutable
- const Waveform = Object.freeze({
- SINE :0, //!< Wave form sine
- SQUARE :1, //!< Wave form square
- TRIANGLE :2, //!< Wave form triangle
- RAMP_UP :3, //!< Wave form sawtooth (/|)
- RAMP_DOWN :4, //!< Wave form reversed sawtooth (|\)
- DC :5, //!< Wave form dc
- PWM :6, //!< Wave form pwm
- //ARBITRARY :7, //!< Use defined wave form
- DC_NEG :8, //!< Wave form negative dc
- //SWEEP :9, //!< Wave form sweep
- });
- const GenMode = Object.freeze({
- CONTINUOUS :0, //!< Continuous signal generation
- BURST :1, //!< Signal is generated N times, wher N is defined with rp_GenBurstCount method
- STREAM :2 //!< User can continuously write data to buffer
- });
- const Menu = Object.freeze({
- CLOSE :0,
- INPUT_CHANNEL_1 :1,
- INPUT_CHANNEL_2 :2,
- OUTPUT_CHANNEL_1 :3,
- OUTPUT_CHANNEL_2 :4,
- MATH_CHANNEL_1 :5,
- MATH_CHANNEL_2 :6,
- TRIGGER :7,
- SAVE :8
- });
- (function() {
- if ("performance" in window == false) {
- window.performance = {};
- }
- Date.now = (Date.now || function() { // thanks IE8
- return new Date().getTime();
- });
- if ("now" in window.performance == false) {
- var nowOffset = Date.now();
- if (performance.timing && performance.timing.navigationStart) {
- nowOffset = performance.timing.navigationStart
- }
- window.performance.now = function now() {
- return Date.now() - nowOffset;
- }
- }
- })();
- (function(APP, $, unused) {
- // Params cache
- APP.params = {
- shared: {},
- local: {},
- callback: {}
- };
- var length_display_signal = 1024*16;
- APP.signals = {
- length_display: length_display_signal,
- OSC_SIGNAL_CH1: Array(length_display_signal).fill(0),
- OSC_SIGNAL_CH2: Array(length_display_signal).fill(0),
- GEN_SIGNAL_CH1: Array(length_display_signal).fill(0),
- GEN_SIGNAL_CH2: Array(length_display_signal).fill(0),
- MATH_SIGNAL_CH1: Array(length_display_signal).fill(0),
- MATH_SIGNAL_CH2: Array(length_display_signal).fill(0),
- };
- // App configuration
- APP.config = {};
- APP.config.app_id = 'exemple';
- APP.config.client_id = undefined;
- APP.config.server_ip = ''; // Leave empty on production, it is used for testing only
- APP.config.start_app_url = window.location.origin + '/bazaar?start=' + APP.config.app_id;
- APP.config.stop_app_url = window.location.origin + '/bazaar?stop=' + APP.config.app_id;
- APP.config.socket_url = 'ws://' + window.location.host + '/wss'; // WebSocket server URI
- APP.config.previousPageUrl = '/';
- // Other global variables
- APP.ws = null;
- APP.plot = {};
- APP.parameterStack = [];
- APP.signalStack = [];
- APP.parametersCache = {};
- // App state
- APP.state = {
- socket_opened: false,
- unexpected_closed: false,
- processing: false,
- parametersCache_isEmpty: false,
- currentMenu: Menu.CLOSE,
- currentChannel: 1,
- running: false,
- };
- APP.startApp = function() {
- $.get(
- APP.config.start_app_url
- )
- .done(function(dresult) {
- if (dresult.status == 'OK') {
- try {
- APP.connectWebSocket();
- console.log("Load manager" );
- } catch (e) {
- APP.startApp();
- }
- } else if (dresult.status == 'ERROR') {
- console.log(dresult.reason ? dresult.reason : 'Could not start the application (ERR1)');
- APP.startApp();
- } else {
- console.log('Could not start the application (ERR2)');
- APP.startApp();
- }
- })
- .fail(function() {
- console.log('Could not start the application (ERR3)');
- APP.startApp();
- });
- };
- APP.realoadAPP = function() {
- $.ajax({
- method: "GET",
- url: "/get_client_id",
- timeout: 2000
- }).done(function(msg) {
- if (msg.trim() === APP.config.app_id) {
- location.reload();
- }
- }).fail(function(msg) {
- console.log(msg);
- });
- }
- // Creates a WebSocket connection with the web server
- APP.connectWebSocket = function() {
- if (window.WebSocket) {
- APP.ws = new WebSocket(APP.config.socket_url);
- APP.ws.binaryType = "arraybuffer";
- } else if (window.MozWebSocket) {
- APP.ws = new MozWebSocket(APP.config.socket_url);
- APP.ws.binaryType = "arraybuffer";
- } else {
- console.log('Browser does not support WebSocket');
- }
- // Define WebSocket event listeners
- if (APP.ws) {
- APP.ws.onopen = function() {
- console.log('Socket opened');
- APP.state.socket_opened = true;
- APP.state.unexpected_closed = true;
- APP.sendParameters();
- };
- APP.ws.onclose = function() {
- APP.state.socket_opened = false;
- if (APP.state.unexpected_closed)
- setTimeout(APP.startApp(), 1000);
- console.log('Socket closed');
- };
- APP.ws.onerror = function(ev) {
- if (!APP.state.socket_opened)
- APP.startApp();
- console.log('Websocket error: ', ev);
- };
- APP.ws.onmessage = function(ev) {
- try {
- var data = new Uint8Array(ev.data);
- var inflate = pako.inflate(data);
- var text = String.fromCharCode.apply(null, new Uint8Array(inflate));
- var receive = JSON.parse(text);
- //Recieving parameters
- if (receive.parameters) {
- APP.parameterStack.push(receive.parameters);
- }
- //Recieve signals
- if (receive.signals) {
- //g_PacketsRecv++;
- APP.signalStack.push(receive.signals);
- }
- } catch (e) {
- console.log(e);
- } finally {}
- };
- }
- };
- /* -------------------------------------------------------------------- */
- // Lire la valeur d'un paramètre partagé ou local
- APP.getVal = function(param_name) {
- if (param_name in APP.params.shared) {
- return APP.params.shared[param_name].value;
- } else if (param_name in APP.params.local) {
- return APP.params.local[param_name].value;
- } else
- return 0;
- }
- // Modifier la valeur d'un paramètre partagé ou local
- APP.setVal = function(param_name, value, send = false) {
- if (param_name in APP.params.shared) {
- console.log("set value of shared param ", param_name);
- if (typeof(APP.params.shared[param_name].value) !== "string" ) {
- if (value > APP.params.shared[param_name].max) value = APP.params.shared[param_name].max;
- if (value < APP.params.shared[param_name].min) value = APP.params.shared[param_name].min;
- APP.params.shared[param_name].value = value;
- } else {
- value = toString(value);
- APP.params.shared[param_name].value = value;
- }
- if (send === true) {
- console.log("app parameters in cache" );
- APP.parametersCache[param_name] = { "value": value };
- APP.state.parametersCache_isEmpty = false;
- }
- } else if (param_name in APP.params.local) {
- console.log("set value of local param ", param_name);
- if (typeof(APP.params.local[param_name].value) !== "string" ) {
- if (value > APP.params.local[param_name].max) value = APP.params.local[param_name].max;
- if (value < APP.params.local[param_name].min) value = APP.params.local[param_name].min;
- APP.params.local[param_name].value = value;
- } else {
- value = toString(value);
- APP.params.local[param_name].value = value;
- }
- }
- return value;
- };
- // Mettre à jour un paramètre à partir de la valeur d'un élément js du même nom
- APP.updateVal = function(param_name, channel = "", proprety = "" ) {
- var val;
- if (proprety.length > 0) {
- val = APP.setVal(param_name + channel, $("#" + param_name).prop(proprety), true);
- $("#" + param_name).prop(proprety, val);
- } else {
- val = APP.setVal(param_name + channel, $("#" + param_name).val(), true);
- $("#" + param_name).val(val);
- }
- return val;
- }
- APP.updateBoolVal = function(param_name, channel = "", proprety = "" ) {
- var val;
- if (proprety.length > 0) {
- val = APP.setVal(param_name + channel, parseInt($("#" + param_name).prop(proprety))?true:false, true);
- $("#" + param_name).prop(proprety, val);
- } else {
- val = APP.setVal(param_name + channel, parseInt($("#" + param_name).val())?true:false, true);
- $("#" + param_name).val(val);
- }
- return val;
- }
- APP.updateIntVal = function(param_name, channel = "", proprety = "" ) {
- var val;
- if (proprety.length > 0) {
- val = APP.setVal(param_name + channel, parseInt($("#" + param_name).prop(proprety)), true);
- $("#" + param_name).prop(proprety, val);
- } else {
- val = APP.setVal(param_name + channel, parseInt($("#" + param_name).val()), true);
- $("#" + param_name).val(val);
- }
- return val;
- }
- APP.updateFloatVal = function(param_name, channel = "", proprety = "" ) {
- var val;
- if (proprety.length > 0) {
- val = APP.setVal(param_name + channel, parseFloat($("#" + param_name).prop(proprety)), true);
- $("#" + param_name).prop(proprety, val);
- } else {
- val = APP.setVal(param_name + channel, parseFloat($("#" + param_name).val()), true);
- $("#" + param_name).val(val);
- }
- return val;
- }
- // Mettre à jour la valeur d'un élément js à partir de un paramètre du même nom
- APP.updateUI = function(param_name, channel = "", proprety = "" ) {
- var val;
- if (proprety.length > 0) {
- val = APP.getVal(param_name + channel);
- $("#" + param_name).prop(proprety, val);
- } else {
- val = APP.getVal(param_name + channel);
- $("#" + param_name).val(val);
- }
- return val;
- }
- /* -------------------------------------------------------------------- */
- // Processes newly received data for signals
- APP.processSignals = function(new_signals) {
- var newDatas = [];
- // Draw signals
- for (sig_name in new_signals) {
- // Ignore empty signals
- if (!(sig_name in APP.signals)) {
- APP.signals[sig_name] = Array(APP.signals.length_display).fill(0)
- }
- if (new_signals[sig_name].size == 0) continue;
- var pointsXY = [];
- count = APP.signals.length_display - new_signals[sig_name].size;
- for (i = 0; i < count; i++) {
- APP.signals[sig_name][i] = APP.signals[sig_name][i+new_signals[sig_name].size];
- pointsXY.push([i, APP.signals[sig_name][i]]);
- }
- for (var i = 0; i < new_signals[sig_name].size; i++) {
- APP.signals[sig_name][i+count] = new_signals[sig_name].value[i];
- pointsXY.push([i+count, APP.signals[sig_name][i+count]]);
- //pointsXY.push([i, new_signals[sig_name].value[i]]);
- }
- newDatas.push(pointsXY);
- }
- // Update graph
- APP.plot.setData(newDatas);
- APP.plot.draw();
- }
- //Handler
- var signalsHandler = function() {
- if (!APP.state.socket_opened || !APP.state.running) return;
- while (APP.signalStack.length > 0) {
- APP.processSignals(APP.signalStack[0]);
- APP.signalStack.splice(0, 1);
- }
- }
- APP.processParameters = function(new_params) {
- var old_params = $.extend(true, {}, APP.params.shared);
- var send_all_params = Object.keys(new_params).indexOf('send_all_params') != -1;
- if ('APP_RUN' in new_params) {
- APP.state.running = new_params['APP_RUN'].value;
- }
- for (var param_name in new_params) {
- APP.params.shared[param_name] = new_params[param_name];
- if (APP.params.callback[param_name] !== undefined)
- APP.params.callback[param_name](new_params);
- }
- // On attend de recevoir les premiers paramètres de l'application C avant de laisser
- // la main à l'utilisateur pour changer les paramètres
- if ($("body" ).hasClass("loaded" ) === false) {
- console.log("Recept init parms ", new_params);
- $("body" ).addClass("loaded" );
- // on masque l"icon de chargement
- var $element = $("#loader-wrapper" );
- if ($element.length == 0){
- $element.remove();
- }
- }
- };
- // Sends to server parameters
- APP.sendParameters = function() {
- if (APP.state.parametersCache_isEmpty !== false) {
- if (!APP.state.socket_opened) {
- console.log('ERROR: Cannot save changes, socket not opened');
- return false;
- }
- APP.parametersCache["in_command"] = { value: "send_all_params" };
- APP.ws.send(JSON.stringify({ parameters: APP.parametersCache }));
- APP.parametersCache = {};
- APP.state.parametersCache_isEmpty = true;
- }
- return true;
- };
- var parametersHandler = function() {
- if (!APP.state.socket_opened) return;
- while (APP.parameterStack.length > 0) {
- APP.processParameters(APP.parameterStack[0]);
- APP.parameterStack.splice(0, 1);
- }
- APP.sendParameters();
- }
- //Set handlers timers
- setInterval(signalsHandler, 40);
- setInterval(parametersHandler, 10);
- /* -------------------------------------------------------------------- */
- APP.change_app_run = function(new_params) {
- $("#APP_RUN" ).text(new_params['APP_RUN'].value? "RUN":"STOP" );
- }
- APP.change_osc_show_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.INPUT_CHANNEL_1)
- $("#OSC_SHOW_CH" ).prop("checked", new_params['OSC_SHOW_CH1'].value);
- }
- APP.change_osc_show_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.INPUT_CHANNEL_2)
- $("#OSC_SHOW_CH" ).prop("checked", new_params['OSC_SHOW_CH2'].value);
- }
- APP.change_osc_invert_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.INPUT_CHANNEL_1)
- $("#OSC_INVERT_CH" ).prop("checked", new_params['OSC_INVERT_CH1'].value);
- }
- APP.change_osc_invert_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.INPUT_CHANNEL_2)
- $("#OSC_INVERT_CH" ).prop("checked", new_params['OSC_INVERT_CH2'].value);
- }
- APP.change_osc_prob_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.INPUT_CHANNEL_1)
- $("#OSC_PROB_CH" ).prop("checked", new_params['OSC_PROB_CH1'].value);
- }
- APP.change_osc_prob_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.INPUT_CHANNEL_2)
- $("#OSC_PROB_CH" ).prop("checked", new_params['OSC_PROB_CH2'].value);
- }
- APP.change_osc_gain_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.INPUT_CHANNEL_1)
- $("#OSC_GAIN_CH" ).prop("checked", new_params['OSC_GAIN_CH1'].value);
- }
- APP.change_osc_gain_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.INPUT_CHANNEL_2)
- $("#OSC_GAIN_CH" ).prop("checked", new_params['OSC_GAIN_CH2'].value);
- }
- APP.change_gen_enable_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_1)
- $("#GEN_ENABLE_CH" ).prop("checked", new_params['GEN_ENABLE_CH1'].value);
- }
- APP.change_gen_enable_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_2)
- $("#GEN_ENABLE_CH" ).prop("checked", new_params['GEN_ENABLE_CH2'].value);
- }
- APP.change_gen_show_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_1)
- $("#GEN_SHOW_CH" ).prop("checked", new_params['GEN_SHOW_CH1'].value);
- }
- APP.change_gen_show_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_2)
- $("#GEN_SHOW_CH" ).prop("checked", new_params['GEN_SHOW_CH2'].value);
- }
- APP.change_gen_amplitude_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_1)
- $("#GEN_AMPLITUDE_CH" ).val(new_params['GEN_AMPLITUDE_CH1'].value);
- }
- APP.change_gen_amplitude_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_2)
- $("#GEN_AMPLITUDE_CH" ).val(new_params['GEN_AMPLITUDE_CH2'].value);
- }
- APP.change_gen_frequency_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_1)
- $("#GEN_FREQUENCY_CH" ).val(new_params['GEN_FREQUENCY_CH1'].value);
- }
- APP.change_gen_frequency_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_2)
- $("#GEN_FREQUENCY_CH" ).val(new_params['GEN_FREQUENCY_CH2'].value);
- }
- APP.change_gen_offset_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_1)
- $("#GEN_OFFSET_CH" ).val(new_params['GEN_OFFSET_CH1'].value);
- }
- APP.change_gen_frequency_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_2)
- $("#GEN_OFFSET_CH" ).val(new_params['GEN_OFFSET_CH2'].value);
- }
- APP.change_gen_waveform_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_1) {
- var val = new_params['GEN_WAVEFORM_CH1'].value;
- $("#GEN_WAVEFORM_CH" ).val(val);
- APP.UI.update_gen_waveform_section(val);
- }
- }
- APP.change_gen_waveform_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_2) {
- var val = new_params['GEN_WAVEFORM_CH2'].value;
- $("#GEN_WAVEFORM_CH" ).val(val);
- APP.UI.update_gen_waveform_section(val);
- }
- }
- APP.change_gen_mode_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_1) {
- var val = new_params['GEN_MODE_CH1'].value;
- $("#GEN_MODE_CH" ).val(val);
- APP.UI.update_gen_mode_section(val);
- }
- }
- APP.change_gen_mode_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_2) {
- var val = new_params['GEN_MODE_CH2'].value;
- $("#GEN_MODE_CH" ).val(val);
- APP.UI.update_gen_mode_section(val);
- }
- }
- APP.change_gen_duty_cycle_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_1)
- $("#GEN_DUTY_CYCLE_CH" ).val(new_params['GEN_DUTY_CYCLE_CH1'].value);
- }
- APP.change_gen_duty_cycle_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_2)
- $("#GEN_DUTY_CYCLE_CH" ).val(new_params['GEN_DUTY_CYCLE_CH2'].value);
- }
- APP.change_gen_burst_count_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_1)
- $("#GEN_BURST_COUNT_CH" ).val(new_params['GEN_BURST_COUNT_CH1'].value);
- }
- APP.change_gen_burst_count_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_2)
- $("#GEN_BURST_COUNT_CH" ).val(new_params['GEN_BURST_COUNT_CH2'].value);
- }
- APP.change_gen_burst_rep_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_1)
- $("#GEN_BURST_REP_CH" ).val(new_params['GEN_BURST_REP_CH1'].value);
- }
- APP.change_gen_burst_rep_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_2)
- $("#GEN_BURST_REP_CH" ).val(new_params['GEN_BURST_REP_CH2'].value);
- }
- APP.change_gen_burst_per_ch1 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_1)
- $("#GEN_BURST_PER_CH" ).val(new_params['GEN_BURST_PER_CH1'].value);
- }
- APP.change_gen_burst_per_ch2 = function(new_params) {
- if (APP.state.currentMenu === Menu.OUTPUT_CHANNEL_2)
- $("#GEN_BURST_PER_CH" ).val(new_params['GEN_BURST_PER_CH2'].value);
- }
- APP.params.callback["APP_RUN"] = APP.change_app_run;
- APP.params.callback["OSC_SHOW_CH1"] = APP.change_osc_show_ch1;
- APP.params.callback["OSC_SHOW_CH2"] = APP.change_osc_show_ch2;
- APP.params.callback["OSC_INVERT_CH1"] = APP.change_osc_invert_ch1;
- APP.params.callback["OSC_INVERT_CH2"] = APP.change_osc_invert_ch2;
- APP.params.callback["OSC_PROB_CH1"] = APP.change_osc_prob_ch1;
- APP.params.callback["OSC_PROB_CH2"] = APP.change_osc_prob_ch2;
- APP.params.callback["OSC_GAIN_CH1"] = APP.change_osc_gain_ch1;
- APP.params.callback["OSC_GAIN_CH2"] = APP.change_osc_gain_ch2;
- APP.params.callback["GEN_ENABLE_CH1"] = APP.change_gen_enable_ch1;
- APP.params.callback["GEN_ENABLE_CH2"] = APP.change_gen_enable_ch2;
- APP.params.callback["GEN_SHOW_CH1"] = APP.change_gen_show_ch1;
- APP.params.callback["GEN_SHOW_CH2"] = APP.change_gen_show_ch2;
- APP.params.callback["GEN_AMPLITUDE_CH1"] = APP.change_gen_amplitude_ch1;
- APP.params.callback["GEN_AMPLITUDE_CH2"] = APP.change_gen_amplitude_ch2;
- APP.params.callback["GEN_FREQUENCY_CH1"] = APP.change_gen_frequency_ch1;
- APP.params.callback["GEN_FREQUENCY_CH2"] = APP.change_gen_frequency_ch2;
- APP.params.callback["GEN_OFFSET_CH1"] = APP.change_gen_offset_ch1;
- APP.params.callback["GEN_OFFSET_CH2"] = APP.change_gen_offset_ch2;
- APP.params.callback["GEN_WAVEFORM_CH1"] = APP.change_gen_waveform_ch1;
- APP.params.callback["GEN_WAVEFORM_CH2"] = APP.change_gen_waveform_ch2;
- APP.params.callback["GEN_MODE_CH1"] = APP.change_gen_mode_ch1;
- APP.params.callback["GEN_MODE_CH2"] = APP.change_gen_mode_ch2;
- APP.params.callback["GEN_DUTY_CYCLE_CH1"] = APP.change_gen_duty_cycle_ch1;
- APP.params.callback["GEN_DUTY_CYCLE_CH2"] = APP.change_gen_duty_cycle_ch2;
- APP.params.callback["GEN_BURST_COUNT_CH1"] = APP.change_gen_burst_count_ch1;
- APP.params.callback["GEN_BURST_COUNT_CH2"] = APP.change_gen_burst_count_ch2;
- APP.params.callback["GEN_BURST_REP_CH1"] = APP.change_gen_burst_rep_ch1;
- APP.params.callback["GEN_BURST_REP_CH2"] = APP.change_gen_burst_rep_ch2;
- APP.params.callback["GEN_BURST_PER_CH1"] = APP.change_gen_burst_per_ch1;
- APP.params.callback["GEN_BURST_PER_CH2"] = APP.change_gen_burst_per_ch2;
- }(window.APP = window.APP || {}, jQuery));
- // Page onload event handler
- $(function() {
- APP.config.client_id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
- var r = Math.random() * 16 | 0,
- v = c == 'x' ? r : (r & 0x3 | 0x8);
- return v.toString(16);
- });
- $.ajax({
- url: '/set_client_id', //Server script to process data
- type: 'POST',
- //Ajax events
- //beforeSend: beforeSendHandler,
- success: function(e) { console.log(e); },
- error: function(e) { console.log(e); },
- // Form data
- data: APP.config.client_id,
- //Options to tell jQuery not to process data or worry about content-type.
- cache: false,
- contentType: false,
- processData: false
- });
- // Init plot
- APP.plot = $.plot($("#placeholder" ), [], {
- series: {
- shadowSize: 0, // Drawing is faster without shadows
- },
- yaxis: {
- min: -5,
- max: 5,
- show: true,
- },
- xaxis: {
- min: 0,
- max: APP.signals.length_display,
- show: true
- },
- grid: {
- show: true
- },
- colors: [
- '#FF2A68', '#FF9500', '#FFDB4C', '#87FC70', '#22EDC7', '#1AD6FD', '#C644FC', '#52EDC7', '#EF4DB6'
- ]
- });
- APP.UI.close_menu();
- for (var name in APP.UI.changeCallbacks) {
- $("#" + name).change(APP.UI.changeCallbacks[name]);
- }
- for (var name in APP.UI.clickCallbacks) {
- $("#" + name).click(APP.UI.clickCallbacks[name]);
- }
- // Bind to the window resize event to redraw the graph; trigger that event to do the first drawing
- $(window).resize(function() {
- APP.plot.resize();
- APP.plot.setupGrid();
- });
- // Revenir à la page précédente si on clic sur back-btn
- APP.config.previousPageUrl = document.referrer;
- const currentUrl = window.location.href;
- if (currentUrl === APP.config.previousPageUrl || APP.config.previousPageUrl === "" ){
- APP.config.previousPageUrl = "/";
- }
- $("#return-button" ).on("click", function(event) {
- APP.state.unexpected_closed = false;
- window.location.href = APP.config.previousPageUrl;
- });
- $("#home-button" ).on("click", function(event) {
- APP.state.unexpected_closed = false;
- window.location.href = "/";
- APP.ws.onclose = function() {}; // disable onclose handler first
- APP.ws.close();
- });
- APP.startApp();
- // Stop the application when page is unloaded
- $(window).on('beforeunload', function() {
- if (APP.ws) {
- APP.ws.onclose = function() {}; // disable onclose handler first
- APP.ws.close();
- $.ajax({
- url: APP.config.stop_app_url,
- async: false
- });
- APP.state.unexpected_closed = false;
- }
- });
- });
|
Message édité par clemCH le 12-05-2024 à 12:41:08
|