wip
authorNick Downing <nick@ndcode.org>
Thu, 24 Mar 2022 12:13:41 +0000 (23:13 +1100)
committerNick Downing <nick@ndcode.org>
Thu, 24 Mar 2022 12:13:41 +0000 (23:13 +1100)
examples/board_clock_7seg/Makefile
examples/board_clock_7seg/atmega168_clock_7seg.c
examples/board_clock_7seg/clock_7seg.c
examples/board_clock_7seg/led_17seg.svg
examples/board_clock_7seg/led_8seg.svg
examples/board_clock_7seg/led_colon.py [new file with mode: 0755]
examples/board_clock_7seg/led_colon.svg [new file with mode: 0644]

index 06154f9..1e7e5a4 100644 (file)
@@ -49,6 +49,9 @@ led_8seg.inc: led_8seg.py
 led_17seg.inc: led_17seg.py
        ./led_17seg.py >$@
 
+led_colon.inc: led_colon.py
+       ./led_colon.py >$@
+
 ${target}: ${board}
        @echo $@ done
 
index 01f59f3..1a9a6f4 100644 (file)
 #include "avr_mcu_section.h"
 AVR_MCU(F_CPU, "atmega168");
 
+#define N_DIGITS 6
 #define USE_17SEG 1
+#if USE_17SEG
+#define BYTES_PER_DIGIT 3
+#else
+#define BYTES_PER_DIGIT 1
+#endif
 
 PIN_DEFINE(SRESET, D, PD4, 1);
 //PIN_DEFINE(SOE, D, PD6, 1);    // pwm AIN0/OC0A
@@ -121,16 +127,30 @@ enum EState {
 
 uint8_t state = state_ShowTime | state_IncrementTime;
 #if USE_17SEG
-uint32_t digits[4];
+uint32_t digits[N_DIGITS];
 #else
-uint8_t digits[4];
+uint8_t digits[N_DIGITS];
 #endif
 
 enum EDecimal {
-  d_second = 0, d_10second, d_minute, d_10minute, d_hour, d_10hour, d_100hour, d_MAX
+  D_SECOND = 0, D_MINUTE, D_HOUR, D_DAY, D_MONTH, D_YEAR, D_MAX
 };
-const uint8_t decimal_max[d_MAX] = { 10, 6, 10, 6, 10, 10, 10 };
-uint8_t decimal[d_MAX] = {0,0,0,0,0,0,0};
+const uint8_t decimal_max[D_MAX] = {60, 60, 24, 31, 12, 100}; //200};
+const uint8_t day_max[12] = {
+  31, // Jan
+  28, // Feb
+  31, // Mar
+  30, // Apr
+  31, // May
+  30, // Jun
+  31, // Jul
+  31, // Aug
+  30, // Sep
+  31, // Oct
+  30, // Nov
+  31, // Dec
+};
+uint8_t decimal[D_MAX] = {0, 0, 0, 0, 0, 0};
 uint8_t decimalChanged = 0;
 
 uint8_t keyState;// = 0x7;
@@ -172,20 +192,32 @@ static inline void pwmSet(uint8_t pwm)
 }
 
 
