Перейти до змісту

HWman

Рекомендовані повідомлення

  • Відповідей 550
  • Створено
  • Остання відповідь

Топ авторів теми

Опубліковано

доброго дня, хто міг би допомогти з побудовою управління (потужним)шаговим двигуном, на базі в же купленої плати mega 2560

ось така платка http://www.chipdip.ru/product/arduino-mega-2560/, гола, потрібно розробити(чи може є вже готові) программу для цього заліза!

з усієї інформації що я знаю в кінцевому результаті має вийти мопед на безщітковому двигуні(індукційному здається якщо я не помиляюсь) з акумуляторним живленням та управлінням на mega 2560! двигун виготовляється під замовлення, чому безщітковий - для того щоб споживання його було мінімальним, тобто підвищіти кпд агрегату, це все що мені відомо!

потрібно не мені, людина платить нормальні гроші за роботу, занявся би сам, але мало часу та досвіду в даній області(розбиратися самому займе час), можливо є людина яка займається цим в задоволення та зробить все швидко і якісно!

я як посередник не беру за це ніяких коштів, просто якщо ви людина з серйозним наміром допомогти та ще й при цьому заробити, пишіть сюди, або в приват свій номер телефону, я передам його людині, далі будете спілкуватись напряму!

буду вдячним за допомогу!

Опубліковано

Планується прямий привід аля мотор колесо?

2.JPG

я ж написав, це все що мені відомо, якщо маєте бажання зайнятись? то напишіть мені свій номер телефону я дам цій людині, або ж можу дати його номер, тільки спитаю, бо не записав!

Опубліковано (змінено)

Ось мої напрацювання по програмному ШИМ на любому цифровому порті:


int led = 13;
byte counter = 0; // обязательно должна бить типа байт
//если до 255 + 1 будет 0, тоесть переменная переполнится
byte brightness = 0;
int fadeAmount = 1;
long previousMillis = 0;
long interval = 30;
void setup() {
pinMode(led, OUTPUT);
}
void loop() {
unsigned long currentMillis = millis(); // используем прерывания
// ибо функцию нужно постоянно вызывать
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
brightness = brightness + fadeAmount;
if (brightness == 0 || brightness == 255) {
fadeAmount = -fadeAmount ;
}
}
software_pwm(led, brightness); // для роботы функции её нужно
// постоянно вызывать иначе не будет работать таймер
}
void software_pwm(byte pin, byte pwm_level){
counter = counter + 1;
if(counter <= pwm_level){
digitalWrite(pin,HIGH);
}
else{
digitalWrite(pin, LOW);
}
//delayMicroseconds(50);
}

Суть цього коду щоб якомога частіше викликати функцію software_pwm() щоб там у ній "тікав" таймер який власне і забезпечує ШИМ.

На частоту ШИМа впливають багато факторів, якщо камінь добре грузити то частота впаде до видимого людським оком діапазону.

В ідеалі треба юзати переривання по таймеру, але я поки ще до цього не дійшов, так... граюся.

Змінено користувачем HWman
  • +1 1
  • 2 тижня потому...
Опубліковано

Як що до:

1387809214_3.jpg

+ вечір два посидіти з паяльником? Ніби досвід маєш.

Якщо опанувати цю нескладну технологію то можна огого.

3f10c8fc30dd1b9bd74e2ff59a881e55.jpg
  • 1 місяць потому...
Опубліковано

Хух, практично закінчив головний модуль мого супер навороченного даталогера, взяв за основу код звідти і трішки переробив, добавив кілька світлодіодів для різної індикації, перемичка(може перетворитись у кнопку якщо підключити спеціальним конектором), призначення якої я ще не придумав, залишив на майбутнє, просто було трішки вільного місця і вільний порт.

Як бачите все працює без кварцового резонатора, на борту мега 328р, на інші код не поміщається, бібліотека для роботи з сд картою вимагає мінімум 13-15 кБ, у МК присутній загрузчик, можна пришити через перехідник юсб-ттл(юарт) куди між іншим відправляються ті дані які пишуться на флеш, по суті це буде і юсб 4-х канальний АЦП.

