Matrisberäkningar med för STM32?
Re: Matrisberäkningar med för STM32?
Jag har kört libusb för en massa år sedan när några hade kommit på att en helt vanlig ATmega med intern oscillator kunde "bit-banga" USB. Men det är länge sedan, och jag satte inte in mig i det särskilt djupt. Men jag föreslår att kopiera exempelprogram (både på PC och STM-sidan) rakt av att utgå ifrån. Som förhoppningsvis fungerar direkt. När väl det fungerar kan du övergå till att göra din egna specialkod.
- Krille Krokodil
- Inlägg: 4062
- Blev medlem: 9 december 2005, 22:33:11
- Ort: Helsingborg
Re: Matrisberäkningar med för STM32?
Beräkningarna är inget större problem längre eftersom att den nya generationen PLC:er har processorer på > 1 GHz och RAM på 10-100-tals MB. Men går man bara några år tillbaka så rymdes där knappt mer än en PID, RAM på 8 kB eller så...guckrum skrev:Om man tittar förbi den teoretiska matematiken ser jag ett antal
praktiska problem som behöver adresseras, förutom att det
beräkningsmässigt är väldigt kostsamt.
Har bl a kommit matrisbibibliotek till Codesys nu samt att man kan programmera OO, man börjar få lite mer PC-lika möjligheter på de industriella plattformarna nu.
Re: Matrisberäkningar med för STM32?
Någon här som kan testa denna kod? Jag ska ha detta för mitt STM32 projekt där STM:en ska fungera som I/O modul. Men då måste jag kunna tala med den först.
https://github.com/Mathias-L/STM32F4-li ... ple/test.c
Allt ni gör är bara ändra
Till vad ni vill kommunicera med. Ni kan hitta vendor och product från.
https://github.com/Mathias-L/STM32F4-li ... ple/test.c
Allt ni gör är bara ändra
Kod: Markera allt
#define USB_VENDOR_ID 0x0483 /* USB vendor ID used by the device
* 0x0483 is STMs ID
*/
#define USB_PRODUCT_ID 0xFFFF /* USB product ID used by the device */
Kod: Markera allt
#include <stdio.h>
#include <stdlib.h>
#include <libusb-1.0/libusb.h>
#include <string.h>
libusb_context *CONTEXT; //a libusb session
libusb_device_handle *DEVICEHANDLE; //a device handle
libusb_device * DEVICE_POINTER; // a pointer to a device
libusb_device **ARRAY_OF_POINTERS_TO_DEVICE; // an array of pointers to devices
ssize_t NUMBER_OF_USB_DEVICES; // Initial zero devices
static uint8_t receiveBuf[64];
uint8_t transferBuf[64];
uint16_t counter = 0;
#define USB_ENDPOINT_IN 0x80 /* endpoint address */
#define USB_ENDPOINT_OUT 0x01 /* endpoint address */
#define USB_TIMEOUT 3000 /* Connection timeout (in ms) */
#define USB_VENDOR_ID 0x0483
#define USB_PRODUCT_ID 0x374b /* USB product ID used by the device */
/*
* Here we are going to read the USB
*/
int readUSB() {
int nread, r, counter = 0;
nread = 64;
unsigned char data[64];
r = libusb_bulk_transfer(DEVICEHANDLE, USB_ENDPOINT_IN, data, nread, &nread, USB_TIMEOUT);
if (LIBUSB_ERROR_TIMEOUT == r) {
printf("LIBUSB_ERROR_TIMEOUT = %d\n", r);
return -1;
}else if(LIBUSB_ERROR_PIPE == r){
printf("LIBUSB_ERROR_PIPE = %d\n", r);
return -1;
}else if(LIBUSB_ERROR_OVERFLOW == r){
printf("LIBUSB_ERROR_OVERFLOW = %d\n", r);
return -1;
}else if(LIBUSB_ERROR_NO_DEVICE == r){
printf("LIBUSB_ERROR_NO_DEVICE = %d\n", r);
return -1;
}else if(LIBUSB_ERROR_IO == r){
printf("LIBUSB_ERROR_IO = %d\n", r);
return -1;
} else {
printf("r = %d, %d receive %d bytes from device: %s\n", r, ++counter, nread, data);
return 0;
}
return 0;
}
/*
* Here are we going to write to the USB
*/
int writeUSB() {
int n, ret;
uint16_t count = 0;
//count up
n = sprintf(transferBuf, "%d\0", count++);
//write transfer
//probably unsafe to use n twice...
ret = libusb_bulk_transfer(DEVICEHANDLE, USB_ENDPOINT_OUT, transferBuf, n,
&n, USB_TIMEOUT);
//Error handling
switch (ret) {
case 0:
printf("send %d bytes to device\n", n);
return 0;
case LIBUSB_ERROR_TIMEOUT:
printf("ERROR in bulk write: %d Timeout\n", ret);
break;
case LIBUSB_ERROR_PIPE:
printf("ERROR in bulk write: %d Pipe\n", ret);
break;
case LIBUSB_ERROR_OVERFLOW:
printf("ERROR in bulk write: %d Overflow\n", ret);
break;
case LIBUSB_ERROR_NO_DEVICE:
printf("ERROR in bulk write: %d No Device\n", ret);
break;
default:
printf("ERROR in bulk write: %d\n", ret);
break;
}
return -1;
return 0;
}
/*
* This will connect to our USB device
*/
int connectUSB() {
libusb_init(&CONTEXT);
//libusb_set_debug(CONTEXT, 3);
//Open Device with VendorID and ProductID
DEVICEHANDLE = libusb_open_device_with_vid_pid(CONTEXT, USB_VENDOR_ID, USB_PRODUCT_ID);
if (DEVICEHANDLE == NULL) {
perror("DEVICEHANDLE == NULL");
return -1;
}
int r = 1;
//Claim Interface 0 from the device
r = libusb_claim_interface(DEVICEHANDLE, 0);
if (r == LIBUSB_ERROR_NOT_FOUND) {
fprintf(stderr, "LIBUSB_ERROR_NOT_FOUND = %d\n", r);
return -1;
}else if(r == LIBUSB_ERROR_BUSY){
fprintf(stderr, "LIBUSB_ERROR_BUSY = %d\n", r);
return -1;
}else if(r == LIBUSB_ERROR_NO_DEVICE){
fprintf(stderr, "LIBUSB_ERROR_NO_DEVICE = %d\n", r);
return -1;
}
printf("Interface claimed\n");
return 0;
}
/*
* This will show all the devices for USB and send it thru sockets
*/
int getDevices() {
/*
* Special local device handle for only get the name of the USB device
*/
libusb_device_handle *DEVICEHANDLE_NULL; //a device handle
/*
* Compute the number of USB
*/
int returnValue = libusb_init(NULL);
NUMBER_OF_USB_DEVICES = libusb_get_device_list(NULL,
&ARRAY_OF_POINTERS_TO_DEVICE);
/*
* Create our list of Vendor, Product and device
* Vendor and product are important for connect the USB and device is important for the user to see which USB to connect
*/
uint16_t vendor[NUMBER_OF_USB_DEVICES];
uint16_t product[NUMBER_OF_USB_DEVICES];
char device[NUMBER_OF_USB_DEVICES][256 * 2];
/*
* Loop thru all USB devices
*/
ssize_t deviceIndex = 0;
while (deviceIndex < NUMBER_OF_USB_DEVICES) {
/*
* Get the description of the USB device
*/
DEVICE_POINTER = ARRAY_OF_POINTERS_TO_DEVICE[deviceIndex];
struct libusb_device_descriptor deviceDescriptor;
returnValue = libusb_get_device_descriptor(DEVICE_POINTER,
&deviceDescriptor);
if (returnValue != LIBUSB_SUCCESS)
break;
/*
* Open the USB device with NULL. It's only because we want the name of the USB device
*/
DEVICEHANDLE_NULL = NULL;
returnValue = libusb_open(DEVICE_POINTER, &DEVICEHANDLE_NULL);
if (returnValue != LIBUSB_SUCCESS) {
/*
* There was an error. Not success.
*/
if (DEVICEHANDLE_NULL != NULL) {
libusb_close(DEVICEHANDLE_NULL);
DEVICEHANDLE_NULL = NULL;
}
/*
* Write as there was no info at all to display
*/
product[deviceIndex] = 0;
vendor[deviceIndex] = 0;
memcpy(device[deviceIndex], "-", 256 * 2 * sizeof(char));
deviceIndex++;
continue;
}
/*
* Get the string associated with iManufacturer index.
*/
const int STRING_LENGTH = 256;
unsigned char stringManufacturer[STRING_LENGTH];
unsigned char stringProduct[STRING_LENGTH];
char stringDeviceName[STRING_LENGTH * 2];
if (DEVICEHANDLE_NULL != NULL && deviceDescriptor.iManufacturer > 0) {
returnValue = libusb_get_string_descriptor_ascii(DEVICEHANDLE_NULL,
deviceDescriptor.iManufacturer, stringManufacturer,
STRING_LENGTH);
if (returnValue < 0)
break;
}
/*
* Get string associated with iProduct index.
*/
if (DEVICEHANDLE_NULL != NULL && deviceDescriptor.iProduct > 0) {
returnValue = libusb_get_string_descriptor_ascii(DEVICEHANDLE_NULL,
deviceDescriptor.iProduct, stringProduct, STRING_LENGTH);
if (returnValue < 0)
break;
}
/*
* Combine manufacturer and product
*/
strcpy(stringDeviceName, (char*) stringManufacturer);
strcat(stringDeviceName, " "); // a space only
strcat(stringDeviceName, (char*) stringProduct);
//printf("%s\n", stringDeviceName);
/*
* Save them all into arrays
*/
product[deviceIndex] = deviceDescriptor.idProduct;
vendor[deviceIndex] = deviceDescriptor.idVendor;
memcpy(device[deviceIndex], stringDeviceName, 256 * 2 * sizeof(char));
/*
* Close and try next one.
*/
if (DEVICEHANDLE_NULL != NULL) {
libusb_close(DEVICEHANDLE_NULL);
DEVICEHANDLE_NULL = NULL;
}
/*
* Next USB device
*/
deviceIndex++;
}
/*
* Print our result what we found and send them to socket
*/
for (int i = 0; i < 11; i++) {
printf("Name: %s\n", device[i]);
printf("Vendor: %u\n", vendor[i]);
printf("Product: %u\n\n", product[i]);
}
libusb_exit(NULL);
return 0;
}
Re: Matrisberäkningar med för STM32?
Jag har lyckats få USB kommunikation nu. Dock inte via libusb, utan via termios. Termios är endast för Linux.
https://blog.mbedded.ninja/programming/ ... ing-c-cpp/
https://blog.mbedded.ninja/programming/ ... ing-c-cpp/
Re: Matrisberäkningar med för STM32?
Anänvder du USB UART eller har lagt in USB stack i STM32?
Re: Matrisberäkningar med för STM32?
USB UART använder jag. Det är väll det som är RX och TX?
Re: Matrisberäkningar med för STM32?
Nu när det börjar nämnas PLC.
Du kan ju kolla om Wagos PFC200 serie skulle kunna passa för dig.
Senaste kvalisort skall finnas med 1GHz ARM-processor.
Det är ett linux operativsystem med Preempt-rt patch, så du kan kompilera C/C++ och köra direkt i operativsystemet, man kan skippa Codesys helt om man vill.
Ett plus är att i SDKn så finns det även drivrutiner för K-Bussen och alla deras IO-kort, för att komma ut i verkligheten.
Hårdvara som är gjort för industriella applikationer.
Du kan ju kolla om Wagos PFC200 serie skulle kunna passa för dig.
Senaste kvalisort skall finnas med 1GHz ARM-processor.
Det är ett linux operativsystem med Preempt-rt patch, så du kan kompilera C/C++ och köra direkt i operativsystemet, man kan skippa Codesys helt om man vill.
Ett plus är att i SDKn så finns det även drivrutiner för K-Bussen och alla deras IO-kort, för att komma ut i verkligheten.
Hårdvara som är gjort för industriella applikationer.
Re: Matrisberäkningar med för STM32?
Tack för tipset. Jag ska lägga detta på minne när jag vill implementera detta
Men för nuvarande så blir det en gammal dator.
Men för nuvarande så blir det en gammal dator.
Re: Matrisberäkningar med för STM32?
Nu när jag har fått USB kommunikationen att fungera.
Då undrar jag hur jag ska göra om jag ständigt läser typ så här:
Jag skickar alltså en sträng som ser ut så här "adc1,adc2,adc3" där adcX byts ut till ett nummer mellan 0 till 4095. Jag har tänkt att jag läser och skriver hela tiden till USB porten. Men jag ändrar värdena som jag skriver och använder det lästa värdet vid vid ett visst samplingsintervall.
Läser jag sista värdet eller? Även i Linux förekommer det samma sak.
Då undrar jag hur jag ska göra om jag ständigt läser typ så här:
Kod: Markera allt
Read 11 bytes. Received message:
Read 11 bytes. Received message: 1205,1173
3
Read 10 bytes. Received message:
Read 12 bytes. Received message: 184,1116
Read 10 bytes. Received message:
Read 12 bytes. Received message: 0,1148
Read 2 bytes. Received message: 121148
Read 18 bytes. Received message: 82,1199,1141
Read 12 bytes. Received message: 1241,1235,11
Read 10 bytes. Received message: 68
Read 12 bytes. Received message: 80,1185,1125
Read 10 bytes. Received message:
Read 11 bytes. Received message: ,1172,1116
5
Read 65 bytes. Received message:
Read 21 bytes. Received message: 1257,1260,1186
Read 22 bytes. Received message: 244,1221,1170
Read 12 bytes. Received message: 8,1217,1177
0
Read 31 bytes. Received message:
Read 12 bytes. Received message: 198,1154
Read 10 bytes. Received message:
Read 10 bytes. Received message: 4,1152
Read 12 bytes. Received message:
Läser jag sista värdet eller? Även i Linux förekommer det samma sak.
Kod: Markera allt
dell@dell-Precision-M6400:/dev$ cat < /dev/ttyACM0
0,1147
1253,1250,1179
1233,1181,1154
1237,1219,1157
1227,1213,1155
1209,1098,1068
1288,1216,1146
1285,1185,1125
1245,1164,1096
1300,1251,1150
1269,1232,1139
1260,1266,1182
1233,1242,1152
1286,1232,1149
1240,1190,1161
1256,1225,1174
1275,1181,1130
1252,1223,1167
1275,1189,1139
1244,1235,1169
1262,1189,1115
1268,1235,1124
9,1164
1285,1212,1133
1294,1245,1142
1252,1266,1165
1261,1197,1116
1292,1216,1150
osv
Re: Matrisberäkningar med för STM32?
Det är väl någon som inte hänger med när det blir så. Om du genererar värden för snabbt kanske.
Re: Matrisberäkningar med för STM32?
Du menar att jag läser för snabbt? Så här ser det ut med 1 sekunds läshastighet.
Kod: Markera allt
Read 11 bytes. Received message: ,1213,1137
Read 256 bytes. Received message:
Read 256 bytes. Received message: 161
Read 256 bytes. Received message:
Read 256 bytes. Received message: 1
Read 256 bytes. Received message: ,1144
Read 256 bytes. Received message: 1211,1142
Read 256 bytes. Received message: 225,1213,1153
Read 256 bytes. Received message:
Read 256 bytes. Received message: 6
Read 256 bytes. Received message: ,1152
Read 256 bytes. Received message: 1208,1118
Read 256 bytes. Received message: 237,1254,1169
Read 256 bytes. Received message:
Read 256 bytes. Received message: 4
Re: Matrisberäkningar med för STM32?
Du kan ju börja med att reda ut varför den säger att den läser 10 bytes tex men inte skriver ut något.
Vad innehöll de 10 tecken som den inte skrev ut?
Vad innehöll de 10 tecken som den inte skrev ut?
Re: Matrisberäkningar med för STM32?
Jag kan lägga upp mitt projekt så kan ni testköra. Kör ni Linux?
Jag har ingen aning varför den gör så. Koden ser ut så här. Kolla vid readUSB funktionen.
Jag har ingen aning varför den gör så. Koden ser ut så här. Kolla vid readUSB funktionen.
Kod: Markera allt
#include "logicFunctions.h"
/*
* Here we are going to read the USB
*/
int readUSB(struct USB* stm32) {
/*
* Reset
*/
while(1){
memset(&stm32->readBuffer, '\0', sizeof(stm32->readBuffer));
/*
* Read
*/
int receiveBytes = read(stm32->serialPort, &stm32->readBuffer, 14);
/*
* receiveBytes is the number of bytes read. receiveBytes may be 0 if no bytes were received, and can also be -1 to signal an error.
*/
if (receiveBytes < 0) {
printf("Error reading: %s", strerror(errno));
}
/*
* Print it out
*/
printf("Read %i bytes. Received message: %s\n", receiveBytes, stm32->readBuffer);
sleep(1);
}
return 0;
}
/*
* Here are we going to write to the USB
*/
int writeUSB(struct USB* stm32) {
/*
* Write the ASCII string of 3 signs
*/
ssize_t sendBytes = write(stm32->serialPort, stm32->messageBuffer, sizeof(stm32->messageBuffer));
/*
* receiveBytes is the number of bytes read. receiveBytes may be 0 if no bytes were received, and can also be -1 to signal an error.
*/
if (sendBytes < 0) {
printf("Error reading: %s", strerror(errno));
}
return 0;
}
/*
* This will connect to our USB device
*/
int connectUSB(struct USB* stm32) {
/*
* Open the serial port. Change device path as needed (currently set to an standard FTDI USB-UART cable type device)
*/
stm32->serialPort = open("/dev/ttyACM0", O_RDWR);
/*
* Reset the tty structure
*/
memset(&stm32->tty, 0, sizeof(stm32->tty));
/*
* Read in existing settings, and handle any error
*/
if (tcgetattr(stm32->serialPort, &stm32->tty) != 0) {
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
return -1;
}
stm32->tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)
stm32->tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication (most common)
stm32->tty.c_cflag |= CS8; // 8 bits per byte (most common)
stm32->tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control (most common)
stm32->tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
stm32->tty.c_lflag &= ~ICANON;
stm32->tty.c_lflag &= ~ECHO; // Disable echo
stm32->tty.c_lflag &= ~ECHOE; // Disable erasure
stm32->tty.c_lflag &= ~ECHONL; // Disable new-line echo
stm32->tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
stm32->tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
stm32->tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR
| ICRNL); // Disable any special handling of received bytes
stm32->tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
stm32->tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
// stm32->tty.c_oflag &= ~OXTABS; // Prevent conversion of tabs to spaces (NOT PRESENT ON LINUX)
// stm32->tty.c_oflag &= ~ONOEOT; // Prevent removal of C-d chars (0x004) in output (NOT PRESENT ON LINUX)
stm32->tty.c_cc[VTIME] = 10; // Wait for up to 1s (10 deciseconds), returning as soon as any data is received.
stm32->tty.c_cc[VMIN] = 0;
/*
* Set in/out baud rate to be 115200
*/
cfsetispeed(&stm32->tty, B115200);
cfsetospeed(&stm32->tty, B115200);
/*
* Save tty settings, also checking for error
*/
if (tcsetattr(stm32->serialPort, TCSANOW, &stm32->tty) != 0) {
printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
return -1;
}
/*
* Success!
*/
printf("Connected to USB\n");
return 0;
}
/*
* This will show all the devices for USB and send them via modbus
*/
int getDevices(struct USB* stm32) {
/*
* structure, class and initial deceleration
*/
DIR *directory;
struct dirent *dir;
directory = opendir("/dev");
stm32->countDevices = 0;
stm32->maxDevices = 100;
memset(stm32->devices, '\0', sizeof(stm32->devices));
/*
* Read all files in Linux folder /dev
*/
while ((dir = readdir(directory)) != NULL) {
// If dir->d_name contains "tty"
if (strstr(dir->d_name, "tty")) {
/*
* Copy d_name into devices array. First string copy, then string cat for the rest
* Every d_name have size of char 256.
*/
if (stm32->countDevices == 0) {
strcpy(stm32->devices[stm32->countDevices], dir->d_name);
} else {
strcat(stm32->devices[stm32->countDevices], dir->d_name);
}
stm32->countDevices++;
if (stm32->countDevices >= stm32->maxDevices)
break; // Can only store maximum 100 devices. Change that? Go to struct USB
}
}
closedir(directory); // Close
return 0;
}
Re: Matrisberäkningar med för STM32?
Blir dina sizeof verkligen rätt i den där koden?
Kör några printf för att kolla om dom verkligen är rätt.
Tror du bara får storleken på en pekare, men jag är osäker.
Kör några printf för att kolla om dom verkligen är rätt.
Tror du bara får storleken på en pekare, men jag är osäker.
Re: Matrisberäkningar med för STM32?
Kan titta på det i morgon först. Det är förbjudet att dricka öl och programmera. Jag lyder detta.