-14

Помогите с программированием! Я не умею делать трехмерные графики. Есть программа, которая по идее должна его делать, но она выдает ошибку

Я в принципе не понимаю, откуда вылезает String, если везде прописан Extended? Если вы меня пошлете на форумы - посылайте, я ни одного работающего не нашла!
Помогите с программированием!  Я не умею делать трехмерные графики.  Есть программа, которая по идее должна его делать, но она выдает ошибку Я в принципе не понимаю, откуда вылезает String, если везде прописан Extended?  Если вы меня пошлете на форумы - посылайте, я ни  одного работающего не нашла!

Дубликаты не найдены

+5

Не туда залезли батенька, вам бы на киберфорум, extended на double меняйте

раскрыть ветку 8
+1

А чем это поможет? Extended же вместительнее?

раскрыть ветку 6
+1

double используйте, 10 лет на дельфи писал.

раскрыть ветку 5
0

А ссылью можешь поделиться на форум?

+2

проверь аргументы, которые передаешь)

раскрыть ветку 12
0

А можешь перевести на человеческий? ^^

Я просто не программист, я радиофизик, и это часть изучения численных методов. Методы хрен с ними, а программирование я не понимаю :(

раскрыть ветку 11
+1

то, что в скобочках, нужно посмотреть какого оно типа.

если массив - то каков тип элемента, если функция - что она возвращает.

раскрыть ветку 10
+1

1. Функции uD1 и uD2. Передаешь в них x и y, а используешь в функции только x в uD2, а в uD1 вообще используется только myPi.

2. Как у тебя определены series3 и series4? И почему ты их не обнуляешь как series1 и series2?

раскрыть ветку 13
0

1. Вот, кстати, я не уверена, что пи так можно задавать.

Я их так пишу, потому что у меня задача такая, функции uD1 и uD2 - это граничные условия уравнения Лапласа, а g и f - собственно, сами границы. И я еще не везде разобралась, я разбираюсь по ходу, появилась ошибка-исправила-следующая.

2. Обнулить я забыла просто. Определены на компоненте Chart, на одной - двумерные series1 и series2, на второй должны быть трехмерные series3 и series4.

раскрыть ветку 12
+1

Если график 3-х мерный, то может там другой метод есть? AddXYZ например?

Если рисуешь в TChart, то третий параметр передаваемый в AddXY как раз должен быть стринговой переменной.

TChart вообще поддерживает графики по трем осям? 

раскрыть ветку 11
0

На Dephi ещё пишет кто-то ?_?

раскрыть ветку 7
+1

а почему нет-то, собственно?)

-1

Мы не пишем, мы численные методы изучаем :)

