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

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 просто инициализирует устройство с новой фиксацией начального положения стрелки, но без изменения даты, время и не прерывая запись в файл. Показываю эскиз схемы, думаю достаточно  понятно, а также скетч для Ардуино и прогу на Питоне.
 
 
Скетч для Ардуино

/*
Мониторинг магнитной стрелки
v 1.0
24.02.2016
Arduino 1.0.5-r2
Предполагается, что начальное положение стрелки в первом квадранте.
LCD - Scott Edwardshs 
http://www.seetron.com/products.html
http://elabz.com/serial-oled-display-and-arduino/
*/

 //** SD card attached to SPI bus as follows:
 //** MOSI - pin 51
 //** MISO - pin 50
 //** CLK - pin 52
 //** CS - pin 53 - отключена, с ней не инициализируется SD - не разбирался
 //    pinMode(53, OUTPUT); 
//


#include <SD.h>
#include <PS2Keyboard.h>
#include "Wire.h"
#include "HMC5883L.h"
#include <SoftwareSerial.h>
#define rxPin A7
#define txPin A7

PS2Keyboard keyboard;
const int DATA_PIN = 2;
const int IRQ_PIN = 3;
File myFile;

SoftwareSerial MySerial = SoftwareSerial(rxPin,txPin);
HMC5883L compass;

volatile long mks100;
volatile long ms10;
volatile int cntr;
long tmillis,tms10=0;
char flip;
int id=0;
char fil[11];
char cd0='1';
char cd1='2';
char cd2='1';
char cd3='2';
char cd4='1';
char cd5='2';
char cd6='.';
char cd7='t';
char cd8='x';
char cd9='t';
float raz=0;
float Mraz=raz;
int i_start=0;
float old_heading=0;
int head = 0; 
int basic_h=0;
int basic_a=0;
int start_h=0;
int dev=0;

// set pin numbers -start - reset:
const int buttonPin_start = 28;     // START COMPASS
const int buttonPin_reset = 36;     // SET DATE-TIME

int pause=1;

// переменные для начального задания времени
int hour=17;
int min=0;
int sec=0;

// переменные для начального задания даты

int day = 12;
int mon = 12;
int yar = 12;

String st1="0";

void setup() {
  keyboard.begin(DATA_PIN,IRQ_PIN);
  Serial.begin(9600);
  Wire.begin();
  delay(1000);
  digitalWrite(txPin,HIGH);
  delay(1000);
  pinMode(txPin,OUTPUT);
  MySerial.begin(9600);
  compass = HMC5883L();  // создаем экземпляр HMC5883L библиотеки
  setupHMC5883L();       // инициализация HMC5883L
  
  mks100 = 0; // счетчик сотен микросекунд, переполнение счетчика примерно через 5 суток
  ms10 = 0;   // счетчик десятков миллисекунд, переполнение счетчика примерно через 16 месяцев
  cntr = 0;
  flip = 0;


  // Включаем нужный нам режим таймера/счетчика - нормальный
  TCCR2A = 0; //нормальный режим (по умолчанию 1 - ШИМ с коррекцией фазы?)
  // Предделитель таймера/счетчика настраиваем на 16 -
  // это позволит "тикать" таймером каждую микросекунду
  // (при условии, что микроконтроллер работает с
  // частотой 16.000.000 тактов в секунду)
  TCCR2B = 2; // 010 - fclk/8 (по умолчанию 100 - fclk/64)
  //TCCR2B = 7; // 111 - fclk/1024 (по умолчанию 100 - fclk/64)
  TCNT2=59;//55;
  TIMSK2 |= (1 << TOIE2);  // разрешаем прерывание таймера/счетчика 2 по переполнению 
fil[0]=cd0;
fil[1]=cd1;
fil[2]=cd2;
fil[3]=cd3;
fil[4]=cd4;
fil[5]=cd5;
fil[6]=cd6;
fil[7]=cd7;
fil[8]=cd8;
fil[9]=cd9;
  

    ini_SD();
    open_SD();
    LCD_clear();
    MySerial.print("One moment");
} 

