Ви не увійшли.
Також важливе питання надійності системи на arduino?
Визначте критерії "надійності системи".
Якщо мається на увазі надійність апаратної частини, то це визначається якістю компонентів та техпроцесом виробницва. Із власного досвіду, з оригінальними платами проблем не мав, а от серед клонів попадається відверте лайно. І звісно, будь-яка надійна система залишаєтся надійною тільки при певних умовах експлуатації.
Якщо мається на увазі надійність ПЗ, то це залежить від радіусу кривизни рук розробника та випуклості очей тестувальника.
а ось зрозуміти, як цей форум працює, що якісь повідомлення видно зразу, якісь ні..
Наскільки розумію, воно занадто рано створює посилання на нову сторінку стрічки (оті [ 1 2 3 4 ] вгорі біля теми), і при відповіді автоматично перекидає на ту неіснуючу сторінку. Якщо повернутись на попередню сторінку, то повідомлення стає видно.
Енкодер річ прикольна, і правильна, я повністю згоден. але потрібно або 3д принтер, або досить прямі руки.
Та працюватиме і з такою конструкцією як у автора, тільки отвір має бути достатньої довжини, щоб обидва датчики могли бути активними одночасно.
Для 3 датчиків годяться руки будь-якої форми
.
Судячи по фото, там і два ледве влізе, куди там третій. Там подвійний, як в кульковій миші, добре би вписався.
Які ще три датчика? Ви якісь велосипеди вигадуєте. Отвір має бути такої довжини, щоби було положення, при якому активні обидва датчика.
Назвемо їх A і B.
При обертанні в один бік спочатку активується A, потім активується B, потім A дективується, потім B деактивується.
При обертанні в інший бік все у зворотньому порядку: спочатку активується B, потім активується A, потім B деактивується, потім A деактивується.
Форма сигналів буде наступна:
┌───┐
A ────┘ └─────
┌───┐
B ─────┘ └─────
┌───┐
A ─────┘ └─────
┌───┐
B ────┘ └──────
Працювати як зі звичайним обертовим енкодером. При правильній реалізації не потрібно ніякого debounce, і не важливо, чи у датчиків активний високий, чи низький.
Для механічного балансу можете симетрично прорізати другий отвір, тоді буде рахувати напів-оберти.
Максимальна частота обертання 1000 оборотів за хвилину
Тобто при рівномірному квадратурному сигналі 15 мілісекунд між фронтами. Навіть при куті між датчиками в 15° мінімальний інтервал між фронтами буде порядка 500 мкс. Це ж як треба програму написати, щоб була проблема?
Будуть проблеми при швидкому обертанні.
Який у вас діапазон обертів, мінімум і максимум? Atmega328P може рахувати зовнішні імпульси з частотою ледь не до тактової частоти. Звісно, не з ардуіно фреймворком.
На першій для роботи Ethernet на другій для SD card
Ethernet та SD card працюють по одній і тій же шині SPI, тільки chip select у них різні. Просто на вашому шилді SPI виведено тільки на на отой 6-піновий ICSP, якщо вірити схемі по посиланню з попереднього повідомлення.
ось трохи змінив ...
Не дуже розумію, навіщо взагалі використовувати String. Це обгортка над динамічним масивом char. Вона зручна, коли потрібно обʼєднувати рядки та маніпулювати літералами що зберігаються на флеші. У вас рядок фіксованої максимальної довжини, читайте одразу в статичний масив.
Вище я наводив приклад реалізації токенайзера, який видає char* на токен по індексу, або на пустий рядок, якщо токена з таким індексом нема.
Все одно не зрозуміло. Різниця між картинками - в проводів reset, який в sd карті не використовується.
Якщо там такий варіант шилда, то SPI виведено тільки на ICSP, а на пінах 10..12 ніякої SPI нема.
4.8 В, це ж не просто так.
То мабуть не на карті міряли, а на вході шилда.
Проблеми вирішив.
Вітаю!
потрібно ще так з'єднати
Reset там, мабуть, зайвий. А розпіновка вашої версії шилда мала би бути відома вам.
Моя б воля, я б законодавчо заборонив продавати периферійні модулі та шилди без надання схеми електричної принципової
Коли мега звертається до шилда, світеться світо діон на шилду.
До якої лінії цей світлодіод підключений? W5100 - це взагалі мікросхема ethernet-контролера. Шилдів з нею багато різних може бути. SD-карта на шилді - це окремий пристрій, тільки використовує спільну з W5100 SPI-шину (мабуть). А chip select у неї окремий. І має бути конвертор рівнів на SPI, або хоча б резистивні дільники.
Давайте схему вашого шилда. Або хоча б посилання чи фото, по якому можна пошукати його схему. Маркування пінів на ньому якесь є?
напруга є, 4,8 В
4.8 В на SD-карті? Вона б мала вже згоріти. На шилді має бути регулятор, з якого живлення подається на SD-розʼєм.
Може в кого є скетч та схема саме для mega та w5100
Шілда W5100 у мене нема, але знайшовся модуль TFT з розʼємом для SD-карти. Підключив до Arduino Mega 2560:
SD Mega
SCK <-> 52
MISO <-> 50
MOSI <-> 51
SD_CS <-> 4
VCC <-> 5V
GND <-> GND
Вставив SD-карту з FAT32.
В Arduino IDE завантажив приклад: File -> Examples -> SD -> listfiles. Вибрав "Arduino Mega or Mega 2560" і відповідний порт.
Замінив
const int chipSelect = 10;
на
const int chipSelect = 4;
Скомпілив, завантажив. Все працює:
12:52:54.452 -> Initializing SD card...initialization done. 12:52:54.484 -> U-BOOT.IMG 464508 12:52:54.516 -> MLO 43828 12:52:54.516 -> ROOTFS~2.SQU 12943360 12:52:54.548 -> AM335X~1.DTB 98763 12:52:54.579 -> ROOTFS~1.SQU 12943360 12:52:54.612 -> ZIMAGE 8115424 12:52:54.612 -> done!
Наскільки памʼятаю, контролер SPI на всіх атмегах однаковий, не має бути різниці чи там atmega2560, чи atmega328P.
Бо в мене є сумнів що я вірно все зробив.
Перевірте живлення що йде на саму SD-карту. Перевірте, чи доходить до неї chipselect.
Якщо у вас підозра, що там щось специфічне для W5100, то давайте схему вашого шілда і що куди підключено, включно з живленням. Телепатично вгадувати будем довго.
пробував і 4, не працює.
Пробували для того SD.begin() що в loop(), чи тільки для того що в setup()? Взагалі-то не дуже хороша ідея реініціалізувати SD на кожній ітерації головного циклу.
Для початку спробуйте мінімальний скетч, який тільки ініціалізує SD і виводить результат, більш нічого не робить.
Спробуйте скетч listfiles із SD examples.
підключено на 4 pin mega -> 4 pin w5100
намагався if (!SD.begin(53))
виходить те саме
Чому 53, якщо до нього вже підключений chip select для W5100? Вказуйте той пін, до якого підключений SD_CSn.
Тоді це буде скетч для дисплея і потрібно додати два входи для оптодатчиків та один для скидання на 0
Ось ця бібліотека використовується?
uint8_t DispMSG[] = {1, 2, 3, 4};
display() приймає масив uint8_t. int8_t тут теж працюватиме, але краще одразу писати правильно.
int t[4]={0,0,0,0};
Навіщо ще один масив, тим більше int? Можна ж
void num(unsigned int value)
{
DispMSG[0]=((value/1000)%10);
DispMSG[1]=((value/100)%10);
DispMSG[2]=((value/10)%10);
DispMSG[3]=((value/1)%10);
}
Або краще так:
void num(unsigned int value)
{
for (int8_t i = 3; i>=0; i--) {
DispMSG[i] = value % 10;
value /= 10;
}
}
І замість цього
tm1637.display(0,t[3]); tm1637.display(1,t[2]); tm1637.display(2,t[1]); tm1637.display(3,t[0]);
просто
tm1637.display(DispMSG);
Хоча я б взагалі зберігав лічильник в BCD, там його ж і модифікував, наприклад так:
void inc()
{
for (int8_t i = 3; i>=0; i--) {
if (DispMSG[i] == 9) {
DispMSG[i] = 0;
} else {
DispMSG[i]++;
break;
}
}
}
void dec()
{
for (int8_t i = 3; i>=0; i--) {
if (DispMSG[i] == 0) {
DispMSG[i] = 9;
} else {
DispMSG[i]--;
break;
}
}
}
За потреби значення в unsigned int береться з нього елементарно.
Оптичний або магнітний датчик вважає в один бік, а мені потрібно в обидві.
Квадратурний покаже в обидві сторони.
Коліщатко від мишки на швидкості моторчика не витримає.
Тобто задача зводиться до вибору підходящого енкодера з необхідними механічними параметрами.
Не можу записати данні в файл на sd за допомогою w5100
Я пыдключаю pin:
w5100 Mega
MOSI------10 ----51
MISO------11-----50
SCK-------12------52
SS---------13-----53
А chip select для SD-карти (SD_CSn)?
Ви так і не написали, що у вас за платформа. AN0/AN1 схоже на PIC.
Необхідно вважати обороти при різній швидкості обертання як в одну сторону, так і в іншу. Використовуючи моторчик, як генератор.
Який у вас моторчик? Той, що крутить диск? Там зазвичай BLDC моторчик з двома проводами. Теоретично, в певному діапазоні швидкостей можна виділяти пульсації за допомогою алгоритмів DSP і дуже приблизно рахувати кількість обертів. Ви ж розумієте, що при повільному обертанні напруга з нього мізерна, може бути нижче рівня чутливості, а при досить великій швидкості напруга може перевищувати допустиму для ADC? До того ж, щоб працювало в обидві сторони, потрібно або додавати позитивне зміщення ззовні, або двополярний ADC.
Схоже на якесь збочення. Чому не застосувати який-небудь оптичний енкодер?
Не можу виставити фото, пробував, не вийшло.
Внизу вікна редагування є "Завантаження".
#include "TM1637.h"
Перш за все давайте посилання на бібліотеки, які використовуєте.
pinMode(AN0,OUTPUT); pinMode(AN1,OUTPUT);
Що за AN0 і AN1? Яка у вас платформа взагалі?
void setup() { ... delay(1000); }
Ну от навіщо в setup() ця затримка в одну секунду?
if (digitalRead(MINUS)==LOW) ctr=0; ... updateDisplay(1); ... decimal(ctr/10); ... num (i);
Де обʼявлені ці ctr, updateDisplay, decimal, num? Цей код взагалі не має компілюватись.
Arduino IDE, як проект для навчання, мав би компілювати з -Wall -Wextra -Werror -pedantic-errors. А у них навіть "Show verbose output during: compile" за замовчуванням вимкнене. Бояться, що багатобуков злякає школярів?
char fullSpeed[5]; sprintf(fullSpeed, "%03d", speedKmh); // чтобы избежать переполнения sprintf(fullSpeed, sizeof(fullSpeed), "%03d", speedKmh);
Така конструкція чомусь виводить на екран якісь сторонні символи замість данних ...
snprintf. Я ж поправився вище.
Взагалі комілятор мав би видати попередження. Чи у вас вони вимкнені?
Для динамічно створеного масиву sizeof теж щось повертає. і це не відомо під час компіляції.
Він повертає те ж значення, що вказане в квадратних дужках при обʼявлені масиву, помножене на розмір елемента. Це ніяк не відображає, чи не виліз стек за дозволені межі, і чи не вилізе при подальшому виклику функцій або обробників переривань.
Ну і автоматика, яка в деяких умовах сама ребутиться, виглядає стрьомно.
Від постановки задачі залежить. Іноді ребут - єдина правильна дія. Іноді має сенс додатково зберігати діагностичну інформацію, яка саме умова спричинила фолт.
Для перевірки, можливо, підійде sizeof.
Ем, оператор sizeof повертає розмір обʼєкта під час компіляції. Яким він тут боком?
Ну, і якщо пам'яті таки не вистачило, то навіть незрозуміло що гірше, просто ребутнутися, чи щось там обробляти.
Так це одна з умов постановки задачі - як обробляти ту чи іншу ситуацію. Можна показати повідомлення, можна ребутнутись, можна "зависнути", але поведінка має бути визначена. Гірше (точніше, неприпустимо), коли поведінка не визначена. Наприклад, виконається довільний код, який перемкне піни в недопустимий стан або перепише важливі дані в EEPROM.
Дійсно, динамічно виділяти пам'ять під масив можна
Це не динамічне виділення в сенсі з купи, як malloc() або оператор new. Тут памʼять виділяється на стеку, як для звичайної локальної змінної. Компілятору нема різниці, чи віднімати від вказівника вершини стека константу, чи значення якого-небудь регістра.
Те ж саме можна зробити "класичним" методом:
char *array = alloca(strlen(str) + 1);
А якщо не вистачить пам'яті при роботі..
Проблема не стільки в тому, що памʼяті може не вистачити, а в тому, що нема можливості це перевірити навіть в рантаймі. При динамічному виділенні є можливіть перевірити успішність результата (і грамотно написаний код має це перевіряти). Хоча в ардуіно фреймворку це теж не дає 100% гарантії, бо хто знає, скільки байтів ще напхає в стек який-небуть обробник переривання умовної бібліотеки Wire. Може і для ардуіни є якісь реалізації runtime stack guard, але мені не зустрічались.
не умею программировать Ардуино, пользуюсь готовыми скетчами,
возникла проблема как объединить 6 в один,может ли кто помочь?
Ви хочете розібратись і навчитись, чи просто отримати готовий результат?
Якщо перше, то почніть з простої програми, поступово додаючи потрібні функції. Почитайте туторіали, подивіться навчальні відео, їх зараз мільйони. Якісь конкретні питання - пишіть, що саме незрозуміло.
Якщо друге, то шукайте виконавця, який зробить вам послугу за відповідну оплату.