+uint8_t dayMax(uint8_t month, uint8_t year) {
+  int max = day_max[month];
+  if (month == 1 && (year & 3) == 0 && year % 100 != 0)
+    ++max;
+  return max;
+}
+
 void decimalInc()
 {
-  for (uint8_t in = 0; in < d_MAX; in++) {
-    decimal[in]++;
+  for (uint8_t in = 0; in < D_MAX; in++) {
+    ++decimal[in];
     decimalChanged |= (1 << in);
-    if (decimal[in] == decimal_max[in]) {
+    if (
+      decimal[in] == (
+        in == D_DAY ?
+          dayMax(decimal[D_MONTH], decimal[D_YEAR]) :
+          decimal_max[in]
+      )
+    )
       decimal[in] = 0;
-    else
+    else
       break;
   }
 }
 
 #if USE_17SEG
-
 //   A1 A2
 // F H J K B
 //   G1 G2
@@ -231,7 +263,7 @@ const uint8_t digits2led[10] = {
 #endif
 
 struct {
-  uint8_t b[16];  
+  uint8_t b[N_DIGITS * BYTES_PER_DIGIT];
   uint8_t in : 4;
   uint8_t out : 4;  
 } spi;
@@ -348,7 +380,7 @@ void resetTimer()
   startShowTime();
   tick_timer_reset(delay_Second, TICK_SECOND);
   tick_timer_reset(delay_Update, 1);
-  for (uint8_t bi = 0; bi < d_MAX; bi++)
+  for (uint8_t bi = 0; bi < D_MAX; bi++)
     decimal[bi] = 0;
 }
 
@@ -360,24 +392,27 @@ void updateTimer()
     switch (state & ~state_IncrementTime) {
       case state_ShowTime:
         //digits[1] |= SEG_DP;
-        digits[2] |= SEG_DP;
-        break;
-      case state_ShowHour:
-        if (state & state_IncrementTime)
-          digits[0] |= SEG_DP;
+        //digits[2] |= SEG_DP;
+        digits[0] |= SEG_DP; // mapped to colon
         break;
+      //case state_ShowHour:
+      //  if (state & state_IncrementTime)
+      //    digits[0] |= SEG_DP;
+      //  break;
     }
   }       
   cli();
   // interupts are stopped here, so there is no race condition
   int restart = spi.out == spi.in;
-#if 0
+#if 1
  digits[0] = 1;
  digits[1] = 2;
  digits[2] = 4;
  digits[3] = 8;
+ digits[4] = 0x10;
+ digits[5] = 0x20;
 #endif
-  for (uint8_t bi = 0; bi < 4; bi++)
+  for (uint8_t bi = 0; bi < N_DIGITS; bi++)
 #if USE_17SEG
   {
     spi.b[spi.out++] = (uint8_t)(digits[bi] >> 16);
@@ -397,17 +432,23 @@ void updateTimerDisplay()
   do {
     switch (state & ~state_IncrementTime) {
       case state_ShowTime: {
-        if (decimalChanged & (1 << d_hour)) {
+        if (decimalChanged & (1 << D_HOUR)) {
           startShowHours(4 * TICK_SECOND);
           break;
         }
         decimalChanged = 0;
-        for (uint8_t bi = 0; bi < 4; bi++)
-          digits[bi] = digits2led[decimal[bi]];
+
+        digits[0] = digits2led[decimal[D_SECOND] % 10];
+        digits[1] = digits2led[decimal[D_SECOND] / 10];
+        digits[2] = digits2led[decimal[D_MINUTE] % 10];
+        digits[3] = digits2led[decimal[D_MINUTE] / 10];
+        digits[4] = digits2led[decimal[D_HOUR] % 10];
+        digits[5] = digits2led[decimal[D_HOUR] / 10];
 
         if (!(state & state_IncrementTime)) {
           //digits[1] |= SEG_DP;
-          digits[2] |= SEG_DP;
+          //digits[2] |= SEG_DP;
+          digits[0] |= SEG_DP; // mapped to colon
         }
       }  break;
       case state_ShowHour: {
@@ -417,20 +458,17 @@ void updateTimerDisplay()
           break;
         }
         decimalChanged = 0;
-        for (uint8_t bi = 0; bi < 4; bi++)
-          digits[bi] = 0;
-        
-        if (decimal[d_100hour]) {
-          digits[3] = digits2led[decimal[d_100hour]];
-          digits[2] = digits2led[decimal[d_10hour]];
-          digits[1] = digits2led[decimal[d_hour]];
-        } else if (decimal[d_10hour]) {
-          digits[3] = digits2led[decimal[d_10hour]];
-          digits[2] = digits2led[decimal[d_hour]];          
-        } else {
-          digits[2] = digits2led[decimal[d_hour]];          
-        }
-        digits[0] = SEG_h; // hours
+
+        uint8_t day = decimal[D_DAY] + 1;
+        uint8_t month = decimal[D_MONTH] + 1;
+        uint16_t year = decimal[D_YEAR]; //+ 2000;
+
+        digits[0] = digits2led[year % 10];
+        digits[1] = digits2led[year / 10];
+        digits[2] = digits2led[month % 10] | SEG_DP;
+        digits[3] = digits2led[month / 10];
+        digits[4] = digits2led[day % 10] | SEG_DP;
+        digits[5] = digits2led[day / 10];
       }  break;
   //    case state_Sleep: {
         /* nothing to do */
index 644fb75..391703c 100644 (file)
 #include "button.h"
 #include "hc595.h"
 
-#define USE_17SEG 1
-
-#define N_DIGITS 4
+#define N_DIGITS 6
 #define ORIGIN_X 50.f
 #define ORIGIN_Y 50.f
-#define PITCH_X 320.f
-#define PITCH_Y 450.f
-#define WINDOW_X (ORIGIN_X + N_DIGITS * PITCH_X)
-#define WINDOW_Y (ORIGIN_Y + PITCH_Y)
+#define DIGIT_WIDTH 320.f
+#define COLON_WIDTH 110.f
+#define LINE_HEIGHT 450.f
+#define COLON_X (ORIGIN_X + 2 * DIGIT_WIDTH)
+#define COLON_Y ORIGIN_Y
+#define WINDOW_X (ORIGIN_X + 5 * DIGIT_WIDTH + 2 * COLON_WIDTH)
+#define WINDOW_Y (ORIGIN_Y + LINE_HEIGHT)
+
+#define USE_17SEG 1
+#if USE_17SEG
+#define BYTES_PER_DIGIT 3
+#define SEG_DP 0x10000
+#else
+#define BYTES_PER_DIGIT 1
+#define SEG_DP 0x80
+#endif
 
 enum {
   B_START = 0, B_STOP, B_RESET,
@@ -59,14 +69,18 @@ button_t button[B_MAX]; // Start/Stop/Reset
 volatile int do_button_press[B_MAX] = {0};
 avr_t * avr = NULL;
 avr_vcd_t vcd_file;
-#if USE_17SEG
-#define SHIFTERS_PER_DIGIT 3
-#else
-#define SHIFTERS_PER_DIGIT 1
-#endif
-#define N_SHIFTERS (N_DIGITS * SHIFTERS_PER_DIGIT)
+#define N_SHIFTERS (N_DIGITS * BYTES_PER_DIGIT)
 hc595_t shifters[N_SHIFTERS];
 
+const float digit_pos[N_DIGITS][3] = {
+  {ORIGIN_X + 0.f * DIGIT_WIDTH + 0.f * COLON_WIDTH, ORIGIN_Y, 1.f},
+  {ORIGIN_X + 1.f * DIGIT_WIDTH + 0.f * COLON_WIDTH, ORIGIN_Y, 1.f},
+  {ORIGIN_X + 2.f * DIGIT_WIDTH + 1.f * COLON_WIDTH, ORIGIN_Y, 1.f},
+  {ORIGIN_X + 3.f * DIGIT_WIDTH + 1.f * COLON_WIDTH, ORIGIN_Y, 1.f},
+  {ORIGIN_X + 4.f * DIGIT_WIDTH + 2.f * COLON_WIDTH, ORIGIN_Y, .5f},
+  {ORIGIN_X + 4.5f * DIGIT_WIDTH + 2.f * COLON_WIDTH, ORIGIN_Y, .5f},
+};
+
 int display_flag = 0;
 volatile uint32_t display_bits[N_DIGITS];
 volatile uint8_t display_pwm = 0;
@@ -75,6 +89,7 @@ int window;
 
 #include "led_8seg.inc"
 #include "led_17seg.inc"
+#include "led_colon.inc"
 
 /*
  * called when the AVR has latched the 595
@@ -88,7 +103,7 @@ void hc595_changed_hook(struct avr_irq_t * irq, uint32_t value, void * param)
  printf("\n");
 #endif
   for (int i = 0; i < N_DIGITS; ++i)
-    display_bits[i] = shifters[i * SHIFTERS_PER_DIGIT].value;
+    display_bits[i] = shifters[i * BYTES_PER_DIGIT].value;
 #if 0
  printf("digits:\n");
  for (int i = 0; i < N_DIGITS; ++i)
@@ -126,32 +141,45 @@ void displayCB(void)    /* function called whenever redisplay needed */
   if (color_on < color_off)
     color_on = color_off;
 
-  for (int di = 0; di < 4; di++) {
-    uint32_t bits = display_bits[di];
+  uint32_t bits;
+  for (int di = 0; di < N_DIGITS; di++) {
+    bits = display_bits[di];
+
+    float x = digit_pos[di][0];
+    float y = digit_pos[di][1];
+    float scale = digit_pos[di][2];
 
 #if USE_17SEG
-    for (int i = 0; i < 17; i++) {
+    int end = di == 3 ? 16 : 17; // last digit DP mapped to colon instead
 #else
-    for (int i = 0; i < 8; i++) {
+    int end = di == 3 ? 7 : 8; // last digit DP mapped to colon instead
 #endif
+    for (int i = 0; i < end; i++) {
       glColor3f(0.f, bits & (1 << i) ? color_on : color_off, 0.f);
-      float x = ORIGIN_X + di * PITCH_X;
-      float y = ORIGIN_Y;
-
       glBegin(GL_POLYGON); //GL_LINE_STRIP);
 #if USE_17SEG
       int end = led_17seg_ptr[i + 1];
       for (int j = led_17seg_ptr[i]; j < end; ++j)
-        glVertex2f(x + led_17seg[j][0], y + led_17seg[j][1]);
+        glVertex2f(x + led_17seg[j][0] * scale, y + led_17seg[j][1] * scale);
 #else
       int end = led_8seg_ptr[i + 1];
       for (int j = led_8seg_ptr[i]; j < end; ++j)
-        glVertex2f(x + led_8seg[j][0], y + led_8seg[j][1]);
+        glVertex2f(x + led_8seg[j][0] * scale, y + led_8seg[j][1] * scale);
 #endif
       glEnd();
     }
   }
 
+  // colon
+  glColor3f(0.f, bits & SEG_DP ? color_on : color_off, 0.f);
+  for (int i = 0; i < 2; ++i) {
+    glBegin(GL_POLYGON); //GL_LINE_STRIP);
+    int end = led_colon_ptr[i + 1];
+    for (int j = led_colon_ptr[i]; j < end; ++j)
+      glVertex2f(COLON_X + led_colon[j][0], COLON_Y + led_colon[j][1]);
+    glEnd();
+  }
+
   glutSwapBuffers();
   //glFlush();        /* Complete any pending operations */
 }
index 1b20c79..df38540 100644 (file)
@@ -25,9 +25,9 @@
      showgrid="true"
      units="px"
      width="100px"
-     inkscape:zoom="0.73940795"
-     inkscape:cx="252.90504"
-     inkscape:cy="387.47217"
+     inkscape:zoom="4.182723"
+     inkscape:cx="252.94527"
+     inkscape:cy="387.66612"
      inkscape:window-width="1920"
      inkscape:window-height="1009"
      inkscape:window-x="0"
        rx="5.291666"
        cy="105.83332"
        cx="68.791672" />
+    <path
+       style="fill:#000000;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
+       d="m 69.849999,100.54166 1.852083,0.79375 1.5875,1.5875 0.79375,1.85209 v 2.11666 l -0.79375,1.85209 -1.5875,1.5875 -1.852083,0.79375 -2.116667,0 -1.852083,-0.79375 -1.5875,-1.5875 -0.79375,-1.85209 0,-2.11666 0.79375,-1.85208 1.5875,-1.5875 1.852083,-0.79376 z"
+       id="path928-6-5-6"
+       sodipodi:nodetypes="ccccccccccccccccc" />
     <path
        style="fill:#000000;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
        d="m 25.135417,47.625005 v 10.58333 H 6.6145817 L -1.6000005e-6,52.916665 6.6145817,47.625005 Z"
        d="m 43.391666,97.895826 -8.995833,-18.52083 v -18.52083 h 1.587499 l 8.995834,18.52083 v 18.52083 z"
        id="path928-3-7-5-6-1-8-3-9"
        sodipodi:nodetypes="ccccccc" />
-    <ellipse
-       style="fill:#000000;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
-       id="path10968"
-       cx="69.717712"
-       cy="107.8177"
-       rx="0.92604166"
-       ry="1.984375" />
-    <path
-       style="fill:#000000;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
-       d="m 69.849999,100.54166 1.852083,0.79375 1.5875,1.5875 0.79375,1.85209 v 2.11666 l -0.79375,1.85209 -1.5875,1.5875 -1.852083,0.79375 -2.116667,0 -1.852083,-0.79375 -1.5875,-1.5875 -0.79375,-1.85209 0,-2.11666 0.79375,-1.85208 1.5875,-1.5875 1.852083,-0.79376 z"
-       id="path928-6-5-6"
-       sodipodi:nodetypes="ccccccccccccccccc" />
   </g>
 </svg>
index 8908215..a616b07 100644 (file)
@@ -25,9 +25,9 @@
      showgrid="true"
      units="px"
      width="100px"
-     inkscape:zoom="0.73940795"
-     inkscape:cx="179.87364"
-     inkscape:cy="387.47217"
+     inkscape:zoom="4.182723"
+     inkscape:cx="179.78719"
+     inkscape:cy="387.66612"
      inkscape:window-width="1920"
      inkscape:window-height="1009"
      inkscape:window-x="0"
      inkscape:label="Layer 1"
      inkscape:groupmode="layer"
      id="layer1">
+    <ellipse
+       style="fill:#ff000f;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
+       id="path10970"
+       ry="5.2916627"
+       rx="5.291666"
+       cy="105.83332"
+       cx="68.791672" />
+    <path
+       style="fill:#000000;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
+       d="m 69.849999,100.54166 1.852083,0.79375 1.5875,1.5875 0.79375,1.85209 v 2.11666 l -0.79375,1.85209 -1.5875,1.5875 -1.852083,0.79375 -2.116667,0 -1.852083,-0.79375 -1.5875,-1.5875 -0.79375,-1.85209 0,-2.11666 0.79375,-1.85208 1.5875,-1.5875 1.852083,-0.79376 z"
+       id="path928-6-5-6"
+       sodipodi:nodetypes="ccccccccccccccccc" />
     <path
        style="fill:#000000;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
        d="m 49.344789,111.12499 1.058333,-0.26458 1.058334,-0.52917 1.058333,-0.79375 1.058333,-1.05833 -7.937499,-7.9375 c 0,0 -30.138854,0 -38.3645838,0 l -7.9375,7.9375 1.058333,1.05833 1.058334,0.79375 1.058333,0.52917 1.058333,0.26458 z"
        d="m 49.344789,-5.2916664 1.058333,0.2645833 1.058334,0.5291667 1.058333,0.7937499 1.058333,1.0583333 -7.937499,7.9374996 -38.364583,9e-7 -7.9374999,-7.9375 1.0583333,-1.058333 1.0583333,-0.79375 1.0583332,-0.529167 1.0583333,-0.264583 z"
        id="path928-9"
        sodipodi:nodetypes="ccccccccccccc" />
-    <ellipse
-       style="fill:#ff000f;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
-       id="path10970"
-       ry="5.2916627"
-       rx="5.291666"
-       cy="105.83332"
-       cx="68.791672" />
     <path
        style="fill:#000000;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
        d="m -2.6458348,-0.6614577 7.9374998,7.9375 V 44.979167 l -7.6067707,6.085417 -1.3229167,-1.05833 -0.8598958,-1.05834 -0.5291666,-1.32291 -0.2645834,-1.058338 2e-7,-42.9947907 0.2645833,-1.058333 0.5291667,-1.058334 0.7937499,-1.058333 z"
        d="M 55.562498,106.49478 47.624999,98.557283 V 60.854164 l 7.60677,-6.085417 1.322916,1.05833 0.859896,1.05834 0.529167,1.32291 0.264583,1.058337 v 42.994786 l -0.264583,1.05833 -0.529167,1.05833 -0.79375,1.05834 z"
        id="path928-3-7-5-0"
        sodipodi:nodetypes="ccccccccccccc" />
-    <ellipse
-       style="fill:#000000;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
-       id="path10968"
-       cx="69.717712"
-       cy="107.8177"
-       rx="0.92604166"
-       ry="1.984375" />
-    <path
-       style="fill:#000000;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
-       d="m 69.849999,100.54166 1.852083,0.79375 1.5875,1.5875 0.79375,1.85209 v 2.11666 l -0.79375,1.85209 -1.5875,1.5875 -1.852083,0.79375 -2.116667,0 -1.852083,-0.79375 -1.5875,-1.5875 -0.79375,-1.85209 0,-2.11666 0.79375,-1.85208 1.5875,-1.5875 1.852083,-0.79376 z"
-       id="path928-6-5-6"
-       sodipodi:nodetypes="ccccccccccccccccc" />
   </g>
 </svg>
diff --git a/examples/board_clock_7seg/led_colon.py b/examples/board_clock_7seg/led_colon.py
new file mode 100755 (executable)
index 0000000..0316096
--- /dev/null
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+
+import math
+import svg.path
+
+# extract the following from the idiotic header that inkscape puts in the svg:
+#   width="200"
+#   height="400"
+#   viewBox="0 0 52.916666 105.83333"
+scale_x = 200. / 52.916666
+scale_y = -400. / 105.83333
+origin_x = 0.
+origin_y = 400.
+
+# extract below using:
+#   sed -ne 's/.* d=\(.*\)/  \1,/p' <led_colon.svg
+# then reorder segments manually
+paths = [
+  "m 1.0583326,68.791663 1.852083,0.79375 1.5875,1.5875 0.79375,1.85209 v 2.11666 l -0.79375,1.85209 -1.5875,1.5875 -1.852083,0.79375 h -2.116667 l -1.852083,-0.79375 -1.5875,-1.5875 -0.79375,-1.85209 v -2.11666 l 0.79375,-1.85208 1.5875,-1.5875 1.852083,-0.79376 z",
+  "m 1.0583333,26.458334 1.852083,0.79375 1.5875,1.5875 0.79375,1.85209 v 2.11666 l -0.79375,1.85209 -1.5875,1.5875 -1.852083,0.79375 h -2.116667 l -1.852083,-0.79375 -1.5875,-1.5875 -0.7937497,-1.85209 v -2.11666 l 0.7937497,-1.85208 1.5875,-1.5875 1.852083,-0.79376 z",
+]
+
+led_colon = []
+led_colon_ptr = [0]
+slant = math.tan(10. * math.pi / 180.)
+for i in paths:
+  for j in svg.path.parse_path(i):
+    p = j.point(1.)
+    x = round(origin_x + p.real * scale_x, 2)
+    y = round(origin_y + p.imag * scale_y, 2)
+    x += slant * y
+    led_colon.append((x, y))
+  led_colon_ptr.append(len(led_colon))
+
+print(
+  'float led_colon[][2] = {{{0:s}\n}};'.format(
+    ','.join(
+      [f'\n  {{{x:.8f}f, {y:.8f}f}}' for x, y in led_colon]
+    )
+  )
+)
+print(
+  'int led_colon_ptr[] = {{{0:s}}};'.format(
+    ', '.join(
+      [str(i) for i in led_colon_ptr]
+    )
+  )
+)
diff --git a/examples/board_clock_7seg/led_colon.svg b/examples/board_clock_7seg/led_colon.svg
new file mode 100644 (file)
index 0000000..ceadbc9
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   width="200"
+   height="400"
+   viewBox="0 0 52.916666 105.83333"
+   version="1.1"
+   id="svg5"
+   inkscape:version="1.1.2 (1:1.1+202202050950+0a00cf5339)"
+   sodipodi:docname="led_colon.svg"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview7"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     inkscape:document-units="mm"
+     showgrid="true"
+     units="px"
+     width="100px"
+     inkscape:zoom="2.9576318"
+     inkscape:cx="-50.716252"
+     inkscape:cy="207.76758"
+     inkscape:window-width="1920"
+     inkscape:window-height="1009"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1">
+    <inkscape:grid
+       type="xygrid"
+       id="grid824"
+       spacingx="2.6458333"
+       spacingy="2.6458333"
+       empspacing="4" />
+  </sodipodi:namedview>
+  <defs
+     id="defs2" />
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <ellipse
+       style="fill:#ff000f;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
+       id="path10970-5"
+       ry="5.2916627"
+       rx="5.291666"
+       cy="74.083328"
+       cx="7.2448365e-06" />
+    <ellipse
+       style="fill:#ff000f;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
+       id="path10970-6"
+       ry="5.2916627"
+       rx="5.291666"
+       cy="31.749992"
+       cx="5.814325e-06" />
+    <path
+       style="fill:#000000;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
+       d="m 1.0583326,68.791663 1.852083,0.79375 1.5875,1.5875 0.79375,1.85209 v 2.11666 l -0.79375,1.85209 -1.5875,1.5875 -1.852083,0.79375 h -2.116667 l -1.852083,-0.79375 -1.5875,-1.5875 -0.79375,-1.85209 v -2.11666 l 0.79375,-1.85208 1.5875,-1.5875 1.852083,-0.79376 z"
+       id="path928-6-5-6-7"
+       sodipodi:nodetypes="ccccccccccccccccc" />
+    <path
+       style="fill:#000000;fill-opacity:1;stroke-width:0.529167;paint-order:stroke fill markers;stop-color:#000000"
+       d="m 1.0583333,26.458334 1.852083,0.79375 1.5875,1.5875 0.79375,1.85209 v 2.11666 l -0.79375,1.85209 -1.5875,1.5875 -1.852083,0.79375 h -2.116667 l -1.852083,-0.79375 -1.5875,-1.5875 -0.7937497,-1.85209 v -2.11666 l 0.7937497,-1.85208 1.5875,-1.5875 1.852083,-0.79376 z"
+       id="path928-6-5-6-5"
+       sodipodi:nodetypes="ccccccccccccccccc" />
+  </g>
+</svg>