ISR(TIMER2_OVF_vect) {
// прежде всего взводим счетчик
  TCNT2=59;//55;
// прошли очередные 100 мксек - увеличиваем счетчик сотен микросекунд
  mks100++;
//  if(mks100%100==0) ms10++;
  cntr++;
// прошли очередные 10 мсек? - увеличиваем счетчик десятков миллисекунд
  if(cntr>99) {
    ms10++;
    cntr = 0;
  }
}
  
//----------------------------------------------------------------------------
void loop() {

// RESET



  if (digitalRead(buttonPin_reset) == HIGH) { // Установка времени, даты
    delay(1000);
    start_h=0;
    id=0;
    myFile.close();
    reset(); 
  }

  if (digitalRead(buttonPin_start) == HIGH) { // Сброс компаса
      start_h=0;
      raz=0;
      Mraz=raz;
      i_start=0;
      old_heading=0;
      head = 0; 
  MySerial.write(0xFE);
  MySerial.write(0x01);
  MySerial.write(0x80);  
  MySerial.print("One moment");
  MySerial.write(0xFE);
  MySerial.write(0xC0);
  MySerial.print("Reset compass");
      delay(1000);   
     
  }
 
  // часы запущены
  if (ms10>tms10) {
    tmillis = millis();
    tms10   = ms10;
 
    if (tms10%100==0) {
      flip = !flip;
    }
    if (tms10%1000==0) { // выполнение каждые 10 сек    

      if(sec<50){
        sec=sec+10;
        Time_Ind();
      }
      else {
        sec=0;
        min=min+1;
          if(min<60){
            Time_Ind();          
          }
          else {
            sec=0;
            min=0;
            hour=hour+1;
              if(hour<24){
              Time_Ind();
              }
              else{ // смените дату !!!!!
                day = day+1;
                hour=0;
                Time_Ind();
              }  
          }  
      }                  
    }
  }
}




