I've tried to read everything including this post:
2D-array as argument to function
I'm getting error: "cannot convert 'float' to 'float ()[8]' for argument '1' to 'float pzemGetter(float ()[8], PZEM004Tv30, byte)'"
Anyway, I couldn't make this code to work with arduino mega and pzem-004t v3 module... I'm just interested to get it in such way only to get a flexible code when using loops and things like that
`#include <PZEM004Tv30.h>`
`byte disabled = 150;`
`byte enabled = 180;`
`byte busyIndex = 0; //To ensure arduino mega is not busy before sending float array from PZEM`
`#define FLOATS_SENT 8`
`//============Arrays definition to be reported to raspberry through serial connection`
`float pzemGroup[8][8]; //A testing way to group pzem modules into array of arrays`
`byte statusArray[32];`
`PZEM004Tv30 pzemFrameGroup[] = {PZEM004Tv30(&Serial3, 0x42), PZEM004Tv30(&Serial3, 0x43),`
` PZEM004Tv30(&Serial3, 0x44), PZEM004Tv30(&Serial3, 0x45),`
` PZEM004Tv30(&Serial3, 0x46), PZEM004Tv30(&Serial3, 0x47),`
` PZEM004Tv30(&Serial3, 0x48), PZEM004Tv30(&Serial3, 0x49)`
};
`void setup() {`
`Serial.begin(115200); //This is the speed for serial monitoring`
`Serial2.begin(9600); //Speed for serial comm with raspberry pi through USB Serial FTDI adapter`
`delay(200);`
`}`
`void loop() {`
`pzemGetter(pzemGroup[3][], pzemFrameGroup[0], busyIndex = 8);`
`float testValue1 = pzemGroup[3][0];`
`float testValue2 = pzemGroup[3][1];`
`float testValue3 = pzemGroup[3][2];`
`}//End loop function`
`//Function definition to get data from energy modules pzem004t installed in the same bus`
`float pzemGetter (float (*frmEnergy)[8], PZEM004Tv30 pzemModule, byte busyFlagLocator) {`
`statusArray[busyFlagLocator] = enabled;`
`frmEnergy[0][0] = 26.10; //I added this one as a personal initial element verification in raspberry`
`frmEnergy[0][1] = pzemModule.voltage();`
`frmEnergy[0][2] = pzemModule.power();`
`frmEnergy[0][3] = pzemModule.current();`
`frmEnergy[0][4] = pzemModule.energy();`
`frmEnergy[0][5] = pzemModule.frequency();`
`frmEnergy[0][6] = pzemModule.pf();`
`frmEnergy[0][7] = 26.10; //I added this one as a personal final element verification in raspberry`
`statusArray[busyFlagLocator] = disabled;`
`}`
Related
I am trying to combine two libraries on an ESP32.
I can run each of them alone, but not together.
I want to make a BT-Speaker as a Gift for my gf.
I want the speaker to play an Audio-file and afterwards run the BT-Sink.
But everytime I try to enable both at once (or after each other), the audio file is not playing and the BT-Script starts running directly.
When I comment one of them out, the other one works.
I hope someone can help. I am sure there is an easy fix.
Here is my .ino File:
`
// Playing a digital WAV recording repeatadly using the XTronical DAC Audio library
// prints out to the serial monitor numbers counting up showing that the sound plays
// independently of the main loop
// See www.xtronical.com for write ups on sound, the hardware required and how to make
// the wav files and include them in your code
#include "BluetoothA2DPSink.h"
BluetoothA2DPSink a2dp_sink;
#include "SoundData.h"
#include "XT_DAC_Audio.h"
#include "Darthatmet.h"
XT_Wav_Class Darthatmet(Darth); // verlinkung zur Darthatmet.h
XT_Wav_Class ForceWithYou(Force);
XT_Sequence_Class Sequence;
XT_DAC_Audio_Class DacAudio(25,0); // Create the main player class object. Use GPIO 25, one of the 2 DAC pins and timer 0
void setup() {
Sequence.RepeatForever=false;
Sequence.AddPlayItem(&Darthatmet);
Sequence.AddPlayItem(&ForceWithYou);
DacAudio.Play(&Sequence);
const i2s_config_t i2s_config = {
.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
.sample_rate = 44100, // corrected by info from bluetooth
.bits_per_sample = (i2s_bits_per_sample_t) 16, // the DAC module will only take the 8bits from MSB
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = (i2s_comm_format_t)I2S_COMM_FORMAT_STAND_MSB,
.intr_alloc_flags = 0, // default interrupt priority
.dma_buf_count = 8,
.dma_buf_len = 64,
.use_apll = false
};
a2dp_sink.set_i2s_config(i2s_config);
a2dp_sink.start("DarthVader-BT");
}
void loop() {
DacAudio.FillBuffer(); // Fill the sound buffer with data
}
`
I allready tried putting stuff inside the loop or using a true/false statement.
But it didn't work or i am just not educated enough with arduinoc-ode to do it :(
Ok, i found the solution :)
After some hours of testing I did it with "millis()".
It can be used to have a timer which runs in the "background".
I did it like this and it works like intended!
It powers the ESP32 and plays the "Startup-Sound" which is made out of 2 Audio-snippets in HEX Format.
while doing that it checks how much time in milliseconds has past since powerup.
I know my Startup-Sound is ruffly 5 seconds long. So i set the "timer" to 5,5 Seconds.
after it reached the 5,5 Seconds it starts the BT-Sink AND sets a flag named "btstarted". The flag needs to be false to trigger the BT-Sink start.
At first i did not used this flag. The Result was that i could see the BT-Device but can't connect cause it kept restarting after 5,5 seconds.
With this flag, it will only start once per powerup. Which is nice :)
Next step are programmable LEDs (ws2812b) and 3D-Design/Printing the Housing :)
Here is my code:
#include "BluetoothA2DPSink.h"
#include "SoundData.h"
#include "XT_DAC_Audio.h"
#include "Darthatmet.h"
BluetoothA2DPSink a2dp_sink;
XT_Wav_Class Darthatmet(Darth); // verlinkung zur Darthatmet.h
XT_Wav_Class ForceWithYou(Force);
XT_Sequence_Class Sequence;
XT_DAC_Audio_Class DacAudio(25,0); // Create the main player class object. Use GPIO 25, one of the 2 DAC pins and timer 0
bool btstarted = false;
void setup() {
Sequence.RepeatForever=false;
Sequence.AddPlayItem(&Darthatmet);
Sequence.AddPlayItem(&ForceWithYou);
DacAudio.Play(&Sequence);
const i2s_config_t i2s_config = {
.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
.sample_rate = 44100, // corrected by info from bluetooth
.bits_per_sample = (i2s_bits_per_sample_t) 16, // the DAC module will only take the 8bits from MSB
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = (i2s_comm_format_t)I2S_COMM_FORMAT_STAND_MSB,
.intr_alloc_flags = 0, // default interrupt priority
.dma_buf_count = 8,
.dma_buf_len = 64,
.use_apll = false
};
a2dp_sink.set_i2s_config(i2s_config);
//a2dp_sink.set_mono_downmix(true);
}
void loop() {
DacAudio.FillBuffer(); // Fill the sound buffer with data, start Playback
unsigned long zeit = millis();
if (zeit >= 5500 and btstarted == false) {
a2dp_sink.start("DarthVaderrr");
btstarted = true;
}
}
I'm trying to use VSPI port of ESP32-WROVER with "Adafruit_SPIFlash.h" library https://github.com/adafruit/Adafruit_SPIFlash
This question is similar to How to use SPI with ESP32 and Arduino , but I'm using "Adafruit_SPIFlash.h" library.
This library seems to be using ESP32-WROVER "internal" SPI port, where WROVER SPI FLASH chip is connected, as a default. I have another SPI FLASH chip connected to VSPI port which I'm trying to use to store some sensor data.
I tried changing CUSTOM_SPI statement, but code doesn't compile
#define CUSTOM_SPI SPI //tried changing SPI to: VSPI, &VSPI, SPI1, SPI2, &SPI2
I asked this from Adafruit forum and got answer: "Create a Adafruit_FlashTransport_SPI object for the secondary SPI interface, then feed that to the Adafruit_SPIFlash object when you create it." Unfortunately I'm so nooby on FW things that this didn't help me and my follow up question is not answered.
For example how would I need to modify sketch below to use VSPI?
// The MIT License (MIT)
// Copyright (c) 2019 Ha Thach for Adafruit Industries
#include "SdFat.h"
#include "Adafruit_SPIFlash.h"
// Uncomment to run example with custom SPI and SS e.g with FRAM breakout
// #define CUSTOM_CS A5
// #define CUSTOM_SPI SPI
#if defined(CUSTOM_CS) && defined(CUSTOM_SPI)
Adafruit_FlashTransport_SPI flashTransport(CUSTOM_CS, CUSTOM_SPI);
#elif defined(ARDUINO_ARCH_ESP32)
// ESP32 use same flash device that store code.
// SPIFlash can use partition table to detect fatfs partition
// Therefore there is no need to specify the SPI and SS
Adafruit_FlashTransport_ESP32 flashTransport;
#elif defined(ARDUINO_ARCH_RP2040)
// RP2040 use same flash device that store code.
// Therefore there is no need to specify the SPI and SS
// Use default (no-args) constructor to be compatible with CircuitPython partition scheme
Adafruit_FlashTransport_RP2040 flashTransport;
// For generic usage: Adafruit_FlashTransport_RP2040(start_address, size)
// If start_address and size are both 0, value that match filesystem setting in
// 'Tools->Flash Size' menu selection will be used
#else
// On-board external flash (QSPI or SPI) macros should already
// defined in your board variant if supported
// - EXTERNAL_FLASH_USE_QSPI
// - EXTERNAL_FLASH_USE_CS/EXTERNAL_FLASH_USE_SPI
#if defined(EXTERNAL_FLASH_USE_QSPI)
Adafruit_FlashTransport_QSPI flashTransport;
#elif defined(EXTERNAL_FLASH_USE_SPI)
Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);
#else
#error No QSPI/SPI flash are defined on your board variant.h !
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
/* If you want to use a specific flash device, for example for a custom built board, first look for it in Adafruit_SPIFlash\src\flash_devices.h
* If it isn't in there you need to create your own definition like the W25Q80DLX_EXAMPLE example below.
* These definitions need to be edited to match information on the data sheet of the flash device that you want to use.
* If you are not sure what the manufacture ID, memory type and capacity values should be, try running the sketch anyway and look at the serial output
* The flash device will report these values to you as a single hexadecimal value (the JDEC ID)
* For example, the first device on the list - the W25Q80DLX - will report its JDEC ID as 0xef4014, which is made of these three values:
* manufacturer_id = 0xef
* memory_type = 0x40
* capacity = 0x14
* With this macro properly defined you can then create an array of device definitions as shown below, this can include any from the list of devices in flash_devices.h, and any you define yourself here
* You need to update the variable on line 71 to reflect the number of items in the array
* You also need to uncomment line 84 and comment out line 81 so this array will be passed to the flash memory driver.
*
* Example of a user defined flash memory device:
#define W25Q80DLX_EXAMPLE \
{ \
.total_size = 1*1024*1024, \
.start_up_time_us = 5000, .manufacturer_id = 0xef, \
.memory_type = 0x40, .capacity = 0x14, .max_clock_speed_mhz = 80, \
.quad_enable_bit_mask = 0x02, .has_sector_protection = false, \
.supports_fast_read = true, .supports_qspi = true, \
.supports_qspi_writes = false, .write_status_register_split = false, \
.single_status_byte = false, .is_fram = false, \
}
*/
/*
* Create an array of data structures and fill it with the settings we defined above.
* We are using two devices, but more can be added if you want.
*/
//static const SPIFlash_Device_t my_flash_devices[] = {
// W25Q80DLX_EXAMPLE,
//};
/*
* Specify the number of different devices that are listed in the array we just created. If you add more devices to the array, update this value to match.
*/
//const int flashDevices = 1;
// the setup function runs once when you press reset or power the board
void setup()
{
Serial.begin(115200);
while ( !Serial ) delay(100); // wait for native usb
Serial.println("Adafruit Serial Flash Info example");
flash.begin();
//Using a flash device not already listed? Start the flash memory by passing it the array of device settings defined above, and the number of elements in the array.
//flash.begin(my_flash_devices, flashDevices);
Serial.print("JEDEC ID: 0x"); Serial.println(flash.getJEDECID(), HEX);
Serial.print("Flash size: "); Serial.print(flash.size() / 1024); Serial.println(" KB");
}
void loop()
{
// nothing to do
}
I am using MPLAB X IDE and MPLAB Code Configurator (MCC).
i generated the library of the flash read/write and erase with MCC.
then when i used "FLASH_ReadPage" built in function created from the MCC its not working, and after debugging i found it stucked in a while loop that is checking for "NVMCON0bits.GO" to be cleared and its never cleared thats why its stucked.
here is the function:
void FLASH_ReadPage(uint32_t flashAddr)
{
uint8_t GIEBitValue = INTCON0bits.GIE; // Save interrupt enable
//Set NVMADR with the target word address
NVMADRU = (uint8_t) ((flashAddr & 0x00FF0000) >> 16);
NVMADRH = (uint8_t) ((flashAddr & 0x0000FF00) >> 8);
NVMADRL = (uint8_t) (flashAddr & 0x000000FF);
//Set the NVMCMD control bits for Page Read operation
NVMCON1bits.NVMCMD = 0b010;
//Disable all interrupt
INTCON0bits.GIE = 0;
//Perform the unlock sequence
NVMLOCK = 0x55;
NVMLOCK = 0xAA;
//Start page read and wait for the operation to complete
NVMCON0bits.GO = 1;
while (NVMCON0bits.GO); **<----- Stucked here**
//Restore the interrupts
INTCON0bits.GIE = GIEBitValue;
//Set the NVMCMD control bits for Word Read operation to avoid accidental writes
NVMCON1bits.NVMCMD = 0b000;
}
I'm Working on ATSAMC21 (ATSAMC21J18A) with Cortex-M0+, making my CAN bootloader.My IDE is ATMEL studio.
Flashing my app is Ok but when I jump in i, it failed.(I tryed with debug and without)
In dissaseembly it point to the first of these two line:
*FFFFFFFE ?? ?? ??? Memory out of bounds or read error*
*00000000 a0.32 adds r2, #160*
pc disassembly point
My bootloader space in my linker :
MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00008000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
My application (or firmware) space in my linker :
MEMORY
{
rom (rx) : ORIGIN = 0x00010000, LENGTH = 0x00030000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
Before jumping,
I disabled irq interrupt, defined my entry point and my stack pointer, and change VTOR.
Here is my code to jump:
void JumpToApp(void) {
uint16_t i;
uint32_t startAddress, applicationStack;
/* Check if WDT is locked */
if (!(WDT->CTRLA.reg & WDT_CTRLA_ALWAYSON)) {
/* Disable the Watchdog module */
WDT->CTRLA.reg &= ~WDT_CTRLA_ENABLE;
}
//stop general IT
__disable_irq();
// Disable SysTick
SysTick->CTRL = 0;
// Disable IRQs & clear pending IRQs
for (i = 0; i < 8; i++) {
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
// Pointer to the Application Section
void (*application_code_entry)(void);
startAddress = FLASH_APP_VADRESS; //HERE 0x00010000, my start App
applicationStack = (uint32_t) *(volatile unsigned int*) (startAddress);
application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)(FLASH_APP_VADRESS + 4)); //HERE 0x00010004
// Rebase the Stack Pointer
__DSB();
__ISB();
__set_MSP(*(uint32_t *)applicationStack); //HERE 0x00010000, my start App
// Rebase the vector table base address
SCB->VTOR = ((uint32_t)startAddress & SCB_VTOR_TBLOFF_Msk);
__DSB();
__ISB();
// Jump to user Reset Handler in the application
application_code_entry();
}
I tried to add +1 at my application_code_entry , like a odd Thumb mode, i see this for Cortex-M3 but it don't work, fail in general IT.
Then I rename main() by main_boot()
and Reset_Handler() by Reset_Handler_Boot() (and by changing in propety flag linker the --entry=Reset_Handler_Boot)
But still not jumping.
I don't know what i'm doing bad.May be there is a long jump to do?
Split the RAM?
If somebody have an idea?
Thank You!!!!!!!!!!!!!!!!!!!
Thank you, (it was a mistake :) )but this hard fault doesn't resolve my jump (in fact i Used directly the adress __set_MSP(*(uint32_t *)(FLASH_APP_VADRESS));
My MSP is not 0x0000000, it's 0x20003240 so is it an offset to apply to my new MSP? (see the picture linked)
Here is my code for testing the MSP
ReadMsp=__get_MSP(); //result 0x20003240, before change it
__DSB();
__ISB();
__set_MSP(*(uint32_t *)applicationStack);
// Rebase the vector table base address TODO: use RAM
SCB->VTOR = ((uint32_t)startAddress & SCB_VTOR_TBLOFF_Msk);
__DSB();
__ISB();
ReadMsp=__get_MSP(); //result is 0xFFFFFFFC , why ???
__DSB();
__ISB();
__set_MSP(0x00010000);
__DSB();
__ISB();
ReadMsp=__get_MSP(); //result is 0x00010000, better than my same #define FLASH_APP_VADRESS or *(uint32_t *)applicationStack in __MSP
//applicationEntry();
// Load the Reset Handler address of the application
//application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)(FLASH_APP_VADRESS ));
// Jump to user Reset Handler in the application
application_code_entry();
Should I use (0x20003240 + 0x00010000) for my new MSP?
enter image description here
You are dereferencing the SP stack pointer twice:
applicationStack = (uint32_t) *(volatile unsigned int*) (startAddress);
// ... --^
__set_MSP(*(uint32_t *)applicationStack);
// -^
You need to do that only once. The second time sets SP highly likely to zero, resulting to a fault once the stack is used.
I found the answer !!!
Finally to jump, just like atmel say BUT before I needed to uninitialized some module.
So : ATMEL part :
*// Pointer to the Application Section
void (*application_code_entry)(void);
// Rebase the Stack Pointer
__set_MSP(*(uint32_t *)FLASH_APP_VADRESS);
// Rebase the vector table base address TODO: use RAM
SCB->VTOR = ((uint32_t)FLASH_APP_VADRESS & SCB_VTOR_TBLOFF_Msk);
// Load the Reset Handler address of the application
application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)
(FLASH_APP_VADRESS + 4));
// Jump to user Reset Handler in the application
application_code_entry();*
My part before executing this :
*Flash_Deinit(); //flash uninit
config_TC_Deinit(); //time clock uninit, scheduler
can_deinit0(); // module CAN0
can_deinit1(); // module CAN1
Handle_Wdt_Disable();
__disable_irq();
// Disable SysTick
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
// Disable IRQs & clear pending IRQs
for (i = 0; i < 8; i++) {
NVIC->IP[i] = 0x00000000;
}
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICPR[0] = 0xFFFFFFFF;*
I hope it will help someone !!! :)
So I'm trying to make a lighting system for my computer, I wanted to write the GUI and whatnot within Python and handle all the controlling of lights and stuff with the Arduino. After some research PySerial seemed like the easiest to use and understand being a beginner myself. I honestly have no idea what I'm doing here and I'm getting errors that I can't diagnose, and Google is not helping whatsoever.
Here is the code I have running in python now:
import serial
ser = serial.Serial('COM8', 9600) # Establish the connection on a specific port
while True:
numIn = str(input("Enter a Color value: "))
ser.write(numIn)
print (ser.readline())
On the Arduino side I have:
void setup ()
{
Serial.begin (9600);
Serial.println ("Ready\n\n");
}
void loop ()
{
int intensity = 0;
while (Serial.available() == 0)
while (Serial.available() > 0)
{
char byteIn = Serial.read();
intensity += int(byteIn) - '0';
Serial.print(byteIn);
}
}
Through Python I'd be sending a value between 0 - 255, That number should be being saved as a string and then be sent to the Arduino which would then create an integer character by character. For debugging reasons I wanted to echo back the string to Python but I haven't gotten my code to run that far yet. There is something up with the way I'm trying to send the data from Python to the Arduino, this is the Trace back I am getting:
Enter a Color value: 25
Traceback (most recent call last):
File "C:\Users\Squirrelzar\Documents\Python Proj\Arduino Serial Testing.py", line 10, in <module>
ser.write(numIn)
File "C:\Python34\lib\site-packages\serial\serialwin32.py", line 283, in write
data = to_bytes(data)
File "C:\Python34\lib\site-packages\serial\serialutil.py", line 76, in to_bytes
b.append(item) # this one handles int and str for our emulation and ints for Python 3.x
TypeError: an integer is required
Im using Python 3.4 with PySerial 2.7
Any help would be greatly appreciated..I am so lost..
You can send from python the integer value as a string, and read it directly in Arduino as integer using Serial.parseInt(). The next code works for me (linux, python 2.7):
Python:
import serial
ser = serial.Serial('/dev/ttyACM1', 9600)
print (ser.readline())
while True:
numIn = raw_input("Enter a Color value: ") # Returns the value as string
ser.write(numIn)
msg = ser.readline()
print (msg)
Arduino:
void setup ()
{
Serial.begin (9600);
Serial.print ("Ready\n");
}
void loop ()
{
while(Serial.available())
{
int inNumber = Serial.parseInt(); # retunrs the first valid long integer buffered
Serial.print(inNumber);
Serial.print('\n');
}
}
A comment, if you send Serial.println ("Ready\n\n"); you have to read all the new-line characters before reading other data