В другій частині будуть дільники для АЦП з багатооборотистими резисторами що дозволить налаштовувати практично любі діапазони напруг. Всі заміри АЦП робляться відносно внутрішнього опорного джерела 1.1 В так що падіння напруги на акумуляторі в процесі розряду не сильно скажеться на похибці у вимірюваннях.

Для зменшення шумів АЦП і підвищення розрядності до 11 біт застосував оверсемплінг, також для вимірювання напруги живлення застосував теж оверсемплінг тільки тут просто фільтрація шумів, до речі, напруга живлення і кількість секунд з моменту запуску теж пишуться на флешку.

А ще після кожного вимкнення створюється новий файл з іменем наприклад 452.csv , тобто комірка пам'яті еппром інкрементується, максимальне можливе число - максимум типу інт(65534), що стало можливе завдяки цьому матеріалу - Пример. EEPROM — чтение/запись int.

Схема має захист від глибокого розряду акумулятора (при напрузі у 3.4 В переходить у режим сну - 0.00005 А) а також від перевищення напруги - 4.2 В, захист флешки реалізував дуже просто, підключив її живлення до 2-х портів МК, у одного не вистачало струму, і тепер коли хочу - можу вимикати живлення, завдяки цьому добився такого низького енергоспоживання у режимі сну.

Що хочу зробити щонайближчим часом:

- Оптимізувати код

- Зробити можливість зміни інтервалу запису від 10 разів на секунду до один раз на 650 секунд(~11 хв.) за допомогою юарта

- Добавити індикацію заряду акумулятора на 3-х світлодіодах

- Задіяти невикористані порти.

Ось фото мізків:

60a7940b302e71f8531b841ec2566d79.jpg

Ось такий на даний момент код:

/*

SD card datalogger

MOSI - pin 11(PB3)

MISO - pin 12(PB4)

CLK - pin 13(PB5)

CS - pin 4(PD4)

*/

#include <EEPROM.h>

#include <SD.h>

#include <avr/sleep.h> // здесь описаны режимы сна

#include <avr/power.h>

#define AnalogPin 1

#define chipSelect 4

//byte FileNumberEEP = 0;

boolean StateLed1 = LOW; //

boolean StateLed2 = LOW; //

boolean StateLed3 = LOW; //

byte Timer = 0;

char FileName[12]; // имя файла, напр. log-114.csv

void setup()

{

pinMode(10, OUTPUT); // питалово 1

pinMode(9, OUTPUT); // питалово 2

pinMode(8, OUTPUT); // жёлтый светодиод

pinMode(7, OUTPUT); // зелёный

pinMode(6, OUTPUT); // белый

for(byte led_test = 6; led_test <= 8; led_test++){ // проверка

digitalWrite(led_test, HIGH);

delay(500);

digitalWrite(led_test, LOW);

delay(500);

}

unsigned int VccSetup = VccReadOversampled();

if(VccSetup > 3070 && VccSetup < 3850){ // гистерезис

//unsigned int FileNumberEEP = 65535;

unsigned int FileNumberEEP = EEPROMReadInt(0); // тут хранится имя файла

FileNumberEEP = FileNumberEEP++;

if (FileNumberEEP >= 65535){ //65535

FileNumberEEP = 0; //

}

EEPROMWriteInt(0,FileNumberEEP);

sprintf(FileName,"log-%u.csv", FileNumberEEP); // тут храниться имя создаваймого в начале файла

digitalWrite(10, HIGH); // подадим питание флешки

digitalWrite(9, HIGH); // одного порта маловато

Serial.begin(9600);

Serial.println("Initializing SD card...");

// see if the card is present and can be initialized:

if (!SD.begin(chipSelect)) {

Serial.println("Card failed, or not present");

return;

}

Serial.println("card initialized.");

}

else{

system_sleep_2S();

}

}

void loop()