//================================================
void Time_Ind()
{
  
    if (digitalRead(buttonPin_start) == HIGH) { // Сброс компаса
    start_h=0;
      raz=0;
      Mraz=raz;
      i_start=0;
      old_heading=0;
//      head = 0; 
  MySerial.write(0xFE);
  MySerial.write(0x01);
  MySerial.write(0x80);  
  MySerial.print("One moment");
  MySerial.write(0xFE);
  MySerial.write(0xC0);
  MySerial.print("Reset compass");
      delay(1000);     
    }
//if (sec==0) {    // вывод результата каждую минуту
  

  MySerial.write(0xFE);
  MySerial.write(0x01);
  MySerial.write(0x80);
// время
  if (hour>9 and min<10){
// час > 10, мин < 10
  float heading = getHeading();
MySerial.print(basic_h); // начальное - стартовое положение стрелки
MySerial.print(" ");
MySerial.print(head); // текущее полжение стрелки
MySerial.print(" ");
MySerial.print(dev); // текущая девиация



MySerial.write(0xFE);
MySerial.write(0xC0);
write_SD();


              MySerial.print(hour,DEC);
              MySerial.print(":");
              MySerial.print("0");
              MySerial.print(min,DEC);
}
if (hour<10 and min>9){
// час < 10, мин > 10
  float heading = getHeading();
MySerial.print(basic_h); // начальное - стартовое положение стрелки
MySerial.print(" ");
MySerial.print(head); // текущее полжение стрелки
MySerial.print(" ");
MySerial.print(dev); // текущая девиация


MySerial.write(0xFE);
MySerial.write(0xC0);
write_SD();
               MySerial.print("0");
               MySerial.print(hour,DEC);
               MySerial.print(":");
               MySerial.print(min,DEC);
}
if (hour>9 and min>9){
// час > 10, мин > 10
  float heading = getHeading();
MySerial.print(basic_h); // начальное - стартовое положение стрелки
MySerial.print(" ");
MySerial.print(head); // текущее полжение стрелки
MySerial.print(" ");
MySerial.print(dev); // текущая девиация

  

MySerial.write(0xFE);
MySerial.write(0xC0);
write_SD();
               MySerial.print(hour,DEC);
               MySerial.print(":");
               MySerial.print(min,DEC);
}
if (hour < 10 and min<10){
// час < 10, мин < 10
  float heading = getHeading();

MySerial.print(basic_h); // начальное - стартовое положение стрелки
MySerial.print(" ");
MySerial.print(head); // текущее полжение стрелки
MySerial.print(" ");
MySerial.print(dev); // текущая девиация
  
MySerial.write(0xFE);
MySerial.write(0xC0);
write_SD();
               MySerial.print("0");
               MySerial.print(hour,DEC);
               MySerial.print(":");
               MySerial.print("0");
               MySerial.print(min,DEC);
}
// дата
if (day < 10 and mon<10){
               MySerial.print("   ");           
               MySerial.print("0");
               MySerial.print(day,DEC);
               MySerial.print(".");               
               MySerial.print("0");
               MySerial.print(mon,DEC);
               MySerial.print(".");
               MySerial.println(yar,DEC);              
}
if (day < 10 and mon>9){
               MySerial.print("   ");           
               MySerial.print("0");
               MySerial.print(day,DEC);
               MySerial.print(".");               
               MySerial.print(mon,DEC);
               MySerial.print(".");
               MySerial.println(yar,DEC);              
}

if (day > 9 and mon>9){
               MySerial.print("   ");           
               MySerial.print(day,DEC);
               MySerial.print(".");               
               MySerial.print(mon,DEC);
               MySerial.print(".");
               MySerial.println(yar,DEC);              
}
if (day > 9 and mon<10){
               MySerial.print("   ");           
               MySerial.print(day,DEC);
               MySerial.print(".");               
               MySerial.print("0");
               MySerial.print(mon,DEC);
               MySerial.print(".");
               MySerial.println(yar,DEC);              
}
}
//}


void setupHMC5883L(){
  // инициализация HMC5883L, и проверка наличия ошибок
  int error;  
  error = compass.SetScale(0.88); // чувствительность датчика из диапазона: 0.88, 1.3, 1.9, 2.5, 4.0, 4.7, 5.6, 8.1
  if(error != 0) 
    LCD_clear();
  MySerial.println(compass.GetErrorText(error)); // если ошибка, то выводим ее
 
  error = compass.SetMeasurementMode(Measurement_Continuous); // установка режима измерений как Continuous (продолжительный)
  if(error != 0) 
    LCD_clear();
  MySerial.println(compass.GetErrorText(error)); // если ошибка, то выводим ее
}
 
