3 акселерометра mma7660 на i2c
- Войдите на сайт для отправки комментариев
Втр, 14/10/2014 - 19:04
Добрый день! Пишу работу по теме "трение при ударе", для этого решил собрать 3 акселерометра на одной i2c, поставить их в разные места (на то чем буду ударять, и куда буду ударять), затем смотреть скачки на графиках в момент удара и делать выводы. Установка с маятниками и всем прочим имеется. Вопросы по шине и акселерометрам mma7660 (http://www.seeedstudio.com/depot/Grove-3Axis-Digital-Accelerometer15g-p-...):
Можно ли с ними снять единомоментные показания?
Я пытался и читал, но не смог осилить подключение. Узнал что для слейвов в даташите указаны адреса с 8 по 19, но далее не смог продвинуться, как заставить их работать? Ранее только в ознакомить лётных целях работал с Ардуино.
одновременно не получится точно
но возможно это будет очень быстрое поочередное опрашивание. но хз какая скорость опроса акселерометра
Может быть тогда проще на каждую Ардуино по одному акселерометру? И потом просто графики наложить?
Я конечно с акселерометрами не сталкивался лично, но наверное должны быть те, которые без I2C работают. Которые работают напряму вполне можно подключить параллельно, лишь бы выводов хватило
самые точные с сожалению получатся только с 3 ардуинами. причем 2 из них будут синхронизироваться по первой. чтобы были одни временные точки
У меня есть три ардуино Уно и акселерометры, с удовольствием откажусь от одной шины, но тогда вопоос : как их вместе заставить работать? Я попробовал запустить уно-акс и уно-акс, постукать, покидать, из значений график построить, но без синхронизации это просто туфта (
сделай просто. объедени земли ардуин. выбери любой пин с которого будешь подавать сигнал остальным
подключать к остальным на пин 2 или 3. использовать прерывание короче
главная отправляет сигнал и начинает измерять. остальные по этому сигналу тоже начинают измерять. получится одновременно
на главной можно еще часы повесить. она будет хранить временные метки. наверно это нужно
далее просто собрать данные и все. черти графики и т.д.
а можно, пожалуйста, несколько подробнее? есть стандартынй скетч вывода показаний акселерометра, есть 3 ардуино, на каждую подключен акселерометр и вставлен кусок кода, отвечающий за их работу. на этом работа с самими акселерометрами закончена и теперь задача только объеденить ардуино все вместе, так? Земли объеденил.
давай код
вот стандартная для вывода показания с акселерометра: #include <Wire.h> #include "MMA7660.h" MMA7660 accelemeter; void setup() { accelemeter.init(); Serial.begin(9600); } void loop() { int8_t x; int8_t y; int8_t z; float ax,ay,az; accelemeter.getXYZ(&x,&y,&z); Serial.print("x = "); Serial.println(x); Serial.print("y = "); Serial.println(y); Serial.print("z = "); Serial.println(z); accelemeter.getAcceleration(&ax,&ay,&az); Serial.println("accleration of X/Y/Z: "); Serial.print(ax); Serial.println(" g"); Serial.print(ay); Serial.println(" g"); Serial.print(az); Serial.println(" g"); Serial.println("*************"); delay(500); }еще есть сами библиотеки для mma7660:
и еще один код для mma7660
есть еще, когда по i2c и второй акселерометр слейв: (но он уже видимо не нужен)
#include <Wire.h> #define I2C_ADDRESS 0x4C #define I2C_ADDRESS_W 0x99 //MMA7660 Address + 1 bit (Write) pag. 21 #define I2C_ADDRESS_R 0x98 //MMA7660 Address + 0 bit (Read) pag 21 #define TILT_STATUS 0x03 #define SRST 0x04 #define SPCNT 0x05 #define INTSU 0x06 #define MODE 0x07 #define SR 0x08 #define PDET 0x09 #define PD 0x0A #define POWER_UP_DELAY 10 #define X_OUT 0x00 #define Y_OUT 0x01 #define Z_OUT 0x02 void setup() { Serial.begin(38400); // start serial for output Serial.println("Setting up I2C protocol..."); Wire.begin(); SLAVE_I2C_INIT(); pinMode(13, OUTPUT); } void loop() { char x = SLAVE_I2C_READ(X_OUT); char y = SLAVE_I2C_READ(Y_OUT); char z = SLAVE_I2C_READ(Z_OUT); char mode = SLAVE_I2C_READ(0x07); // char tilt = SLAVE_I2C_READ(0x03); char sample = SLAVE_I2C_READ(0x04); // char fac = SLAVE_I2C_READ(0x0B); Serial.print("X="); Serial.print(x, DEC); Serial.print(", Y="); Serial.print(y, DEC); Serial.print(", Z="); Serial.print(z, DEC); Serial.print(", Mode="); Serial.print(mode,DEC); //Serial.print(", Tilt="); // Serial.print(tilt,DEC); Serial.print(", sample="); Serial.print(sample,DEC); //Serial.print(", fac="); //Serial.print(fac,DEC); Serial.println("."); delay(100); } void SLAVE_I2C_INIT() { Serial.println("Powering up SLAVE interface..."); delay(POWER_UP_DELAY); SLAVE_I2C_SEND(MODE,0x00); // Setting up MODE to Stand by to set SR delay(100); SLAVE_I2C_SEND(SR,0x00); // Setting up SR register to 120 samples active and auto sleep mode delay(100); SLAVE_I2C_SEND(MODE,0x01); //Setting up MODE Active to START measures delay(100); } void SLAVE_I2C_SEND(unsigned char REG_ADDRESS, unsigned char DATA) //SEND data to MMA7660 { Wire.beginTransmission(I2C_ADDRESS); Wire.write(REG_ADDRESS); Wire.write(DATA); Wire.endTransmission(); } unsigned char SLAVE_I2C_READ(unsigned char REG_ADDRESS) //READ MMA7660 data { unsigned char R_VALUE; Wire.beginTransmission(I2C_ADDRESS); Wire.write(REG_ADDRESS); // register to read Wire.endTransmission(); Wire.requestFrom(I2C_ADDRESS, 1); // read a byte while(!Wire.available()) { digitalWrite(13, HIGH); delay(100); digitalWrite(13, LOW); delay(100); } R_VALUE = Wire.read(); return R_VALUE; }во первых когда вставляешь код больше 10 строк ставь галочку сворачивать код по умолчанию
насколько быстро работает этот код? только убери все про отправку в сериал в лупе. с помощью millis() измерь время опроса датчика, чтобы понять на что рассчитывать и если ли смысл продолжать
вот стандартная для вывода показания с акселерометра: #include <Wire.h> #include "MMA7660.h" MMA7660 accelemeter; void setup() { accelemeter.init(); Serial.begin(9600); } void loop() { int8_t x; int8_t y; int8_t z; float ax,ay,az; accelemeter.getXYZ(&x,&y,&z); Serial.print("x = "); Serial.println(x); Serial.print("y = "); Serial.println(y); Serial.print("z = "); Serial.println(z); accelemeter.getAcceleration(&ax,&ay,&az); Serial.println("accleration of X/Y/Z: "); Serial.print(ax); Serial.println(" g"); Serial.print(ay); Serial.println(" g"); Serial.print(az); Serial.println(" g"); Serial.println("*************"); delay(500); }на это код
#include <Wire.h> #include "MMA7660.h" MMA7660 accelemeter; unsigned long time; void setup() { accelemeter.init(); Serial.begin(9600); } void loop() { Serial.print("Time: "); time = millis(); Serial.println(time); int8_t x; int8_t y; int8_t z; float ax,ay,az; accelemeter.getXYZ(&x,&y,&z); // Serial.print("x = "); // Serial.println(x); // Serial.print("y = "); // Serial.println(y); // Serial.print("z = "); // Serial.println(z); accelemeter.getAcceleration(&ax,&ay,&az); // Serial.println("accleration of X/Y/Z: "); // Serial.print(ax); // Serial.println(" g"); // Serial.print(ay); // Serial.println(" g"); // Serial.print(az); // Serial.println(" g"); // Serial.println("*************"); delay(500); }показал значения:
а delay то зачем оставил?
и используй micros()
поставив микрос и закомментировав delay(500)
1 сек = 1\4 000 000 от полученного значения?
т.е. в моем случае время прохода один раз составляет 0.000304 секунды?
получил:
Time: 1216
проверь так. сразу разница будет. и переменные каждый раз объявлять глупо
#include <Wire.h> #include "MMA7660.h" MMA7660 accelemeter; unsigned long time; int8_t x; int8_t y; int8_t z; float ax,ay,az; void setup() { accelemeter.init(); Serial.begin(9600); } void loop(){ time = micros(); accelemeter.getXYZ(&x,&y,&z); accelemeter.getAcceleration(&ax,&ay,&az); Serial.println(micros()-time); }вот так вот получилось(значение в 50 тыс. через каждые 90 строк повторяется):
ну такие значения приемлимы. можно и поизмерять
Отлично! каждый по отдельности у меня измеряет, а вместе как? я просто очень поверхностно знаком с тем как это работает!
почитай про прерывания. не буду за тебя все делать. а принцип уже описал
понял! к концу недели постараюсь разобраться!
я пока таким образом научился принимать сигнал со второй на первую ардуино:
передает:
int led = 13; int arcon = 1; int val = 0; void setup() { pinMode(led, OUTPUT); pinMode (arcon, INPUT); } void loop() { digitalWrite(led, digitalRead(arcon)); }получает:
int arcon = 3; void setup() { pinMode (arcon, OUTPUT); } void loop() { digitalWrite(arcon, HIGH); delay(1000); digitalWrite(arcon, LOW); delay(1000); }перепутал местами, но смысл правильный. только теперь на прерываниях
если я использую rx tx для считывания значений с одной ардуино на другую, то какими командами к ним обращаться, serial, как я понял, не работает, потому что в это же время используется подключение по юсб! с лампочкой понятно - там либо лоу либо хай, а как записать данные и отправить на ногу я не понял!
прерывание мне нужно ставить каждый раз, когда посылающая ардуинка отпраила сигнал и что бы принимающая могла его успевать каждый раз записывать?
по прерыванию две остальные измеряют и например хранят данные в оперативной памяти. а после измерений как хочешь. можешь в eeprom в конце измерения записать и считать с каждой (для 500 измерений нужно всего 1кбайт оперативки), можешь на sd карту записывать или в uart отправить. короче как хочешь и как сможешь
я написал для передачи времени, но почему то значения разнятся с теми, что были раньше
получает:
void setup() { Serial.begin(9600); } void loop() { if(Serial.available()) { delay(10); unsigned long x = Serial.read(); Serial.println(x); } }передает:
#include <Wire.h> #include "MMA7660.h" MMA7660 accelemeter; int8_t x; int8_t y; int8_t z; float ax,ay,az; unsigned long time; void setup() { Serial.begin(9600); accelemeter.init(); } void loop() { time = micros(); accelemeter.getXYZ(&x,&y,&z); accelemeter.getAcceleration(&ax,&ay,&az); time = (micros()-time); Serial.write(time); }выдает около
я правильно понимаю, что по поводу прерываний надо использовать http://arduino.ru/Reference/AttachInterrupt в отправляющем контроллере в void setup() поставть? или нет? Подскажи пожалуйста!
нет. должно быть в приемных. приемные должны по прерыванию начать измерять. а передающей не надо. она сама говорит когда начинать
сделал для принимающей вот так вот: но все равно не работает.
unsigned long x; void setup() { Serial.begin(9600); attachInterrupt(0, priem, CHANGE); } void loop() { void priem() { if(Serial.available() == 0) { x = Serial.read(); Serial.println(x); }} }http://arduino.ru/Reference/AttachInterrupt
посмотри пример как нужно правильно оформлять
подумал и решил сделать таким вот образом: подключить на каждый ком порт по ардуино и через процессинг записывать показания в один файл, что думаешь? с одной пока что все работает!
а как синхронизировать будешь?
то что процессинг будет собирать и строить графики хорошо, но тебе же нужна привязка ко времени процессов или неважно если показания одного из датчиков будут отставать?
вот так вот выглядит код для процессинга:
// Example by Tom Igoe import processing.serial.*; Serial myPort; Serial myPort1; PrintWriter output; // The serial port void setup() { // List all the available serial ports: println(Serial.list()); // Open the port you are using at the rate you want: myPort = new Serial(this, Serial.list()[1], 9600); myPort1 = new Serial(this, Serial.list()[2], 9600); output = createWriter("positions.txt"); } void draw() { while (myPort.available() > 0 && myPort1.available() > 0) { String inBuffer = myPort.readString(); String inBuffer1 = myPort1.readString(); if (inBuffer != null && inBuffer1 != null) { println(inBuffer); output.println(inBuffer); println(inBuffer1); output.println(inBuffer1); } } } void keyPressed() { output.flush(); // Writes the remaining data to the file output.close(); // Finishes the file exit(); // Stops the program }а вот так вот выглядят выводы:
как видно он не совсем последовательно выводит. кто быстрее того и вывел. тут тоже получается надо синхронизировать, но я не понимаю как(
да писал уже. как по другому сделать сам придумывай
через прерывания. но я не разобрался что было не так с тем. http://arduino.ru/forum/apparatnye-voprosy/3-akselerometra-mma7660-na-i2c#comment-85759 тут я включаю прерывание priem, затем это прерывание должно при условии получения чего либо записывать эту информацию в файл.
а в
http://arduino.ru/forum/apparatnye-voprosy/3-akselerometra-mma7660-na-i2...
я писал что посмотри как правильно оформлять
у меня ошибка в том, что я не правильно задаю function? "function: функция, вызваемая прерыванием, функция должна быть без параметров и не возвращать значений"
программа для ведущей ардуино с акселерометром должна выглядеть так: ардуино получает значения от акселерометра и записывает их, но, если на цифровом порту есть сигнал, то включается прерывание и он должен записать полученные данные с цифрового порта?
пока не поставил на установку думаю что оба(ускорение смотрю, а перемещение может быть пригодится), потом будет убрана одна ось и даже может быть и вторая.
проверь. скорость 115200. мне нужно последнее число
unsigned long time; float ax = 25.365; void setup(){ Serial.begin(115200); } void loop(){ time = micros(); for(int i=0;i<1000;i++){ Serial.println(ax); } Serial.println((micros()-time)/1000); while(1){ } }589 выдал, а что он считает?
это сколько занимает передача числа с плавающей запятой в uart на скорости 115200
0,59 мс неплохо. как часто нужно измерять?
50-100-200 милиссекунд
чем чаще - тем лучше, там маятник бьет по вагонетке, которая на пружинах калеблется туда-сюда.
попробуй так. на 2 пин подавай сигнал от второй ардуины. при сигнале первая должна провести измерения и отправить в uart
#include <Wire.h> #include "MMA7660.h" MMA7660 accelemeter; float ax,ay,az; void setup() { Serial.begin(115200); accelemeter.init(); attachInterrupt(0, blink, RISING); } void loop(){ } void accel(){ accelemeter.getAcceleration(&ax,&ay,&az); Serial.print(ax); Serial.print("\t");Serial.print("\t"); Serial.print(ay); Serial.print("\t");Serial.print("\t"); Serial.println(az); }минимум около 10 мс чтобы точно установилось. а это 100 раз в секунду
я попробовал подававать 1 на второй вход через равные промежутки времени - ничего не произошло!
так же попробовал залить код который был у нас ранее для передачи значений - тоже ничего не вышло!
а ты как смотришь? в терминале ардуины или сразу в процессинг шлешь?
в терминале ардуины! надо просто любое чредование 0 и 1 подавать, верно?
ну да. попробуй с частотой 1гц для начала
я взял стандартное мигание светодиодом на 13 порту - там как раз 1 Гц, соеденил 13 порт со 2-ым на главной и ничего не происходит.
#include <Wire.h> #include "MMA7660.h" MMA7660 accelemeter; float ax,ay,az; void setup() { Serial.begin(115200); accelemeter.init(); attachInterrupt(0, accel, RISING); } void loop(){ } void accel(){ accelemeter.getAcceleration(&ax,&ay,&az); Serial.print(ax); Serial.print("\t");Serial.print("\t"); Serial.print(ay); Serial.print("\t");Serial.print("\t"); Serial.println(az); }попробуй еще раз
ничего не происходит!
ничего не происходит!