Мне самой очень стыдно, да :(

раскрыть ветку 5
+1
Чего стыдиться то, Дельфи это инструмент и если для одних это лишь тренды, то для других это реальные деньги. Инструментов не стыдятся.
раскрыть ветку 3
0

несоответствие типов передаваемых аргументов

раскрыть ветку 1
-1

Да я умею читать, я не понимаю, откуда это несоответствие берется, везде же Extended.

0

Есть подозрение что ошибка нет тут, можно весь код? не похоже что тут вообще где-то есть string и он видимо берется еще где-то.

раскрыть ветку 1
0

Вот остатки кода, никогда эту часть не кодила :(

Иллюстрация к комментарию
0

я кажется понял, что вам надо. напишите две строчки с ошибкой и я в ответе исправлю ошибку.

раскрыть ветку 3
0

series3.AddXY(x1, g(x1), uD2(x1, g(x1)));

series4.AddXY(x1, f(x1), uD1(x1, f(x1)));

раскрыть ветку 2
0

series3.AddXY(x1, uD2(x1, g(x1)));

series4.AddXY(x1, uD1(x1, f(x1)));

раскрыть ветку 1
0

П - пикабушница

раскрыть ветку 1
+1

И какой же смысл здесь скрыт?

Я бы еще поняла Т, а П что значит?

Похожие посты
952

Delphi - 25 лет

Надо же, уже 25 лет прошло с тех пор, как появился Delphi.

Уже никто и не помнит, что тогда ни одна СУБД не содержала толкового языка программирования. И еще не существовало средств быстрой разработки пользовательского интерфейса. Т.е. те окошки, которые сейчас программист может нарисовать за 5 минут, требовали нескольких часов (а то и дней) программирования.

А еще - все ждали появления толкового средства разработки для Windows.

И вот - появился Delphi. Для Windows. C обновленным Паскалем. C фантастическими на тот момент возможностями по разработке интерфейса. С фантастически удобной средой.

И с возможностью работать с базами данных. Практически любыми! Что тогда тоже было почти фантастикой.

Само название - Delphi - намекало на то, что даже для самой мощной на тот момент СУБД - Oracle - это средство позволит построить всю нужную инфраструктуру. Как Дельфы вокруг Дельфийского оракула.

И сколько программистов перешло тогда с С и С++ на Delphi, вы бы видели!

Хочется сказать за это спасибо Филиппу Кану, основавшему Borland и выпустившему этот продукт.

Delphi - 25 лет Программирование, Delphi, Net
112

Вторая жизнь старому стрелочному мультиметру

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

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост
Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

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

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

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

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

Выбираем провод с более резким наклоном прямой. В моем случае получилось что при максимальном отклонении стрелки напряжение равно 96,4 мВ. Для оцифровки микроконтроллером мало, но ничего страшного, это напряжение можно усилить операционным усилителем. Подойдет любой ОУ, я взял LM2904, просто потому что у меня такой был. Смотрим документ на микросхему – два ОУ в одном корпусе, максимальное выходное напряжение Vcc-1.5v. Запитывать будем от 3.3 вольт, значит надо подобрать коэффициенты усиления так, чтобы при зашкаливающей стрелке ОУ выдавал максимально возможное напряжение.

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

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

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

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

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

На борту у нее микроконтроллер STM32F103C8T6. Есть АЦП и USB. Подходит. Для первоначальной настройки предлагаю воспользоваться STM32CubeMX. Включаем тактирование, настраиваем кварцевые резонаторы.

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

Включаем и настраиваем АЦП, не забываем про прерывание по готовности.

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

АЦП будет запускаться по событию таймера, настраиваем таймер.

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

Таймер тактируется частотой 48 МГц, с предделителем 24 и периодом 2000 получится, что он будет запускать АЦП каждую 1 мс. В принципе так часто нет смысла, но мы будем использовать усреднение значений, поэтому пусть будет. Включаем USB, выбираем Custom HID.

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

Генерируем проект и переходим к написанию кода. Я использовал System Workbench for STM32. Добавляем в «main.c» запуск таймера и АЦП, и несколько глобальных переменных.


/* USER CODE BEGIN PV */

//uint16_t adc_arr[ADC_MAX_CONVERSATIONS];

uint16_t adc_to_send;

uint32_t adc_sum;

uint8_t adc_counter;

uint8_t send_flag;

volatile uint16_t x;

/* USER CODE END PV */

/* USER CODE BEGIN 2 */

HAL_ADC_Start(&hadc1);

HAL_ADC_Start_IT(&hadc1);

HAL_TIM_Base_Start(&htim3);

/* USER CODE END 2 */


В прерывании прибавляем к переменной значение с АЦП и увеличиваем счетчик. Когда счетчик достигнет 200, усредняем значение и перекладываем в буфер для отправки по USB. Поднимем флаг, что пора отправлять.


/* USER CODE BEGIN 4 */

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){

adc_sum+=HAL_ADC_GetValue(hadc);

adc_counter++;

if(adc_counter==ADC_MAX_CONVERSATIONS){

HAL_GPIO_TogglePin(LD_1_GPIO_Port,LD_1_Pin);

adc_to_send=adc_sum/ADC_MAX_CONVERSATIONS;

adc_counter=0;

adc_sum=0;

send_flag=1;

}

}

/* USER CODE END 4 */


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


/* USER CODE BEGIN WHILE */

while (1)

{

// HAL_GPIO_TogglePin(LD_1_GPIO_Port,LD_1_Pin);

if(send_flag){

send_flag=0;

..USB_Send_report(adc_to_send);

}

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}


Дескриптор USB устройства уже создался стм кубом, его трогать не будем, только проверим интервал опроса, должно быть не больше наших 200 мс.


/* 34 */

0x07, /* bLength: Endpoint Descriptor size */

USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */

CUSTOM_HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/

0x03, /* bmAttributes: Interrupt endpoint */

CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */

0x00,

0x20, /* bInterval: Polling Interval (20 ms) */

/* 41 */


Далее составим «HID Report» дескриптор в программке HID Descriptor Tool.

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

Тут мы говорим, что наше устройство сообщает температуру в комнате (Usage). Report Size=8 и Report Count=4 означают, что 32 бита посылается от устройства к компьютеру (Input) и столько же от компьютера к устройству (Output). Нам из этого всего понадобится только 2 байта, остальное на будущее. Сохраняем как заголовочный файл, и копируем в наш код (куб там оставил место в файле usbd_custom_hid_if.c). Так же надо проверить соответствие размеров репорт дескриптора 35 байт и размер буфера под отправку (тут должно быть 5 байт, потому что мы еще указали Report ID – это еще 1 байт в самом начале). Прошьем и проверим, что устройство правильно определилось в системе.

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

Раскомментируем функцию отправки в файле «usbd_custom_hid_if.c» и заполняем, указав первым байтом Report ID, дальше наше значение АЦП.


/* USER CODE BEGIN 7 */

/**

* @brief Send the report to the Host

* @Param report: The report to be sent

* @Param len: The report length

* @retval USBD_OK if all operations are OK else USBD_FAIL

*/

static uint8_t USBD_CUSTOM_HID_SendReport_FS(uint8_t *report, uint16_t len)

{

return USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, report, len);

}