float getHeading(){
  // считываем данные с HMC5883L и рассчитываем  направление
  MagnetometerScaled scaled = compass.ReadScaledAxis(); // получаем масштабированные элементы с датчика
  float heading = atan2(scaled.YAxis, scaled.XAxis);    // высчитываем направление
  
// return heading;
  // корректируем значения с учетом знаков
  if(heading < 0) heading += 2*PI;
  if(heading > 2*PI) heading -= 2*PI;
 head=heading * RAD_TO_DEG;
 
  // вычисление отклонения стрелки 
  if (start_h==0){
  basic_h=head;     // начальное положение стрелки
  basic_a=basic_h+180; //при условии 180 >=basic_h>=0
  start_h=1;
  }
  
 if((basic_h<=180)&&(basic_h>=0)){   //   начальное положение стрелки в секторе 180>=basic_h>=0
   if ((basic_h>head)&&(head>=0)){   // текущее положение стрелки в секторе basic_h>head>=0
     dev=(basic_h-head)*(-1);
   }
   if ((basic_a>=head)&&(head>=basic_h)){   // текущее положение стрелки в секторе basic_a>=head>=basic_h
     dev=head-basic_h;
   }
   if ((basic_a<head)&&(head<=360)){   // текущее положение стрелки в секторе basic_a<head<=360
     dev=(basic_h+(360-head))*(-1);
   }
 
 }
  return heading * RAD_TO_DEG; // переводим радианы в градусы
}
//===================================================
void reset(){
  
reset:
  
//      Serial.println("reset");
day:
st1="0";
pause = 1;
    myFile.close();
    LCD_clear();
    MySerial.print("DD <Enter>");

while (pause){         
  if(keyboard.available()) {
   char c = (keyboard.read());  // читаем состояние клавиатуры
//            Serial.print("id=");  
//         Serial.println(id);  
   fil[id]=c;
//   Serial.print(fil[id]);   
   id=id+1;

   if (c==PS2_ENTER){
    id=id-1;
    goto mon;
  } 
   String c1 = String (c);
   String st = String(st1+c1);
   st1=c1;
   day=st.toInt();
//   Serial.print("day  ");    
//   Serial.println(day); 
    
MySerial.write(0xFE);
MySerial.write(0xC0);
MySerial.print(day);

  }
}



mon:  
st1="0";
pause = 1;
    LCD_clear();
MySerial.print("MM <Enter>");

while (pause){
  if(keyboard.available()) {
   char c = (keyboard.read());  // читаем состояние клавиатуры
//               Serial.print("id=");  
//         Serial.println(id);  
   fil[id]=c;
//   Serial.print(fil[id]);   
   id=id+1;
  
   if (c==PS2_ENTER){
    id=id-1;
    goto yar;
  } 
   String c1 = String (c);
   String st = String(st1+c1);
   st1=c1;
   mon=st.toInt();   
MySerial.write(0xFE);
MySerial.write(0xC0);
MySerial.print(mon); 

  }
}


yar:  
st1="0";
pause = 1;
    LCD_clear();
    MySerial.print("YY <Enter>");

while (pause){
  if(keyboard.available()) {
   char c = (keyboard.read());  // читаем состояние клавиатуры
   fil[id]=c;
   id=id+1;
 
   if (c==PS2_ENTER){
fil[6]=cd6;
fil[7]=cd7;
fil[8]=cd8;
fil[9]=cd9;
    goto hour;
  } 
   String c1 = String (c);
   String st = String(st1+c1);
   st1=c1;
   yar=st.toInt();
   
MySerial.write(0xFE);
MySerial.write(0xC0);
MySerial.print(yar); 

  }
}

hour:  
st1="0";
pause = 1;
    LCD_clear();
    MySerial.print("HH <Enter>");

while (pause){
  if(keyboard.available()) {
   char c = (keyboard.read());  // читаем состояние клавиатуры
   if (c==PS2_ENTER){
    goto min;
  } 
   String c1 = String (c);
   String st = String(st1+c1);
   st1=c1;
   hour=st.toInt();
   
MySerial.write(0xFE);
MySerial.write(0xC0);
MySerial.print(hour); 

  }
}

min:  
st1="0";
pause = 1;
    LCD_clear();
    MySerial.print("MM <Enter>");

while (pause){
  if(keyboard.available()) {
   char c = (keyboard.read());  // читаем состояние клавиатуры  
      if (c==PS2_ENTER){
      raz=0;
      Mraz=raz;
      i_start=0;
      old_heading=0;
      head = 0; 
      id=0;
    ini_SD();
    open_SD();
    LCD_clear();
    MySerial.print("One moment");      
    return;
  } 
   String c1 = String (c);
   String st = String(st1+c1);
   st1=c1;
   min=st.toInt();
MySerial.write(0xFE);
MySerial.write(0xC0);
MySerial.print(min); 

  }
}
}