{

digitalWrite(6, StateLed1);

digitalWrite(7, StateLed2);

digitalWrite(8, StateLed3);

unsigned int sensor = analogReadOversampled(AnalogPin);

unsigned int Vcc = VccReadOversampled();

if(Vcc > 2950 && Vcc < 3850){

if (sensor > 5) {

StateLed2 = HIGH;

}

else{

StateLed2 = LOW;

}

File dataFile = SD.open(FileName, FILE_WRITE); // "datalog.csv"

if (dataFile) {

dataFile.print((millis() / 1000));

dataFile.print(", ");

dataFile.print(Vcc);

dataFile.print(", ");

dataFile.println(sensor);

dataFile.close();

Serial.print((millis() / 1000));

Serial.print(", ");

Serial.print(Vcc);

Serial.print(", ");

Serial.println(sensor);

StateLed1 = HIGH;

}

else {

Serial.print("error opening ");

Serial.println(FileName);

StateLed3 = !StateLed3;

digitalWrite(10, LOW); // отключим питалоаво флешки

digitalWrite(9, LOW); // ведь она всёравно не установлена

// временно

Serial.print((millis() / 1000));

Serial.print(", ");

Serial.print(Vcc);

Serial.print(", ");

Serial.println(100-Timer);

// временно

Timer++;

if(Timer > 100){ // 100*12

Serial.print("Zzz...");

delay(100);

system_sleep_2S();

}

delay(100);

}

}

else{

system_sleep_2S();

}

}

unsigned int analogReadOversampled(byte analogChannel) {

unsigned long aSum = 0; // the sum of all analog readings

for(unsigned int i = 256; i > 0; i--){

aSum = aSum + read_adc(analogChannel); // read and sum 16 ADС probes

}

return aSum >> 7; // ..

}

unsigned int read_adc(byte Channel){

ADMUX |= (1<<REFS0); //|(1<<REFS1); //(1<<REFS0); - 5 V, (1<<REFS0)|(1<<REFS1); - 2.56V

ADMUX &= 0xF0; //Clear the older channel that was read

ADMUX |= Channel; //Defines the new ADC channel to be read

ADCSRA |= (1<<ADSC); //Starts a new conversion

while(ADCSRA & (1<<ADSC)); //Wait until the conversion is done

//ADCSRA &= ~(1 << ADEN); // отключаем АЦП

return ADCW; //Returns the ADC value of the chosen channel

}

static int vccRead(byte us =250) { // измерение напряжение питания

ADMUX = 1<<REFS0; // опорное напряжение - Vcc

ADMUX |= 0x0E; // объект измерения - внутренний источник

// стабилизированного напряжения 1.1В

delayMicroseconds(us);

ADCSRA |= 1<<ADSC; // запуск АЦ-преобразования

while(ADCSRA & (1<<ADSC)); // и ожидание его завершения

word x = ADC;

return x ? (1100L * 1023) / x : -1;

}

unsigned int VccReadOversampled() {

unsigned long aSum = 0; // the sum of all analog readings

for(unsigned int i = 16; i > 0; i--){

aSum = aSum + vccRead(); // read and sum 16 ADС probes

}

return aSum >> 4; // ..

}

void system_sleep_2S(){

//wdt_reset(); // сброс

//wdt_enable(WDTO_2S); // разрешение ватчдога раз в 2с

//WDTCR |= _BV(WDTE); // разрешение прерываний по ватчдогу (иначе будет резет)!

//sei(); // разрешение прерывания

digitalWrite(10, LOW); // отключим питалоаво флешки

digitalWrite(9, LOW); // ведь она всёравно не установлена

digitalWrite(8, LOW); //

digitalWrite(7, LOW); // и все потушим светодиоди

digitalWrite(6, LOW); //

ADCSRA &= ~(1 << ADEN); // отключаем АЦП

set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную

while(1) {

sleep_enable(); // разрешаем сон

sleep_cpu(); // спать!

}

}

void EEPROMWriteInt(int p_address, unsigned int p_value)

{

byte lowByte = ((p_value >> 0) & 0xFF);

byte highByte = ((p_value >> 8) & 0xFF);

EEPROM.write(p_address, lowByte);

EEPROM.write(p_address + 1, highByte);

}

