Matrisberäkningar med för STM32?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
bearing
Inlägg: 11232
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Matrisberäkningar med för STM32?

Inlägg av bearing »

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.
Användarvisningsbild
Krille Krokodil
Inlägg: 4062
Blev medlem: 9 december 2005, 22:33:11
Ort: Helsingborg

Re: Matrisberäkningar med för STM32?

Inlägg av Krille Krokodil »

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.
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å...

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.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av Al_Bundy »

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

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 */
Till vad ni vill kommunicera med. Ni kan hitta vendor och product från.

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;
}
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av Al_Bundy »

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/
Rick81
Inlägg: 746
Blev medlem: 30 december 2005, 13:07:09

Re: Matrisberäkningar med för STM32?

Inlägg av Rick81 »

Anänvder du USB UART eller har lagt in USB stack i STM32?
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av Al_Bundy »

USB UART använder jag. Det är väll det som är RX och TX?
Användarvisningsbild
Erikk
Inlägg: 63
Blev medlem: 1 april 2011, 12:13:40

Re: Matrisberäkningar med för STM32?

Inlägg av Erikk »

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.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av Al_Bundy »

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. :)
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av Al_Bundy »

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:

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: 
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.

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
Användarvisningsbild
hawkan
Inlägg: 2586
Blev medlem: 14 augusti 2011, 10:27:40

Re: Matrisberäkningar med för STM32?

Inlägg av hawkan »

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.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av Al_Bundy »

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

Användarvisningsbild
AndLi
Inlägg: 17049
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av AndLi »

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?
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av Al_Bundy »

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.

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;
}
bearing
Inlägg: 11232
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Matrisberäkningar med för STM32?

Inlägg av bearing »

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.
Användarvisningsbild
hawkan
Inlägg: 2586
Blev medlem: 14 augusti 2011, 10:27:40

Re: Matrisberäkningar med för STM32?

Inlägg av hawkan »

Kan titta på det i morgon först. Det är förbjudet att dricka öl och programmera. Jag lyder detta.
Skriv svar