void LCD_clear(){
  MySerial.write(0xFE);
  MySerial.write(0x01);
  MySerial.write(0x80);  
  MySerial.write(0xFE);
  MySerial.write(0xC0);
}
void ini_SD(){
    if (!SD.begin(4)) {
    LCD_clear();
    MySerial.print("initialization failed!");
    return;
  }
  else 
      LCD_clear();
    MySerial.print("initialization done");
      return;
}
void open_SD(){
  
  // Открываем файл, если есть, то удаляем старый
 
  if (SD.exists(fil)) {
          LCD_clear();
    MySerial.print("Removing ...");
    SD.remove(fil);

  }
  else {
              LCD_clear();
    MySerial.print("doesn't exist.");
        delay(1000);
  }


//========================================================================
  // Создаем новый файл
// 
                LCD_clear();
    MySerial.print("Creating ...");
  myFile = SD.open(fil, FILE_WRITE);
  myFile.close();


//========================================================================
// Проверяем открывается или нет
// 
  if (SD.exists(fil)){ 
                    LCD_clear();
    MySerial.print(" exists.");

  }
  else {
                        LCD_clear();
    MySerial.print(" doesn't exist.");
                return;
  }

  myFile = SD.open(fil, FILE_WRITE);
              return;
}

void write_SD(){ 
  
  if (SD.exists(fil)){ 
  }
  else {
    LCD_clear();
    MySerial.print(" doesn't exist.");
                return;
  }

  myFile = SD.open(fil, FILE_WRITE);  
  
  if (myFile) {
myFile.print(day);
myFile.print(" ");
myFile.print(mon);
myFile.print(" ");
myFile.print(yar);
//myFile.print(" ");
myFile.print(" ");
myFile.print(hour);
myFile.print(" ");
myFile.print(min);
myFile.print(" ");
myFile.print(sec);
//myFile.print(" ");
myFile.print(" ");

myFile.print(basic_h); // начальное - стартовое положение стрелки
//myFile.print(" ");
myFile.print(" ");
myFile.print(head); // текущее полжение стрелки
//myFile.print(" ");
myFile.print(" ");
myFile.println(dev); // текущая девиация
    myFile.close();
  } 
  else {
        delay(1000);
  }
}

void read_SD(){
    // re-open the file for reading:

// 
  myFile = SD.open(fil);
  if (myFile) {    
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
    }
                delay(1000);
    myFile.close();
        return;
  } else {
    // if the file didn't open, print an error:
        LCD_clear();
    MySerial.print("error opening SD.");
        delay(1000);
  }

return;
}

 

 

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

# Обработка измерений отклонения магнитной стрелки за период 


from math import *
from tkinter import *

f= open('C:/Python_proekt/flash/050316.TXT')  # файл с исходными измерениями
pp=8 # граница для считывания значения отклонения из исходного файла
i=0     #  индекс текущей строки string
ip=0   # счетчик пробелов при разборе string
dev=[' ',' ',' ',' ']   # массив преобразования значения девиации
di=0                    # индекс dev
s_izm=8640     # общее количество измерений 
i_izm=0       # счетчик обработанных измерений
s_X=720      # количество отображаемых измерений 
k_X=[]          # массив отображаемых измерений   по X
k_Y_p=[]      # массив отображаемых измерений (+) по Y
k_Y_m=[]     # массив отображаемых измерений (-)  по Y
X=0              # индекс k_X
Y=0              # индекс k_Y_p, k_y_m
Ydev=0        # девиация по Y берется из файла измерений
k_M=11       # масштабный коэффициент измерений
                    # в сутках получается около 8645 измерений в сутки, 1440 минут, отображаем каждую 2-ю минуту = 720
i_M=0          # счетчик суммы девиации за период k_M
sum_dev_p =0  # сумма девиации за период k_M (+)
sum_dev_m =0 # сумма девиации за период k_M (-)

