Магнитометр-магнитограф

RN6LJK
Offline
Зарегистрирован: 24.03.2013
Представляю магнитометр-магнитограф созданный как пробный инструмент для дальнейшего развития при построении домашней метеостанции с возможностью индикации состояния магнитного поля земли, что очень важно для метео-зависимых людей к которым отношусь и я сам. Не совсем уверен в правильности выбранного пути, но по другому не получается и технических возможностей в общем-то не так уж и много.  Устройство выполняет мониторинг и фиксацию поведения магнитной стрелки компаса за определенный период.  Я отталкивался от факта, что магнитная стрелка чувствительна к колебаниям магнитного поля земли. Созданный прибор фиксирует на SD карте величины девиации стрелки за каждые 10 сек. За сутки количество измерений составляет 8645. Для отображения результатов на сегодняшний день используется программа на PYTHON, которая считывает из файла измерений данные и строит график. На мой взгляд подход оправдал себя и в дальнейшем после получения от китайских братьев графического дисплея отображение результата автор планирует реализовать в реальном масштабе времени непосредственно на дисплей. Сердцем устройства является электронный магнитный компас HMC 5883L. Компас жестко зафиксирован в пространстве с примерной ориентацией на север. При экспериментах я понял, что датчик в любом случае реагирует на поведение магнитного поля и следовательно, на мой взгляд, положение его в пространстве для данной задачи несущественно. При построении программы пока действует условие, что начальное положение стрелки находится в первом квадранте. Все устройство реализовано на основе Arduino Mega2560. На плате установлен самодельный шилд, на котором распаяны разъем клавиатуры, кнопки управления, разъем питания по min-USB, кнопка сброса и диод 13-го порта. Сама Ардуина закреплена на макетной плате, на которой установлен SD модуль, LCD монитор, разъем для шилда и магнитного компаса, а также выключатель питания LCD. Надо отметить, что дисплей применен не обычный китайский а типа американьский, фирмы Scott Edwardshs, и управляется он всего по одному проводу, просто другого под рукой небыло. Вещь, надо сказать интересная и управляется в принципе как обычный LCD I2C, библиотека для него по крайней мере стандартная SoftwareSerial.h. Часы-календарь реализованы программно, т.к. опять же под рукой нетбыло DS1320. Начальные данные (дата+время) вводятся при каждой перезагрузке или смене  флешки при помощи клавиатуры PS/2. Часики у меня имеют технологическую неточность около 5 минут в сутки, но такая точчность меня вполне устраивает, т.к. файл результата выбирается ежедневно, а устройство как было сказано является испытательным инструментом. Результаты записываются в файл с именем ДДММГГ.txt (день, месяц, год) в виде строк (смотри на картинке) ДД ММ ГГ ЧЧ МН СК НН ТТ ДВ (день, месяц, год, час, минута, секунда, начальный угол стрелки, текущий угол, текущая девиация). Как уже отмечалось выше таких строк за сутки получается 8645. На сегодняшний день результаты отображаются не динамически, а по истечении периода измерения, но это уверен пока. По окончании периода измерения, т.е. суток, устройство останавливается нажатием кнопки START, флешка вынимается и файл переписывается на ПК, затем флешка снова вставляется и с клавитауры вводятся исходные значения день, месяц, год, час, минута и после нажатия <Enter> устройство запускается. Считанный файл обрабатывается программкой на Питоне. При этом из имеющихся 8645 записей формируется 720 координат путем вычисления среднего арифметического за каждые 12 минут. На основе получено массива строится график. Примеры привожу на фото. Должен сказать, что мои данные в принципе повторяют публикуемые данные с сайта http://v-kosmose.com/, но отстают на несколько часов. Скорее всего это связано с географическим положением регистратора. Видимо мне надо еще подумать над тем как правильно обрабатывать результаты и т.д., может кто посоветует дельную мысль, но уже сегодня я вижу, что возмущения магнитного поля мною фиксируются и такую функцию можно добавить в домашнюю метеостанцию, и она не будет лишней,  так как  показывает значение в моей домашней зоне. Для примера привожу полученные мною графики за 4 и 5 марта 2016г.. Картинка с заголовком "Геомагнитный индекс" это данные с сайта. Очень интересным считаю объединить результаты по компасу и атмосферному давлению, но это надеюсь в скором времени реализовать. Кнопка RESET просто инициализирует устройство с новой фиксацией начального положения стрелки, но без изменения даты, время и не прерывая запись в файл. Показываю эскиз схемы, думаю достаточно  понятно, а также скетч для Ардуино и прогу на Питоне.
 
 
001Скетч для Ардуино
002 
003/*
004Мониторинг магнитной стрелки
005v 1.0
00624.02.2016
007Arduino 1.0.5-r2
008Предполагается, что начальное положение стрелки в первом квадранте.
009LCD - Scott Edwardshs
012*/
013 
014 //** SD card attached to SPI bus as follows:
015 //** MOSI - pin 51
016 //** MISO - pin 50
017 //** CLK - pin 52
018 //** CS - pin 53 - отключена, с ней не инициализируется SD - не разбирался
019 //    pinMode(53, OUTPUT);
020//
021 
022 
023#include <SD.h>
024#include <PS2Keyboard.h>
025#include "Wire.h"
026#include "HMC5883L.h"
027#include <SoftwareSerial.h>
028#define rxPin A7
029#define txPin A7
030 
031PS2Keyboard keyboard;
032const int DATA_PIN = 2;
033const int IRQ_PIN = 3;
034File myFile;
035 
036SoftwareSerial MySerial = SoftwareSerial(rxPin,txPin);
037HMC5883L compass;
038 
039volatile long mks100;
040volatile long ms10;
041volatile int cntr;
042long tmillis,tms10=0;
043char flip;
044int id=0;
045char fil[11];
046char cd0='1';
047char cd1='2';
048char cd2='1';
049char cd3='2';
050char cd4='1';
051char cd5='2';
052char cd6='.';
053char cd7='t';
054char cd8='x';
055char cd9='t';
056float raz=0;
057float Mraz=raz;
058int i_start=0;
059float old_heading=0;
060int head = 0;
061int basic_h=0;
062int basic_a=0;
063int start_h=0;
064int dev=0;
065 
066// set pin numbers -start - reset:
067const int buttonPin_start = 28;     // START COMPASS
068const int buttonPin_reset = 36;     // SET DATE-TIME
069 
070int pause=1;
071 
072// переменные для начального задания времени
073int hour=17;
074int min=0;
075int sec=0;
076 
077// переменные для начального задания даты
078 
079int day = 12;
080int mon = 12;
081int yar = 12;
082 
083String st1="0";
084 
085void setup() {
086  keyboard.begin(DATA_PIN,IRQ_PIN);
087  Serial.begin(9600);
088  Wire.begin();
089  delay(1000);
090  digitalWrite(txPin,HIGH);
091  delay(1000);
092  pinMode(txPin,OUTPUT);
093  MySerial.begin(9600);
094  compass = HMC5883L();  // создаем экземпляр HMC5883L библиотеки
095  setupHMC5883L();       // инициализация HMC5883L
096   
097  mks100 = 0; // счетчик сотен микросекунд, переполнение счетчика примерно через 5 суток
098  ms10 = 0;   // счетчик десятков миллисекунд, переполнение счетчика примерно через 16 месяцев
099  cntr = 0;
100  flip = 0;
101 
102 
103  // Включаем нужный нам режим таймера/счетчика - нормальный
104  TCCR2A = 0; //нормальный режим (по умолчанию 1 - ШИМ с коррекцией фазы?)
105  // Предделитель таймера/счетчика настраиваем на 16 -
106  // это позволит "тикать" таймером каждую микросекунду
107  // (при условии, что микроконтроллер работает с
108  // частотой 16.000.000 тактов в секунду)
109  TCCR2B = 2; // 010 - fclk/8 (по умолчанию 100 - fclk/64)
110  //TCCR2B = 7; // 111 - fclk/1024 (по умолчанию 100 - fclk/64)
111  TCNT2=59;//55;
112  TIMSK2 |= (1 << TOIE2);  // разрешаем прерывание таймера/счетчика 2 по переполнению
113fil[0]=cd0;
114fil[1]=cd1;
115fil[2]=cd2;
116fil[3]=cd3;
117fil[4]=cd4;
118fil[5]=cd5;
119fil[6]=cd6;
120fil[7]=cd7;
121fil[8]=cd8;
122fil[9]=cd9;
123   
124 
125    ini_SD();
126    open_SD();
127    LCD_clear();
128    MySerial.print("One moment");
129}
130 
131ISR(TIMER2_OVF_vect) {
132// прежде всего взводим счетчик
133  TCNT2=59;//55;
134// прошли очередные 100 мксек - увеличиваем счетчик сотен микросекунд
135  mks100++;
136//  if(mks100%100==0) ms10++;
137  cntr++;
138// прошли очередные 10 мсек? - увеличиваем счетчик десятков миллисекунд
139  if(cntr>99) {
140    ms10++;
141    cntr = 0;
142  }
143}
144   
145//----------------------------------------------------------------------------
146void loop() {
147 
148// RESET
149 
150 
151 
152  if (digitalRead(buttonPin_reset) == HIGH) { // Установка времени, даты
153    delay(1000);
154    start_h=0;
155    id=0;
156    myFile.close();
157    reset();
158  }
159 
160  if (digitalRead(buttonPin_start) == HIGH) { // Сброс компаса
161      start_h=0;
162      raz=0;
163      Mraz=raz;
164      i_start=0;
165      old_heading=0;
166      head = 0;
167  MySerial.write(0xFE);
168  MySerial.write(0x01);
169  MySerial.write(0x80); 
170  MySerial.print("One moment");
171  MySerial.write(0xFE);
172  MySerial.write(0xC0);
173  MySerial.print("Reset compass");
174      delay(1000);  
175      
176  }
177  
178  // часы запущены
179  if (ms10>tms10) {
180    tmillis = millis();
181    tms10   = ms10;
182  
183    if (tms10%100==0) {
184      flip = !flip;
185    }
186    if (tms10%1000==0) { // выполнение каждые 10 сек   
187 
188      if(sec<50){
189        sec=sec+10;
190        Time_Ind();
191      }
192      else {
193        sec=0;
194        min=min+1;
195          if(min<60){
196            Time_Ind();         
197          }
198          else {
199            sec=0;
200            min=0;
201            hour=hour+1;
202              if(hour<24){
203              Time_Ind();
204              }
205              else{ // смените дату !!!!!
206                day = day+1;
207                hour=0;
208                Time_Ind();
209              
210          
211      }                 
212    }
213  }
214}
215 
216 
217 
218 
219//================================================
220void Time_Ind()
221{
222   
223    if (digitalRead(buttonPin_start) == HIGH) { // Сброс компаса
224    start_h=0;
225      raz=0;
226      Mraz=raz;
227      i_start=0;
228      old_heading=0;
229//      head = 0;
230  MySerial.write(0xFE);
231  MySerial.write(0x01);
232  MySerial.write(0x80); 
233  MySerial.print("One moment");
234  MySerial.write(0xFE);
235  MySerial.write(0xC0);
236  MySerial.print("Reset compass");
237      delay(1000);    
238    }
239//if (sec==0) {    // вывод результата каждую минуту
240   
241 
242  MySerial.write(0xFE);
243  MySerial.write(0x01);
244  MySerial.write(0x80);
245// время
246  if (hour>9 and min<10){
247// час > 10, мин < 10
248  float heading = getHeading();
249MySerial.print(basic_h); // начальное - стартовое положение стрелки
250MySerial.print(" ");
251MySerial.print(head); // текущее полжение стрелки
252MySerial.print(" ");
253MySerial.print(dev); // текущая девиация
254 
255 
256 
257MySerial.write(0xFE);
258MySerial.write(0xC0);
259write_SD();
260 
261 
262              MySerial.print(hour,DEC);
263              MySerial.print(":");
264              MySerial.print("0");
265              MySerial.print(min,DEC);
266}
267if (hour<10 and min>9){
268// час < 10, мин > 10
269  float heading = getHeading();
270MySerial.print(basic_h); // начальное - стартовое положение стрелки
271MySerial.print(" ");
272MySerial.print(head); // текущее полжение стрелки
273MySerial.print(" ");
274MySerial.print(dev); // текущая девиация
275 
276 
277MySerial.write(0xFE);
278MySerial.write(0xC0);
279write_SD();
280               MySerial.print("0");
281               MySerial.print(hour,DEC);
282               MySerial.print(":");
283               MySerial.print(min,DEC);
284}
285if (hour>9 and min>9){
286// час > 10, мин > 10
287  float heading = getHeading();
288MySerial.print(basic_h); // начальное - стартовое положение стрелки
289MySerial.print(" ");
290MySerial.print(head); // текущее полжение стрелки
291MySerial.print(" ");
292MySerial.print(dev); // текущая девиация
293 
294   
295 
296MySerial.write(0xFE);
297MySerial.write(0xC0);
298write_SD();
299               MySerial.print(hour,DEC);
300               MySerial.print(":");
301               MySerial.print(min,DEC);
302}
303if (hour < 10 and min<10){
304// час < 10, мин < 10
305  float heading = getHeading();
306 
307MySerial.print(basic_h); // начальное - стартовое положение стрелки
308MySerial.print(" ");
309MySerial.print(head); // текущее полжение стрелки
310MySerial.print(" ");
311MySerial.print(dev); // текущая девиация
312   
313MySerial.write(0xFE);
314MySerial.write(0xC0);
315write_SD();
316               MySerial.print("0");
317               MySerial.print(hour,DEC);
318               MySerial.print(":");
319               MySerial.print("0");
320               MySerial.print(min,DEC);
321}
322// дата
323if (day < 10 and mon<10){
324               MySerial.print("   ");          
325               MySerial.print("0");
326               MySerial.print(day,DEC);
327               MySerial.print(".");              
328               MySerial.print("0");
329               MySerial.print(mon,DEC);
330               MySerial.print(".");
331               MySerial.println(yar,DEC);             
332}
333if (day < 10 and mon>9){
334               MySerial.print("   ");          
335               MySerial.print("0");
336               MySerial.print(day,DEC);
337               MySerial.print(".");              
338               MySerial.print(mon,DEC);
339               MySerial.print(".");
340               MySerial.println(yar,DEC);             
341}
342 
343if (day > 9 and mon>9){
344               MySerial.print("   ");          
345               MySerial.print(day,DEC);
346               MySerial.print(".");              
347               MySerial.print(mon,DEC);
348               MySerial.print(".");
349               MySerial.println(yar,DEC);             
350}
351if (day > 9 and mon<10){
352               MySerial.print("   ");          
353               MySerial.print(day,DEC);
354               MySerial.print(".");              
355               MySerial.print("0");
356               MySerial.print(mon,DEC);
357               MySerial.print(".");
358               MySerial.println(yar,DEC);             
359}
360}
361//}
362 
363 
364void setupHMC5883L(){
365  // инициализация HMC5883L, и проверка наличия ошибок
366  int error; 
367  error = compass.SetScale(0.88); // чувствительность датчика из диапазона: 0.88, 1.3, 1.9, 2.5, 4.0, 4.7, 5.6, 8.1
368  if(error != 0)
369    LCD_clear();
370  MySerial.println(compass.GetErrorText(error)); // если ошибка, то выводим ее
371  
372  error = compass.SetMeasurementMode(Measurement_Continuous); // установка режима измерений как Continuous (продолжительный)
373  if(error != 0)
374    LCD_clear();
375  MySerial.println(compass.GetErrorText(error)); // если ошибка, то выводим ее
376}
377  
378float getHeading(){
379  // считываем данные с HMC5883L и рассчитываем  направление
380  MagnetometerScaled scaled = compass.ReadScaledAxis(); // получаем масштабированные элементы с датчика
381  float heading = atan2(scaled.YAxis, scaled.XAxis);    // высчитываем направление
382   
383// return heading;
384  // корректируем значения с учетом знаков
385  if(heading < 0) heading += 2*PI;
386  if(heading > 2*PI) heading -= 2*PI;
387 head=heading * RAD_TO_DEG;
388  
389  // вычисление отклонения стрелки
390  if (start_h==0){
391  basic_h=head;     // начальное положение стрелки
392  basic_a=basic_h+180; //при условии 180 >=basic_h>=0
393  start_h=1;
394  }
395   
396 if((basic_h<=180)&&(basic_h>=0)){   //   начальное положение стрелки в секторе 180>=basic_h>=0
397   if ((basic_h>head)&&(head>=0)){   // текущее положение стрелки в секторе basic_h>head>=0
398     dev=(basic_h-head)*(-1);
399   }
400   if ((basic_a>=head)&&(head>=basic_h)){   // текущее положение стрелки в секторе basic_a>=head>=basic_h
401     dev=head-basic_h;
402   }
403   if ((basic_a<head)&&(head<=360)){   // текущее положение стрелки в секторе basic_a<head<=360
404     dev=(basic_h+(360-head))*(-1);
405   }
406  
407 }
408  return heading * RAD_TO_DEG; // переводим радианы в градусы
409}
410//===================================================
411void reset(){
412   
413reset:
414   
415//      Serial.println("reset");
416day:
417st1="0";
418pause = 1;
419    myFile.close();
420    LCD_clear();
421    MySerial.print("DD <Enter>");
422 
423while (pause){        
424  if(keyboard.available()) {
425   char c = (keyboard.read());  // читаем состояние клавиатуры
426//            Serial.print("id="); 
427//         Serial.println(id); 
428   fil[id]=c;
429//   Serial.print(fil[id]);  
430   id=id+1;
431 
432   if (c==PS2_ENTER){
433    id=id-1;
434    goto mon;
435  }
436   String c1 = String (c);
437   String st = String(st1+c1);
438   st1=c1;
439   day=st.toInt();
440//   Serial.print("day  ");   
441//   Serial.println(day);
442     
443MySerial.write(0xFE);
444MySerial.write(0xC0);
445MySerial.print(day);
446 
447  }
448}
449 
450 
451 
452mon: 
453st1="0";
454pause = 1;
455    LCD_clear();
456MySerial.print("MM <Enter>");
457 
458while (pause){
459  if(keyboard.available()) {
460   char c = (keyboard.read());  // читаем состояние клавиатуры
461//               Serial.print("id="); 
462//         Serial.println(id); 
463   fil[id]=c;
464//   Serial.print(fil[id]);  
465   id=id+1;
466   
467   if (c==PS2_ENTER){
468    id=id-1;
469    goto yar;
470  }
471   String c1 = String (c);
472   String st = String(st1+c1);
473   st1=c1;
474   mon=st.toInt();  
475MySerial.write(0xFE);
476MySerial.write(0xC0);
477MySerial.print(mon);
478 
479  }
480}
481 
482 
483yar: 
484st1="0";
485pause = 1;
486    LCD_clear();
487    MySerial.print("YY <Enter>");
488 
489while (pause){
490  if(keyboard.available()) {
491   char c = (keyboard.read());  // читаем состояние клавиатуры
492   fil[id]=c;
493   id=id+1;
494  
495   if (c==PS2_ENTER){
496fil[6]=cd6;
497fil[7]=cd7;
498fil[8]=cd8;
499fil[9]=cd9;
500    goto hour;
501  }
502   String c1 = String (c);
503   String st = String(st1+c1);
504   st1=c1;
505   yar=st.toInt();
506    
507MySerial.write(0xFE);
508MySerial.write(0xC0);
509MySerial.print(yar);
510 
511  }
512}
513 
514hour: 
515st1="0";
516pause = 1;
517    LCD_clear();
518    MySerial.print("HH <Enter>");
519 
520while (pause){
521  if(keyboard.available()) {
522   char c = (keyboard.read());  // читаем состояние клавиатуры
523   if (c==PS2_ENTER){
524    goto min;
525  }
526   String c1 = String (c);
527   String st = String(st1+c1);
528   st1=c1;
529   hour=st.toInt();
530    
531MySerial.write(0xFE);
532MySerial.write(0xC0);
533MySerial.print(hour);
534 
535  }
536}
537 
538min: 
539st1="0";
540pause = 1;
541    LCD_clear();
542    MySerial.print("MM <Enter>");
543 
544while (pause){
545  if(keyboard.available()) {
546   char c = (keyboard.read());  // читаем состояние клавиатуры 
547      if (c==PS2_ENTER){
548      raz=0;
549      Mraz=raz;
550      i_start=0;
551      old_heading=0;
552      head = 0;
553      id=0;
554    ini_SD();
555    open_SD();
556    LCD_clear();
557    MySerial.print("One moment");     
558    return;
559  }
560   String c1 = String (c);
561   String st = String(st1+c1);
562   st1=c1;
563   min=st.toInt();
564MySerial.write(0xFE);
565MySerial.write(0xC0);
566MySerial.print(min);
567 
568  }
569}
570}
571 
572 
573void LCD_clear(){
574  MySerial.write(0xFE);
575  MySerial.write(0x01);
576  MySerial.write(0x80); 
577  MySerial.write(0xFE);
578  MySerial.write(0xC0);
579}
580void ini_SD(){
581    if (!SD.begin(4)) {
582    LCD_clear();
583    MySerial.print("initialization failed!");
584    return;
585  }
586  else
587      LCD_clear();
588    MySerial.print("initialization done");
589      return;
590}
591void open_SD(){
592   
593  // Открываем файл, если есть, то удаляем старый
594  
595  if (SD.exists(fil)) {
596          LCD_clear();
597    MySerial.print("Removing ...");
598    SD.remove(fil);
599 
600  }
601  else {
602              LCD_clear();
603    MySerial.print("doesn't exist.");
604        delay(1000);
605  }
606 
607 
608//========================================================================
609  // Создаем новый файл
610//
611                LCD_clear();
612    MySerial.print("Creating ...");
613  myFile = SD.open(fil, FILE_WRITE);
614  myFile.close();
615 
616 
617//========================================================================
618// Проверяем открывается или нет
619//
620  if (SD.exists(fil)){
621                    LCD_clear();
622    MySerial.print(" exists.");
623 
624  }
625  else {
626                        LCD_clear();
627    MySerial.print(" doesn't exist.");
628                return;
629  }
630 
631  myFile = SD.open(fil, FILE_WRITE);
632              return;
633}
634 
635void write_SD(){
636   
637  if (SD.exists(fil)){
638  }
639  else {
640    LCD_clear();
641    MySerial.print(" doesn't exist.");
642                return;
643  }
644 
645  myFile = SD.open(fil, FILE_WRITE); 
646   
647  if (myFile) {
648myFile.print(day);
649myFile.print(" ");
650myFile.print(mon);
651myFile.print(" ");
652myFile.print(yar);
653//myFile.print(" ");
654myFile.print(" ");
655myFile.print(hour);
656myFile.print(" ");
657myFile.print(min);
658myFile.print(" ");
659myFile.print(sec);
660//myFile.print(" ");
661myFile.print(" ");
662 
663myFile.print(basic_h); // начальное - стартовое положение стрелки
664//myFile.print(" ");
665myFile.print(" ");
666myFile.print(head); // текущее полжение стрелки
667//myFile.print(" ");
668myFile.print(" ");
669myFile.println(dev); // текущая девиация
670    myFile.close();
671  }
672  else {
673        delay(1000);
674  }
675}
676 
677void read_SD(){
678    // re-open the file for reading:
679 
680//
681  myFile = SD.open(fil);
682  if (myFile) {   
683    // read from the file until there's nothing else in it:
684    while (myFile.available()) {
685    }
686                delay(1000);
687    myFile.close();
688        return;
689  } else {
690    // if the file didn't open, print an error:
691        LCD_clear();
692    MySerial.print("error opening SD.");
693        delay(1000);
694  }
695 
696return;
697}

 

 

Программа на Питоне

001# Обработка измерений отклонения магнитной стрелки за период
002 
003 
004from math import *
005from tkinter import *
006 
007f= open('C:/Python_proekt/flash/050316.TXT')  # файл с исходными измерениями
008pp=8 # граница для считывания значения отклонения из исходного файла
009i=0     #  индекс текущей строки string
010ip=0   # счетчик пробелов при разборе string
011dev=[' ',' ',' ',' ']   # массив преобразования значения девиации
012di=0                    # индекс dev
013s_izm=8640     # общее количество измерений
014i_izm=0       # счетчик обработанных измерений
015s_X=720      # количество отображаемых измерений
016k_X=[]          # массив отображаемых измерений   по X
017k_Y_p=[]      # массив отображаемых измерений (+) по Y
018k_Y_m=[]     # массив отображаемых измерений (-)  по Y
019X=0              # индекс k_X
020Y=0              # индекс k_Y_p, k_y_m
021Ydev=0        # девиация по Y берется из файла измерений
022k_M=11       # масштабный коэффициент измерений
023                    # в сутках получается около 8645 измерений в сутки, 1440 минут, отображаем каждую 2-ю минуту = 720
024i_M=0          # счетчик суммы девиации за период k_M
025sum_dev_p =0  # сумма девиации за период k_M (+)
026sum_dev_m =0 # сумма девиации за период k_M (-)
027 
028while True:
029    if i_izm==s_izm:
030        print('Break')
031        break
032    else:
033        if i_izm==0:
034            string=f.readline()
035            string_n=string
036        else:
037            string=f.readline()
038 
039 
040    while True:
041        if string[i]=='\n' :
042            break
043        else:
044            if string[i]==' ':
045                ip=ip+1
046            else:
047                if ip==pp:
048                    dev[di]=string[i]
049                    di=di+1
050                    if ip==(ip+1):
051                        break
052        i=i+1
053 
054 
055    i_izm=i_izm+1
056    i_M=i_M+1
057    Ydev=int(dev[0]+dev[1]+dev[2]+dev[3])
058     
059    if i_M<=k_M:
060        if Ydev>=0:
061            sum_dev_p=sum_dev_p+Ydev
062        else:
063            sum_dev_m=sum_dev_m+Ydev
064    else:
065        k_X.append([1])
066        k_X[X]=X      
067        X=X+1
068        k_Y_p.append([1])
069        k_Y_m.append([1])
070        k_Y_p[Y]=int(sum_dev_p/k_M)
071        k_Y_m[Y]=int((sum_dev_m/k_M)*(-1))
072        Y=Y+1
073        sum_dev_p =0  # сумма девиации за период k_M (+)
074        sum_dev_m =0 # сумма девиации за период k_M (-)   
075        i_M=0
076 
077    i=0
078    ip=0
079    dev=[' ',' ',' ',' ']
080    di=0
081 
082 
083 
084#   В Ы В О Д      Г Р А Ф И К А
085 
086X_s=10          # отступ слева по оси Х - координата нуля
087Y_s=200      # координата нуля по Y
088D_X=0.01    # масштабный коэффициент по Х
089D_Y=10       # масштабный коэффициент по Y
090Y_P_p=17   # граница по Y выхода в красный
091Y_0=0         #  левый верхний Y
092sm_X=100  # смещение по X от последнего измерения до конца оси X
093kd_Y=2       # коэффициент деления оси Y
094line_canv=2 # толщина линии оси координат
095line_izm=2  # толщина линии отображения измерения
096 
097 
098root = Tk()
099 
100canv = Canvas(root, width = (s_X+sm_X), height = 400, bg = "white")         # окно
101canv.create_line(X_s,Y_s*kd_Y,X_s,Y_0,width=line_canv,arrow=LAST)      # координата Y
102canv.create_line(X_s,Y_s,(s_X+sm_X),Y_s,width=line_canv,arrow=LAST) # координата X
103canv.create_text((s_X+sm_X-45), Y_s+20, text ='Время-минуты ', fill="purple", font=("Courier New CYR", "10"))
104canv.create_text((X_s+80), Y_0+10, text ='Отклонение - градусы ', fill="purple", font=("Courier New CYR", "10"))
105canv.create_text((X_s+400), Y_0+10, text ='Отклонение магнитной стрелки за период 1440 минут ', fill="black", font=("Courier New CYR", "10"))
106canv.create_line((X_s-3),(Y_s-170),(X_s+3),(Y_s-170),width=line_canv)
107canv.create_line((X_s-3),(Y_s+170),(X_s+3),(Y_s+170),width=line_canv)
108canv.create_text((X_s+17), (Y_s-170), text ='+17 ', fill="purple", font=("Courier New CYR", "10"))
109canv.create_text((X_s+17), (Y_s+170), text ='-17 ', fill="purple", font=("Courier New CYR", "10"))
110canv.create_line((s_X+X_s),Y_s-3,(s_X+X_s),Y_s+3,width=line_canv)
111canv.create_text((s_X+X_s+35),Y_s-10,text='1440 min',fill="purple", font=("Courier New CYR", "10"))
112canv.create_text((X_s+400), Y_s+185, text =string_n, fill="black", font=("Courier New CYR", "10"))
113canv.create_text((X_s+400), Y_s+199, text =string, fill="black", font=("Courier New CYR", "10"))
114 
115 
116J=0     # индекс выводимых результатов
117 
118for J in range(X):
119     
120    if k_Y_p[J]<=Y_P_p:   #  проверка на положительное красное
121        canv.create_line([[X_s+k_X[J]+D_X*J],Y_s],[[X_s+k_X[J]+D_X*J],[Y_s-k_Y_p[J]*D_Y]],fill="blue",width=line_izm)
122    else:
123        canv.create_line([[X_s+k_X[J]+D_X*J],Y_s],[[X_s+k_X[J]+D_X*J],[Y_P_p]],fill="red",width=line_izm)        
124 
125 
126    if k_Y_m[J]<=Y_P_p:  #  проверка на отрицательное красное
127        canv.create_line([[X_s+k_X[J]+D_X*J],Y_s],[[X_s+k_X[J]+D_X*J],[Y_s+k_Y_m[J]*D_Y]],fill="green",width=line_izm)
128    else:
129        canv.create_line([[X_s+k_X[J]+D_X*J],Y_s],[[X_s+k_X[J]+D_X*J],[Y_s+Y_P_p*D_Y]],fill="red",width=line_izm)
130         
131 
132canv.pack()
133root.mainloop()
134f.close()

 

marc1961
Offline
Зарегистрирован: 06.10.2018

штука интересная можно ей искать не однородности земли к примеру и грунтовые воды в том числе... будет время попробую повторить ну может у автора есть какие то наработки

RN6LJK
Offline
Зарегистрирован: 24.03.2013

Честно говоря я забросил этот проект. Не оправдались ожидания от результата.

IvanKor
Offline
Зарегистрирован: 30.04.2018

Вот

https://github.com/IvanKor/geomagnetic-magnetometer

гораздо круче, чувствительность не хуже чем у протонного магнитометра

Если нарастить магнитную антенну и сделать дифсистему то можно и грунтовые воды в том числе... искать ...

sva_khv
Offline
Зарегистрирован: 19.12.2016

RN6LJK пишет:

Честно говоря я забросил этот проект. Не оправдались ожидания от результата.

А можно подробнее что не понравилось?

Идея то интересная. Я бы себе на устройство к графикам радиации и давления за сутки такой график добавил бы.

RN6LJK
Offline
Зарегистрирован: 24.03.2013

Просто не хватило терпения и усидчивости. Надо было глубже погрузиться в предметную область, а хотелось быстрого результата, но видимо не в этом случае. Уверен, что этот магнитометр имеет большой запас возможностей, но надо серьезнее подойти к решению задачи. По сути я соорудил болванку, а вот до правильной методики измерений не смог довести. Тема сложная и требует определенных знаний, которыми я, к сожалению, не владею. 

Dushev
Offline
Зарегистрирован: 29.04.2018
Здравствуйте! Интересные проекты!
IvanKor, пожалуйста, расскажите  об антенне вашего устройства. какие ферриты вы использовали, размеры, есть ли обмотки ...
RN6LJK
Offline
Зарегистрирован: 24.03.2013

Добрый день.

Позвольте спросить о какой антенне идет речь?

 

IvanKor
Offline
Зарегистрирован: 30.04.2018

Dushev пишет:

IvanKor, пожалуйста, расскажите  об антенне вашего устройства. какие ферриты вы использовали, размеры, есть ли обмотки ...

ферриты М400 от антенн старых радиоприемников, длиной 200 мм и диаметром 10 мм

стержни необходимо тщательно размагнитить

обмоток нет, весь эффект достигается как там показано, за счет фокусировки МП на крошечный датчик который внутри чипа.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

IvanKor пишет:

ферриты М400 от антенн старых радиоприемников, длиной 200 мм и диаметром 10 мм

стержни необходимо тщательно размагнитить

Ты каданить видел намагниченный М400 живьём? 

svm
Offline
Зарегистрирован: 06.11.2016

DetSimen пишет:

Ты каданить видел намагниченный М400 живьём? 

Ежели с китаю, то могет. У них и медь магнитится.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

svm пишет:

DetSimen пишет:

Ты каданить видел намагниченный М400 живьём? 

Ежели с китаю, то могет. У них и медь магнитится.

У него написано  "от антенн старых радиоприемников".  Не думаю, что китайских, ибо размер самый что ни на есть советский. 200х10

IvanKor
Offline
Зарегистрирован: 30.04.2018

DetSimen пишет:

Ты каданить видел намагниченный М400 живьём? 

ты видать никогда их не видал как и мой

geomagnetic-magnetometer

https://github.com/IvanKor/geomagnetic-magnetometer

где есть фотка, там два круглых стержня по 200 мм с обмотками.

обмотки я хотел использовать для компенсации земного поля но это оказалоссь весьма непростой задачей при измерениях меньше единицы нано теслы. Очень высокие требования к стабильности тока ... меньше пико ампера.

так вот, запомни, в старых приемниках такие антенны расположены недалеко от магнитов динамиков и ВСЕГДА НАМАГНИЧЕНЫ !

выяснить при помощи компаса намагничены или нет стержни может каждый

если стержень размагниченный и его расположить по вектору МП (наклонный) Земли то ...дальше сами,

ибо мине с хамами  грить ниочем :D

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ха черточка ха черточка ха

Dushev
Offline
Зарегистрирован: 29.04.2018

IvanKor, спасибо за быстрый ответ! 

Что это и  для чего нужна маленькая печатная плата ? 
 

 

 

Dushev
Offline
Зарегистрирован: 29.04.2018

 

RN6LJK пишет:

Добрый день.

Позвольте спросить о какой антенне идет речь?

 

https://github.com/IvanKor/geomagnetic-magnetometer

IvanKor
Offline
Зарегистрирован: 30.04.2018

Dushev пишет:
Что это и  для чего нужна маленькая печатная плата ?

это модуль Bluetooth для передачи на основной комп результата измерений

b707
Offline
Зарегистрирован: 26.05.2017

IvanKor пишет:

обмоток нет, весь эффект достигается как там показано, за счет фокусировки МП на крошечный датчик который внутри чипа.

Думаю. если стержни не "размагничивать" - графики не изменятся, там же относительные величины. а не абсолютные.

интересно, а если стержни вовсе выкинуть - хоть что-нибудь изменится?

 

IvanKor
Offline
Зарегистрирован: 30.04.2018

b707 пишет:

Думаю. если стержни не "размагничивать" - графики не изменятся, там же относительные величины. а не абсолютные.

Измеряется абсолютная величина горизонтальной составляющей МП Земли при размещении антенны восток-запад. Путем юстировки (незначительных поворотов) антенны в горизонтальной плоскости добиваемся показаний близких к нулю.   Если это не сделать прибор уйдет в зашкал.

b707 пишет:

интересно, а если стержни вовсе выкинуть - хоть что-нибудь изменится?

Получите чувствительность обыкновенного электронного компаса вместо ~ 1 nT и как следствие не сможете наблюдать вариации МП Земли типа как здесь http://geodata.izmiran.ru/  Собственно при геомагнитных бурях я сверялся с показаниями этого сайта.

 

Denev
Offline
Зарегистрирован: 19.12.2019

Оба проекта http://arduino.ru/forum/proekty/magnitometr-magnitograf#comment-form и этот https://github.com/IvanKor/geomagn-magnetometer очень хороши в идее. Я не видел ничего подобного в интернете. Я рад, что их авторы отвечают на сообщения. Проекты были опубликованы давно. Магнитометр HMC 5983 больше не производится. Неясно, может ли его аналог HMC 5883L быть использован в проекте. Возможно, есть различия в их характеристиках и в том, как они связаны. Буду очень признателен авторам проекта за разъяснение этого важного вопроса. Я решил воссоздать оба проекта. Тот, что с Arduino UNO, не очень ясно, как защищены шесть ферритов. Может ли какая-нибудь картина быть просто о том, как феррит прикреплен к чипу магнитометра? Еще одна вещь, которая не была объяснена, состоит в том, почему, поскольку в ее коде для Arduino UNO есть bluetotch, его использование не включено? Также нет строкового кода. Для проекта, реализованного с помощью Arduino MEGA, нет антенной схемы. Авторы могут дать один? Заранее спасибо

RN6LJK
Offline
Зарегистрирован: 24.03.2013

Буду рад помочь. Уверен, если дополнить мой проект антенной из https://github.com/IvanKor/geomagnetic-magnetometer то получится интересное продолжение. Правда давно это все было реализовано, но материалы где то остались. 

Denev
Offline
Зарегистрирован: 19.12.2019

Я хотел бы спросить автора проекта на основе Arduino MEGA, что именно использовал модуль SD-карты. Не ясно, для большой или маленькой карты памяти. И какая антенна использовалась в этом проекте? Даже простая схема антенны отсутствует. Я спрашиваю автора, не мешает ли ему поставить одну картинку и диаграмму. Я буду ему очень благодарен. Я решил воспроизвести этот проект.

RN6LJK
Offline
Зарегистрирован: 24.03.2013

Модуль для большой SD, не для MicroSD. Антенны никакой нет, поэтому и бросил т.к. никто тогда мне не подсказал про антенну, а сам просто забросил проект, хотя долго - несколько месяцев собирал статистику. Появились другие проекты.

Denev
Offline
Зарегистрирован: 19.12.2019

Вы собираете данные на карту памяти, но не ясно, какой программой вы обрабатываете собранную информацию  впоследствии. Это важно для того, чтобы получить необходимые графики из этих данных. У вас есть такая программа? Что касается антенны, я спроектирую и опубликую здесь. Вопрос о моделях магнитометров и их взаимозаменяемости является важным. Можно ли заменить HMC 5983 на HMC 5883L???х Первый больше не производится. И еще одна вещь. Добавления в проекте часов реального времени RTC  может оптимизировать проект, и я мог бы развивать его дальше, поскольку я инженер и программист. Я считаю ети два проекта http://arduino.ru/forum/proekty/magnitometr-magnitograf#comment-form и https://github.com/IvanKor/geomagn-magnetometer очень важными, так как большинство применений микросхем магнитометра предназначены для измерения земное поле но куда важнее скорость, с которой меняется это поле. Я заинтересован в поиске зоны аномалий в области земной территории. Я буду рад разработать оба проекта http://arduino.ru/forum/proekty/magnitometr-magnitograf#comment-form и https://github.com/IvanKor/geomagn-magnetometer, для которых мне нужны ответы на мои вопросы спросены выше. Спасибо за быстрые ответы.

b707
Offline
Зарегистрирован: 26.05.2017

Denev пишет:

я мог бы развивать его дальше, поскольку я инженер и программист.

судя по вашим вопросам, в этом есть большие сомнения....

Цитата:
Вы собираете данные на карту памяти, но не ясно, какой программой вы обрабатываете собранную информацию  впоследствии.

странно слышать такой вопрос от "инженера и программиста". У вас есть файл с точками, программ для построения графиков - просто море. Начните с Экселя

Цитата:
Добавления в проекте часов реального времени RTC  может оптимизировать проект,

ну так добавляйте... Или вы хотите, чтобы это сделали для вас авторы? - они выложили проекты, дальше кто угодно может их развивать по собственному вкусу...

 

PS - не сочтите за наезд, но уж больно забавный контраст между заявлениями "я-инженер"  "хочу развивать проекты" и наивными вопросами на уровне школьника

 

 

Denev
Offline
Зарегистрирован: 19.12.2019

Это правда, что я не прочитал все написанное авторами с достаточной тщательностью (поэтому позже я делал это несколько раз). Тогда я просто увидел, что там есть файл Python. Вы правы И еще одна вещь. Я не ленивый и не жду другой работы. Конечно, я инженер и программист. Вопросы их вопросы. Они не бьют вопрос. Наивный или не проявляющий особого живого интереса. Одно можно сказать наверняка, эти типы проектов чрезвычайно интересны. Даже для не инженеров и не программистов.

b707
Offline
Зарегистрирован: 26.05.2017

Denev - вы свои сообщения через Гугль переводчик пишете?

RN6LJK
Offline
Зарегистрирован: 24.03.2013

Данные собираются на карту и обрабатываются на Питоне. Все это указано выше. В проекте применен HMC 5883L. Часы можно добавить, не вижу проблем. Касательно антенны я уже писал. 

Denev
Offline
Зарегистрирован: 19.12.2019

Я прошу прощения, но русский не мой родной язык. Переводчик Google предназначен для использования. Я прошу прощения за использование этого. У меня есть обязанности, ответственность и приверженность только моему родному языку. Как бы вы написали вопрос на португальском форуме?

RN6LJK
Offline
Зарегистрирован: 24.03.2013

Какие трудности вы испытываете при повторении этого проекта?

b707
Offline
Зарегистрирован: 26.05.2017

Denev пишет:

 Как бы вы написали вопрос на португальском форуме?

hablo espanol un poco, claro que potugues no es espanol :)))

 