unsigned int EEPROMReadInt(int p_address)

{

byte lowByte = EEPROM.read(p_address);

byte highByte = EEPROM.read(p_address + 1);

return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);

}

Код звичайно на охайний не претендує, я і не відхрещуюсь що це бидлокодерство.

to%2Bbe%2Bcontinued.jpg

PS многа букаф, знаю але так як у мене кількість повідомлень обмежена то постарався вкластись у один пост

  • +1 4
Опубліковано (змінено)

Ще б глянути скрін монітора порта))) що там в серіал йде ...

66f8e719106fd82f917b5b9206892eaf.png

Час у секундах, напруга живлення у мВ і показники 1-го порта АЦП(поки).

Зробив усе що планував корім оптимізації коду, для оптимізації думаю треба переписувати практично половину...

ЗІ скористався ось цим прикладом для того щоб по юарту отримувати великі числа для задавання затримки:

ЗІІ для того щоб уникнути непередбачувані наслідки то затримку реалізував наступним чином:

if(waiting > 0){

unsigned int waiting_ms = 0;

for(waiting_ms = waiting; waiting_ms > 0; waiting_ms--){

delay(1);// ждём

}

}

Змінна waiting зчитується з EEPROM.

Змінено користувачем HWman
  • +1 1
  • 2 тижня потому...
Опубліковано (змінено)

https://www.youtube....h?v=WXdDA3vwT7I

Жаль 74HC595 немає, так би перевірив як насправді працює.

До речі 1020 байт із 1024 можливих.

Змінено користувачем HWman
  • +1 1
Опубліковано

Ще б глянути скрін монітора порта))) що там в серіал йде ...

66f8e719106fd82f917b5b9206892eaf.png

Час у секундах, напруга живлення у мВ і показники 1-го порта АЦП(поки).

Зробив усе що планував корім оптимізації коду, для оптимізації думаю треба переписувати практично половину...

ЗІ скористався ось цим прикладом для того щоб по юарту отримувати великі числа для задавання затримки:

ЗІІ для того щоб уникнути непередбачувані наслідки то затримку реалізував наступним чином:

if(waiting > 0){

unsigned int waiting_ms = 0;

for(waiting_ms = waiting; waiting_ms > 0; waiting_ms--){

delay(1);// ждём

}

}

Змінна waiting зчитується з EEPROM.

Краще про delay забути раз і на завжди.

Якось так unsigned long newtime=milis()

Десь раніше oldtime=milis()

If newtime-oldtime>zatrumka then робимо що треба обо кидаемо флаг

Коли робити по такій схемі процессор тупо не тормозиться, а виконує роботу, дивиться, рахує,...

Якщо делау весь цикл тормозиться і можна пропустити щось важливе.

  • +1 1
Опубліковано

Я думав над цим, але з такими розкладами треба трішки буде змінити логіку програми. А там майже три сотні стрічок, іншими словами влом.

Та і нічого важливого МК не пропустить коли він буде втикати.

Багато чого хочеться доробити але то часу немає, то влом, то ще щось...

  • +1 1
Опубліковано

Жаль 74HC595 немає, так би перевірив як насправді працює.

До речі 1020 байт із 1024 можливих.

В мене скоро мають бути 74HC595, якщо потрібні - пишіть, домовимось.

Опубліковано

Жаль 74HC595 немає, так би перевірив як насправді працює.

До речі 1020 байт із 1024 можливих.

Цілком собі робочий код:

Трішки зробив під себе, підняв макс. діапазон до 39.99 В і за допомогою оверсемплінгу зробив вивід сотих.

Код і схема взяті звідси http://radioparty.ru...74hc595-hd44780 .

  • +1 2
  • 3 тижня потому...

Для публікації повідомлень створіть обліковий запис або авторизуйтесь

Ви повинні бути користувачем, щоб залишити коментар

Створити обліковий запис

Зареєструйте новий обліковий запис у нашій спільноті. Це дуже просто!

Реєстрація нового користувача

Увійти

Вже є акаунт? Увійти до системи.

Увійти
×
×
  • Створити...