while True:
    if i_izm==s_izm:
        print('Break')
        break
    else:
        if i_izm==0:
            string=f.readline()
            string_n=string
        else:
            string=f.readline()


    while True:
        if string[i]=='\n' :
            break
        else:
            if string[i]==' ':
                ip=ip+1
            else:
                if ip==pp:
                    dev[di]=string[i]
                    di=di+1
                    if ip==(ip+1):
                        break
        i=i+1


    i_izm=i_izm+1
    i_M=i_M+1
    Ydev=int(dev[0]+dev[1]+dev[2]+dev[3])
    
    if i_M<=k_M:
        if Ydev>=0:
            sum_dev_p=sum_dev_p+Ydev
        else:
            sum_dev_m=sum_dev_m+Ydev
    else:
        k_X.append([1])
        k_X[X]=X       
        X=X+1
        k_Y_p.append([1])
        k_Y_m.append([1])
        k_Y_p[Y]=int(sum_dev_p/k_M)
        k_Y_m[Y]=int((sum_dev_m/k_M)*(-1))
        Y=Y+1
        sum_dev_p =0  # сумма девиации за период k_M (+)
        sum_dev_m =0 # сумма девиации за период k_M (-)    
        i_M=0

    i=0
    ip=0
    dev=[' ',' ',' ',' ']
    di=0



#   В Ы В О Д      Г Р А Ф И К А

X_s=10          # отступ слева по оси Х - координата нуля 
Y_s=200      # координата нуля по Y
D_X=0.01    # масштабный коэффициент по Х
D_Y=10       # масштабный коэффициент по Y
Y_P_p=17   # граница по Y выхода в красный
Y_0=0         #  левый верхний Y
sm_X=100  # смещение по X от последнего измерения до конца оси X
kd_Y=2       # коэффициент деления оси Y
line_canv=2 # толщина линии оси координат
line_izm=2  # толщина линии отображения измерения


root = Tk()

canv = Canvas(root, width = (s_X+sm_X), height = 400, bg = "white")         # окно
canv.create_line(X_s,Y_s*kd_Y,X_s,Y_0,width=line_canv,arrow=LAST)      # координата Y
canv.create_line(X_s,Y_s,(s_X+sm_X),Y_s,width=line_canv,arrow=LAST) # координата X
canv.create_text((s_X+sm_X-45), Y_s+20, text ='Время-минуты ', fill="purple", font=("Courier New CYR", "10"))
canv.create_text((X_s+80), Y_0+10, text ='Отклонение - градусы ', fill="purple", font=("Courier New CYR", "10"))
canv.create_text((X_s+400), Y_0+10, text ='Отклонение магнитной стрелки за период 1440 минут ', fill="black", font=("Courier New CYR", "10"))
canv.create_line((X_s-3),(Y_s-170),(X_s+3),(Y_s-170),width=line_canv)
canv.create_line((X_s-3),(Y_s+170),(X_s+3),(Y_s+170),width=line_canv)
canv.create_text((X_s+17), (Y_s-170), text ='+17 ', fill="purple", font=("Courier New CYR", "10"))
canv.create_text((X_s+17), (Y_s+170), text ='-17 ', fill="purple", font=("Courier New CYR", "10"))
canv.create_line((s_X+X_s),Y_s-3,(s_X+X_s),Y_s+3,width=line_canv)
canv.create_text((s_X+X_s+35),Y_s-10,text='1440 min',fill="purple", font=("Courier New CYR", "10"))
canv.create_text((X_s+400), Y_s+185, text =string_n, fill="black", font=("Courier New CYR", "10"))
canv.create_text((X_s+400), Y_s+199, text =string, fill="black", font=("Courier New CYR", "10"))


J=0     # индекс выводимых результатов

for J in range(X):
    
    if k_Y_p[J]<=Y_P_p:   #  проверка на положительное красное
        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)
    else:
        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)         


    if k_Y_m[J]<=Y_P_p:  #  проверка на отрицательное красное
        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)
    else:
        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)
        

canv.pack()	
root.mainloop()
f.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

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