2015-05-29 3 views
1

У меня проблема с приложением в Arduino Uno.Arduino Uno, несколько процессов, многопоточность

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

Я искал, поддерживает ли Arduino многопоточность, чтобы иметь поток для отправки данных на сервер, а другой для регистрации количества продуктов, но пока у меня нет четкого ответа.

Что было бы лучшим решением для решения этой проблемы?

const long MAX_ITERATION = 100000; 
const int OFF = 1; 
const int ON = 0; 
const int PHOTOELECTRIC_SENSOR = 3; 

int counter = 0; 
long iteration = 0; 
int state = OFF; 

void loop() { 
    registerProduct(); 
    if (iteration >= MAX_ITERATION) { 
     // this process takes more than a second 
     sendDataToServer(); 
     iteration = 0; 
    } 
    iteration++; 
} 

void registerProduct() { 
    int currentSensorState = digitalRead(PHOTOELECTRIC_SENSOR); 
    if (currentSensorState != state) { 
     if (currentSensorState == ON) { 
      counter++; 
     } 
    } 
    state = currentSensorState; 
} 

void sendDataToServer() { 
    // Sends data through HTTP protocol, and sets counter to zero 
} 

ответ

2

Похоже, вы захотите перепроектировать это. Хотя вы можете использовать что-то вроде потоковой обработки на настольной платформе, у вас нет аппаратной поддержки параллелизма таким образом на Arduino UNO. Однако у вас есть прерывания, которые вы можете использовать для своей текущей проблемы.

Установите датчик на прерывание смены контактов. Увеличьте счетчик в ISR для прерывания изменения пин-кода. Arduino UNO имеет несколько прецедентов с переменным разрывом общего назначения, для получения дополнительной информации просмотрите таблицу данных.

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

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

+0

Большое спасибо, я попробую ваше предложение. – jahepi

1

Не существует параллелизма в оборудовании микроконтроллера или на языке.

Правильный способ сделать это - использовать interrupt, чтобы получать обновления от датчика асинхронно.

Вы также не должны блокировать отправку, вы должны отправить несколько байтов, а затем отправить еще несколько на каждый цикл.

+0

Thanks Jarrod, собираюсь прочитать о прерываниях. – jahepi

0

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

Я работаю над проектом, который требуется некоторое время назад, и вы можете найти source code here. Это основано на более обширной библиотеке очередей Zuph под названием AVRQueue.

Простая реализация библиотеки планировщика. Я изначально написал его для компиляции с помощью компилятора avr-c и не тестировал его с помощью IDE arduino, но это не должно быть проблемой.

Scheduler m(); 

void setup() { 
    m.addTask(querySensor, "q_sens", 0, 1000); 
    m.addTask(doStuffWithData, "stuff", 0, 5000); 
} 

void loop() { 
    m.run(millis()); 
} 

int querySensor(unsigned long now) { 
    ... 
} 

int doStuffWithData(unsigned long now) { 
    ... 
}