I'm using a Pro Mini as an I2C slave, which computes a double. This double is requested by the ESP8266 WiFi module and it's sent over I2C byte by byte.
Now I'm trying to reassemble the double at the other end but it's not working.
Current code running on ESP8266:
// ABOVE SETUP
union {
byte bytes[4];
double value;
} bytedouble;
// IN LOOP
while(Wire.available()){
byte read = Wire.read();
bytedouble.bytes[num] = read;
num++;
}
Serial.println(bytedouble.value); // Returns ovf/overflow
I found out a double on the Arduino Pro Mini is 4 bytes but 8 bytes on the ESP8266. Can I convert this?
ESP8266 is 32 bit processor so sizeof(int) is 4 and sizeof(double) is 8. On ATmega328 sizeof(int) is 2 and sizeof(double) is 4. However, on both processors sizeof(float) is 4 and that is why you could use that workaround you mentioned in the comment.
Since you are dealing with integer numbers it would be better to just use int or uint32_t instead of double in ESP8266's code so the length will be the same as Arduino's double. That way you can avoid using floats which generates quite a few bytes of code that is unnecessary.
Related
I have interfaced I2S mic (ICS-43434) with STM32f401RET6 board.
I have wired it correctly, now just trying to test the mic by passing the data through UART to my pc. Hoping someone can point me in the correct direction.
I have tried passing straight to the UART transmit. However I think I may need some datahandling - I am receiving from the UART, but sometimes just 0 or other times just gibberish which is not from the Mic as it still transmits even when i disconnect the mic.
I2S mic is receiving data in 24 bits in 32 bit frame, the last 8 bits are junk. The protocol is Big Endian, I am thinking that the HAL library handles this, however I am not completely sure.
uint16_t data;
while (1)
{
/*USER CODE END WHILE */
HAL_StatusTypeDef result= HAL_I2S_Receive(&hi2s1,&data,2,100);
HAL_UART_Transmit(&huart3,&data,2,100);
/*USER CODE BEGIN 3 */
}
/*USER CODE END 3 */
What did I miss?
I can't get the SPI on my STM32f3 discovery board (Datasheet) to work with gyroscope sensor (I3G4250D) on the register level. I know I'm sending data since I'm in full duplex and receiving dummy bytes from sensor using 16 bit data packing but when I try to receive using 8 bit access to DR register I get inconsistent values from sensor, sometimes returning one byte 0xff and other times returning 2 bytes 0xffff (at least I think that's what's happening) but no real values from from the sensor register I want to read. I think this has to do with automatic packing of STM32 SPI on my chip but I think I am addressing that by accessing DR register with uint8_t* but it doesn't seem to work. I also want to ask that when I compare the SPI protocol on sensor (datasheet page 24) and STM32 datasheet (page 729) I infer that both CPOL (clock polarity) and CPHA (clock phase) bits in STM32 SPI should be set but I seem to be able to at least send data with or without these bits set...
Here is my SPI Initialization function which includes trying to read bytes at the end of it and a write a byte to sensor register function:
void SPI_Init() {
/* Peripheral Clock Enable */
RCC->AHBENR |= RCC_AHBENR_GPIOEEN|RCC_AHBENR_GPIOAEN;
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
/* GPIO Configuration */
GPIOA->MODER |= GPIO_MODER_MODER5_1|GPIO_MODER_MODER6_1|GPIO_MODER_MODER7_1; //Alternate function
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5|GPIO_OSPEEDER_OSPEEDR6|GPIO_OSPEEDER_OSPEEDR7; //High speed
GPIOA->AFR[0] |= 0x00500000|0x05000000|0x50000000; //AF for SCK,MISO,MOSI
GPIOE->MODER |= GPIO_MODER_MODER3_0; //Port E for NSS Pin
GPIOE->MODER |= GPIO_MODER_MODER3_0;
/* SPI Configuration */
SPI1->CR2 |= SPI_CR2_FRXTH|SPI_CR2_RXDMAEN; //Enable DMA but DMA is not used
// not sure if I need this?|SPI_CR1_CPOL|SPI_CR1_CPHA;
SPI1->CR1 |= SPI_CR1_BR_1|SPI_CR1_SSM|SPI_CR1_SSI|SPI_CR1_MSTR|SPI_CR1_SPE; //big endian, SPI#6MH, since using software set SPI_CR1_SSI to high for master mode
/* Slave Device Initialization */
SPI_WriteByte(CTRL_REG1_G,0x9f);
SPI_WriteByte(CTRL_REG4_G,0x10);
SPI_WriteByte(CTRL_REG5_G,0x10);
//receive test
uint8_t test =0xff;
uint8_t* spiDrPtr = (__IO uint8_t*)&SPI1->DR;
*spiDrPtr = 0x80|CTRL_REG1_G;
while(!(SPI1->SR & SPI_SR_TXE)){}
//SPI1->CR2 &= ~(SPI_CR2_FRXTH); //this is done in HAL not sure why though
*spiDrPtr = test; //Send dummy
while(!(SPI1->SR & SPI_SR_RXNE)){}
test = *spiDrPtr;
}
static void SPI_WriteByte(uint8_t regAdd, uint8_t data) {
uint8_t arr[2] = {regAdd,data}; //16 bit data packing
SPI1->DR = *((uint16_t*)arr);
}
Any suggestions?
Do not enable DMA if you do not use it.
You need to force 16 bit access (not 32 bits)
static void SPI_WriteByte(uint8_t regAdd, uint8_t data) {
uint8_t arr[2] = {regAdd,data}; //16 bit data packing
*(volatile uint16_t *)&SPI1->DR = *((volatile uint16_t*)arr);
}
Try using FRXTH = 0, and do all DR reads and writes in 16-bit words, then just discard the first byte.
To the later question, about CPOL/CPHA. These bits control SPI transfer format on the bit level. Refer to the following image (from wikipedia).
CPOL = 0, CPHA = 0 is also called "SPI mode 0", data bits are sampled on the SCK rising edge
CPOL = 1, CPHA = 1 is also called "SPI mode 3", data bits are also sampled on the rising edge.
The difference between two modes is SCK level between transfers, and an extra falling edge before the first bit.
Some chips states explicitly that both mode 0 and mode 3 are supported. Yet in the I3G4250D datasheet, section 5.2: "SDI and SDO are,
respectively, the serial port data input and output. These lines are driven at the falling edge
of SPC and should be captured at the rising edge of SPC."
When data is sent to the chip from mcu in mode 0, mcu drives the MOSI line before the first rising edge. Thus a slave chip can recieve valid data in both mode 0 and mode 3. But when data is transfered from chip to the mcu, chip may need the first falling SCK edge to shift/latch first data bit to the MISO line and with mode 0 you'll receive the readings shifted on one bit.
I've emphasised 'may' word, because the chip could still work correcly in both modes, latching the first bit with falling nSS-edge, the manufacturer just didn't do the testings, or doesn't guarantees that it'll work with other revisions and in all conditions.
I am looking for something like a datasheet for the R444A01 modbus rtu protocol. I want to implement a tool to read the temperature and the Humidity of this sensor.
the only thing what I could found is something like this: https://www.mikrocontroller.net/attachment/376848/datenBlatt_teil2.pdf
But to implement the tool I miss information about the modbus register definitions like Modbus address, which register stores which information and how many bytes are used.
May someone have some information about this sensor.
https://www.aliexpress.com/item/33054683552.html shows the R444A01 modbus RTU communication protocol. I could not find a proper datasheet either.
Quoting one of the reviewers from https://www.amazon.co.uk/Temperature-Humidity-humidity-temperature-External/dp/B078PHLR4T:
Supply voltage: DC 5-40V (recommended 6.5-28V) MODBUS RTU protocol, 03
read command, 06 write command. Serial port baud rate: 9600 (default),
N, 8, 1
Temperature Register Address 0x0000 (2 bytes) Humidity Register
Address 0x0001 (2 bytes) RS485 Address 0x0002 (2 bytes) Baud Rate
0x0003 (2 bytes)
Baud Rate Table : 0:1200 / 1:2400 / 2:4800 / 3:9600(default) / 4:
19200
Values returned in temperature is a SIGNED two byte value meaning that
a 1 in the highest bit indicates a negative temperature. Divide by 10
(decimal) to get the actual value
Values returned in humidity is an UNSIGNED two byte value. Divide
by 10 (decimal) to get the actual value
How would I convert a 16K x 32 SRAM into a 64K x 8 SRAM? The 16K x 32 RAM module is a single unit that cannot be altered internally and is capable of address decoding, has tristate outputs, and read/write/and chip enable. Also only the memory read of the circuit has to be implemented.
The 16K x 32 SRAM accepts a 14-bit address and produces a 32-bit value. However, the 64K x 8 SRAM accepts a 16-bit address and produces an 8-bit value. You can design a circuit whose interface exactly matches the interface of a 64K x 8 SRAM module. However, internally, it sends the most significant 14 bits of the supplied 16-bit address to the 16K x 32 SRAM together with the control signals. Then it uses the least significant 2 bits of the 16-bit address to select an 8-bit value from the 32-bit value produced by the 16K x 32 SRAM. Finally, the resulting 8-bit value is sent to the output pins of the circuit.
I want to transmit float data from matlab gui to pic16f877A using uart.
i went through google and got some examples but i am not able to understand exactly how 4bytes(float) be transmitted to pic and inside pic how to recombine those 4 bytes to read a float data.Is there a simple way to understand the transmission of float .
UART transmission is always made by sending bytes (byte array) one by one. So basically you need to convert your float number to four raw bytes. Keep in mind that float is already written (in memory) as four bytes. So if you make byte pointer to location of your float variable and take for bytes from that address you will get four bytes of your float number. Next what you need to do is to transmit byte per byte over UART. When you have byte array received on PIC side you can make float pointer to address of first byte of your array and get the value.
I hope this helps.
Also, please check following link which solves similar issue
C Function to Convert float to byte array