IvanKor
Offline
Зарегистрирован: 30.04.2018

Denev пишет:
Можно ли заменить HMC 5983 на HMC 5883L???х Первый больше не производится.
Странно, но производитель утверждает что HMC 5883L тоже не производится https://aerospace.honeywell.com/content/dam/aero/en-us/documents/learn/products/sensors/technical-articles/MagneticSensorProductLineRoHsComplianceStrategy_ta.pdf однако нет ни малейших проблем купить HMC5983 например здесь https://best.aliexpress.com

HMC 5883L более старый чип и естественнно хуже HMC 5983, чем именно хуже всегда можно прочесть в описании на эти чипы.

 

Denev пишет:
Я заинтересован в поиске зоны аномалий в области земной территории.
Собственно свой проект я делал именно для этих целей, но потом отвлекся на другой и к этому потерял интерес. По этой причине и выложил оригинальную конструкцию антенны которую больше никто не использовал и не описывал.

Для поиска аномалий необходимо проделать весьма большую работу, намного большую чем просто этот магнитометр. Чувствительность всегда можно увеличить еще как минимум на два порядка, т.е. до ~ 0.01 nT что более чем достаточно для поиска аномалий.

Даже при нынешних ~ 1 nT магнитометр фиксирует проезжающие легковые авто за ~60 метров от антенны

RN6LJK
Offline
Зарегистрирован: 24.03.2013

Полностью согласен с вами коллега. Для развития такого проекта требуются значительные усилия, которые в итоге могут и не привести к ожидаемому результату.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

RN6LJK пишет:

Для развития такого проекта требуются значительные усилия, которые в итоге могут и не привести к ожидаемому результату.

Если физику в школе прогуливать, то, таки, да. 

marc1961
Offline
Зарегистрирован: 06.10.2018

тут не одна физика тут и материаловедение и химия в том числе