Browse Source

arduino sketch: use fixed `delayMicroseconds()` instead of simple wait loop to improve stability of sample rate

Fabian Peter Hammerle 3 years ago
parent
commit
89b68f938b
3 changed files with 25 additions and 29 deletions
  1. 2 8
      arduino-sketch.ino
  2. 1 0
      epy_block_0.py
  3. 22 21
      scope.grc

+ 2 - 8
arduino-sketch.ino

@@ -1,17 +1,11 @@
-// https://www.arduino.cc/reference/en/language/functions/time/micros/
-const unsigned long SAMPLE_INTERVAL_MICROSECONDS = 1000L;
-
 void setup() {
     // $ stty -F /dev/ttyUSB0 | grep speed
     Serial.begin(115200);
 }
 
-unsigned long last_sample_micros = 0;
-
 void loop() {
-    while (micros() - last_sample_micros < SAMPLE_INTERVAL_MICROSECONDS)
-        ;
-    last_sample_micros = micros();
+    // effective sample rate measured in epy_block_0.py
+    delayMicroseconds(800);
     // > On ATmega based boards [...], it takes about 100 microseconds
     // > (0.0001 s) > to read an analog input, [...]
     // https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/

+ 1 - 0
epy_block_0.py

@@ -27,6 +27,7 @@ class ArduinoAnalogReadings(gnuradio.gr.sync_block):
         assert len(buffer) % 2 == 0
         buffer_samples_count = len(buffer) // 2
         output_items[0][:buffer_samples_count] = numpy.frombuffer(buffer, dtype=">u2")
+        assert output_items[0][:buffer_samples_count].max() < 1024, "lost sync?"
         self._samples_counter += buffer_samples_count
         current_timestamp = time.time()
         if not self._sample_rate_report_timestamp:

+ 22 - 21
scope.grc

@@ -41,7 +41,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [439, 210]
+    coordinate: [454, 210]
     rotation: 0
     state: true
 - name: resistor_1_ohm
@@ -53,7 +53,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [813, 29]
+    coordinate: [828, 29]
     rotation: 0
     state: true
 - name: resistor_2_ohm
@@ -65,14 +65,14 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [811, 128]
+    coordinate: [826, 128]
     rotation: 0
     state: true
 - name: sample_rate_hz
   id: variable
   parameters:
     comment: ''
-    value: 1e6 / 1000
+    value: '1044.2'
   states:
     bus_sink: false
     bus_source: false
@@ -89,7 +89,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [816, 227]
+    coordinate: [831, 227]
     rotation: 0
     state: true
 - name: blocks_multiply_const_vxx_0
@@ -107,7 +107,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [811, 324]
+    coordinate: [826, 324]
     rotation: 0
     state: true
 - name: blocks_short_to_float_0
@@ -124,7 +124,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [472, 324]
+    coordinate: [487, 324]
     rotation: 0
     state: true
 - name: epy_block_0
@@ -143,19 +143,20 @@ blocks:
       \       buffer = self._serial_port.read(\n            2 * min(len(output_items[0]),\
       \ self._buffer_max_length)\n        )\n        assert len(buffer) % 2 == 0\n\
       \        buffer_samples_count = len(buffer) // 2\n        output_items[0][:buffer_samples_count]\
-      \ = numpy.frombuffer(buffer, dtype=\">u2\")\n        self._samples_counter +=\
-      \ buffer_samples_count\n        current_timestamp = time.time()\n        if\
-      \ not self._sample_rate_report_timestamp:\n            self._sample_rate_report_timestamp\
-      \ = current_timestamp\n        elif (current_timestamp - self._sample_rate_report_timestamp)\
-      \ > 8:\n            sample_rate_hz = self._samples_counter / (\n           \
-      \     current_timestamp - self._sample_rate_report_timestamp\n            )\n\
-      \            print(f\"{sample_rate_hz:.01f} Hz\")\n            self._samples_counter\
-      \ = 0\n            self._sample_rate_report_timestamp = current_timestamp\n\
-      \        return buffer_samples_count\n"
+      \ = numpy.frombuffer(buffer, dtype=\">u2\")\n        assert output_items[0][:buffer_samples_count].max()\
+      \ < 1024, \"lost sync?\"\n        self._samples_counter += buffer_samples_count\n\
+      \        current_timestamp = time.time()\n        if not self._sample_rate_report_timestamp:\n\
+      \            self._sample_rate_report_timestamp = current_timestamp\n      \
+      \  elif (current_timestamp - self._sample_rate_report_timestamp) > 8:\n    \
+      \        sample_rate_hz = self._samples_counter / (\n                current_timestamp\
+      \ - self._sample_rate_report_timestamp\n            )\n            print(f\"\
+      {sample_rate_hz:.01f} Hz\")\n            self._samples_counter = 0\n       \
+      \     self._sample_rate_report_timestamp = current_timestamp\n        return\
+      \ buffer_samples_count\n"
     affinity: ''
     alias: ''
     baud_rate: '115200'
-    buffer_max_length: int(sample_rate_hz)
+    buffer_max_length: int(sample_rate_hz/4)
     comment: ''
     maxoutbuf: '0'
     minoutbuf: '0'
@@ -168,7 +169,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [32, 276]
+    coordinate: [33, 276]
     rotation: 0
     state: true
 - name: qtgui_freq_sink_x_0
@@ -248,7 +249,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [822, 442]
+    coordinate: [837, 442]
     rotation: 0
     state: true
 - name: qtgui_number_sink_0
@@ -311,7 +312,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [1155, 291]
+    coordinate: [1170, 291]
     rotation: 0
     state: true
 - name: qtgui_time_sink_x_0
@@ -408,7 +409,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [1159, 138]
+    coordinate: [1174, 138]
     rotation: 0
     state: true