uint8_t USB_Send_report(uint16_t data){

Rep_buffer[0]=0x01;//report id

Rep_buffer[1]=data>>8;

Rep_buffer[2]=data;

Rep_buffer[3]=0xFF;

Rep_buffer[4]=0xFF;

return USBD_CUSTOM_HID_SendReport_FS(Rep_buffer,5);

}

/* USER CODE END 7 */


Проверяем в какой-нибудь утилитке что пакеты действительно идут.

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

Осталось написать программку под Windows, которая бы все это обрабатывала. Берем любимую среду программирования и библиотеку для работы с HID устройствами. Я взял старенькую Delphi 7 и библиотеку компонентов JEDI VCL. Из нее нужны «TJvHidDeviceController» и «TJvHidDevice». Добавляем обработчик «OnEnumerate» у девайс контроллера, в него по очереди прилетают все HID устройства при вызове энумерации. Остается отфильтровать наше устройство по VID и PID, затем связать с компонентом «TJvHidDevice».


function TUSBMeter.HidControllerEnumerate(HidDev: TJvHidDevice; const Idx: Integer): Boolean;

begin

if (IntToHex(HidDev.Attributes.VendorID,4)=VID)and

(IntToHex(HidDev.Attributes.ProductID,4)=PID) then

begin

if (HidDev.Caps.OutputReportByteLength=OUT_REPORT_COUNT_AMPERAGE) then

HidController.CheckOutByIndex(HidAmperage,Idx);

usb_ready:=true;

end;

Result := True;

end;


Данные будут приходить в обработчик «OnDeviceData». В нем вычисляем из посылки значение АЦП и выводим куда-нибудь для проверки.


procedure TUSBMeter.HidControllerDeviceData(HidDev: TJvHidDevice; ReportID: Byte; const Data: Pointer; Size: Word);


var

buf:^byte;

begin

if (IntToHex(HidDev.Attributes.VendorID,4)<>VID)or((IntToHex(HidDev.Attributes.ProductID,4)<>PID)) then exit;

buf:=Data; // rep

adc_abs:=buf^;

adc_abs:= adc_abs shl 8;

inc(buf);

adc_abs:=adc_abs+(buf^);

inc(buf);

callback;

end;


Теперь надо сделать пересчет, добавим на форму RadioGroup и настроим как на переключателе мультиметра. Я не стал добавлять шкалу сопротивлений, не нужна.

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

Заведем так же масштабирующий массив для пересчета и массив с единицами измерений.


const

scale_arr: array[1..18] of real = (600,300,150,60,30,15,6,3,0.75,1500,300,60,15,3,0.6,0.12,0.000012,1);

scale_arr_symb: array[1..18] of string[2] = ('V','V','V','V','V','V','V','V','V','mA','mA','mA','mA','mA','mA','mA','uA','');


Для пересчета еще понадобятся два граничных значения acd_min и adc_max. Подключаем потенциометр к мультиметру, выставляем стрелку на 0 и смотрим, что присылается в программу. Если тоже 0 – хорошо, если нет – не беда, подкорректируем. Потом выставляем стрелку на максимум и так же смотрим. Важно чтобы когда стрелка «зашкаливала» значение продолжало увеличиваться, так будет запас. Если этого нет, надо подкрутить потенциометр ОУ. У меня получилось 0 и 2365. Пересчитываем и выводим уже на основное табло.


procedure TMainForm.HID_Callback;

var

s:string;

buf:string;

rec_s:string;

begin

s:=floattostr(((meter.ADC-adc_min)/(adc_max-adc_min))*scale_arr[RadioGroup1.ItemIndex+1]);

buf:=copy(s,1,5);

buf[pos(',',buf)]:='.';

Label2.Caption:=buf;

end;

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост
Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост
Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

Большая часть готова, теперь надо прикрутить запись в файл, страницу настроек с сохранением и красивый GUI. Формат файла я взял CSV, так как из него будет легко строить графики в Экселе.

Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост
Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост
Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост
Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост
Вторая жизнь старому стрелочному мультиметру Мультиметр, Новая жизнь старых вещей, Схемотехника, Микроконтроллеры, Arduino, Stm32, Delphi, Программирование, Видео, Длиннопост

Все, готово. Осталось собрать все в корпус мультиметра, свободного места там полно. Прорезать отверстие под USB шнурок и убрать обратно на самую дальнюю полку до тех пор, пока не понадобится снять долгий график разряда аккумулятора или график потребления тока каким-нибудь устройством.


Надеюсь, кому-нибудь будет полезно.

Показать полностью 21 1
Похожие посты закончились. Возможно, вас заинтересуют другие посты по тегам: