Read byte from Serial - byte

I´ve made this program that reads info from serial and writes the value binary to 6 LEDs. I don´t feel that it´s the easiest or the fastest way though and that is what I´m really looking for. My code looks like this:
boolean enable = false;
void setup()
{
for (int i = 2; i < 8; i++)
{
pinMode(i, OUTPUT);
}
}
void loop()
{
if (Serial.available() > 0)
{
enable = true;
}
if (enable)
{
while (Serial.available() > 0)
{
byte b = Serial.parseInt();
b = constrain(b, 0, 63);
byte val = b;
for (int i = 7; i >= 2; i--)
{
if (pow(2, (i-2)) <= val)
{
digitalWrite(i, HIGH);
val -= pow(2, (i-2));
}
else
{
digitalWrite(i, LOW);
}
}
}
enable = false;
}
delay(100);
}
A valid code example would be nice. I´ve tried using PORTD but it does not work.

Use binary operations
for(int i = 0 ; i < 8 ; i++ ) {
val = ( b >> i ) & 0x1;
digitalWrite(i, val == 1 ? HIGH : LOW );
}
If you plan some serious serial communication have a look into library I created https://github.com/lukaszkujawa/arduino-serial-helper

Related

Moving from AVR to ESP32 rto control led strip using 1 pin and SPI/DMA

i'm working on an old project based on AVR, that controls a led stripe using 1 pin with SPI high frequency in DMA. (42 leds)
I'm converting the code to esp-idf, but i'm facing some problem, probably base on bus/config parameters.
These are the code:
AVR:
USART_SPI_RGB_OPTIONS.baudrate = USART_SPI_RGB_BAUDRATE;
USART_SPI_RGB_OPTIONS.spimode = USART_SPI_RGB_CHMODE;
USART_SPI_RGB_OPTIONS.data_order = USART_SPI_RGB_DATA_ORDER;
usart_init_spi(USART_SPI_RGB_PORT, &USART_SPI_RGB_OPTIONS);
void dma_init(void){
struct dma_channel_config dmach_conf;
memset(&dmach_conf, 0, sizeof(dmach_conf));
dma_channel_set_burst_length(&dmach_conf, DMA_CH_BURSTLEN_1BYTE_gc);
dma_channel_set_transfer_count(&dmach_conf, DMA_BUFFER_SIZE);
dma_channel_set_src_reload_mode(&dmach_conf, DMA_CH_SRCRELOAD_TRANSACTION_gc);
dma_channel_set_dest_reload_mode(&dmach_conf, DMA_CH_DESTRELOAD_NONE_gc);
dma_channel_set_src_dir_mode(&dmach_conf, DMA_CH_SRCDIR_INC_gc);
dma_channel_set_source_address(&dmach_conf, (uint16_t)(uintptr_t)RGBMemoryMap);
dma_channel_set_dest_dir_mode(&dmach_conf, DMA_CH_DESTDIR_FIXED_gc);
dma_channel_set_destination_address(&dmach_conf, (uint16_t)(uintptr_t)USART_SPI_RGB_PORT.DATA);
dma_channel_set_trigger_source(&dmach_conf, DMA_CH_TRIGSRC_USARTD0_DRE_gc);
dma_channel_set_single_shot(&dmach_conf);
dma_enable();
dma_channel_write_config(DMA_CHANNEL, &dmach_conf);
dma_channel_enable(DMA_CHANNEL);
}
ESP-IDF:
void initSPISettings()
{
//memset(&SPI_settings, 0, sizeof(SPI_settings));
SPI_settings.host = HSPI_HOST,
SPI_settings.dma_chan = SPI_DMA_CH2;
// buscfg
SPI_settings.buscfg.flags = 0;
SPI_settings.buscfg.miso_io_num = -1;
SPI_settings.buscfg.mosi_io_num = GPIO_NUM_32;
SPI_settings.buscfg.sclk_io_num = -1;
SPI_settings.buscfg.quadwp_io_num = -1;
SPI_settings.buscfg.quadhd_io_num = -1;
SPI_settings.buscfg.max_transfer_sz = LED_DMA_BUFFER_SIZE;
// devcfg
SPI_settings.devcfg.clock_speed_hz = DMA_SPEED;
SPI_settings.devcfg.dummy_bits = 0;
SPI_settings.devcfg.mode = 0;
SPI_settings.devcfg.flags = SPI_DEVICE_NO_DUMMY;
SPI_settings.devcfg.spics_io_num = -1;
SPI_settings.devcfg.queue_size = 1;
SPI_settings.devcfg.command_bits = 0;
SPI_settings.devcfg.address_bits = 0;
}
void initSPI()
{
esp_err_t err;
initSPISettings();
err = spi_bus_initialize(SPI_settings.host, &SPI_settings.buscfg, SPI_settings.dma_chan);
ESP_ERROR_CHECK(err);
//Attach the Accel to the SPI bus
err = spi_bus_add_device(SPI_settings.host, &SPI_settings.devcfg, &SPI_settings.spi);
ESP_ERROR_CHECK(err);
}
void updateRGB()
{
spi_transaction_t t;
esp_err_t err;
printf("Start transaction to DMA...\r\n");
// for (int i = (LED_DMA_BUFFER_SIZE - LED_RESET_COUNT); i < LED_DMA_BUFFER_SIZE; i++) {
// //Setting more bytes to 0x00 at the end of memory map to assure correct RGB init
// ledDMAbuffer[i] = 0x00;
// }
t.flags = 0;
t.length = LED_DMA_BUFFER_SIZE * 8; //length is in bits
t.tx_buffer = ledDMAbuffer;
t.rx_buffer = NULL;
t.rxlength = 0;
err = spi_device_transmit(SPI_settings.spi, &t);
ESP_ERROR_CHECK(err);
}
ledDMAbuffer = heap_caps_malloc(LED_DMA_BUFFER_SIZE, MALLOC_CAP_DMA); // Critical to be DMA memory.
Do you have any ideas what i'm missing?
I fill data in the right way (i'm sure of that). If i try to control 1 led no problem at all, while increasing the number of leds controlled i have strange behaviour (for example with 2 led blinking red/green, first one works properly while second one just red)
Thanks to all

How to exit or break from 'for loop' on Arduino C Program

I'm not new to the programming world, but for last 2 weeks I'm working with Arduino C++. I have a strange problem. In general, I have a 7-segment display that will act as an up counter when the condition is 01, down counter when the condition is 10, 00 for reset to zero, and 11 for stop (pause in that number).
The problem is, when the up or down counter is still counting and I've change the state, the 7-segment is still counting! Besides that, I've printed the status of state when state is changed, but nothing happens. I think maybe there's mistakes in my code, I need some advice from you guys. Here is my code:
*FYI, I've try to use break, return, also call loop(), but nothing happens
*saklar1 = switch1
*saklar2 = switch2
#include <SevSeg.h>
SevSeg sevseg;
const int saklar1 = 2;
const int saklar2 = 3;
void setup() {
byte sevenSegments = 1;
byte commonPins[] = {};
byte sevenPins[] = {11, 10, 9, 8, 7, 6, 5, 4};
bool resistor = true;
sevseg.begin(COMMON_CATHODE, sevenSegments, commonPins, sevenPins, resistor);
sevseg.setBrightness(90);
pinMode(saklar1, INPUT);
pinMode(saklar2, INPUT);
Serial.begin(9600);
}
void loop() {
checking(digitalRead(saklar1), digitalRead(saklar2));
}
void checking(bool saklar1, bool saklar2){
if (saklar1 == LOW && saklar2 == LOW) {
setSevSeg(0);
} else if (saklar1 == LOW && saklar2 == HIGH) {
for (int i=0; i<=9; i++) {
setSevSeg(i);
if (saklar1 != LOW || saklar2 != HIGH) {
Serial.println("STATE CHANGED"); //THIS LINE IS NOT EXECUTED OR PRINTED
checking(digitalRead(saklar1), digitalRead(saklar2));
}
}
} else if (saklar1 == HIGH && saklar2 == LOW) {
for (int i=9; i>=0; i--) {
setSevSeg(i);
if (saklar1 != HIGH || saklar2 != LOW) {
checking(digitalRead(saklar1), digitalRead(saklar2));
}
}
} else if (saklar1 == HIGH && saklar2 == HIGH) {
delay(100); //Stop
}
}
void setSevSeg(int num) {
sevseg.setNumber(num);
sevseg.refreshDisplay();
delay(500); //1 detik
}
In the following code, the control exits the for loop when the sensor value exceeds the threshold.
Reference: [https://www.arduino.cc/reference/en/language/structure/control-structure/break]
int threshold = 40;
for (int x = 0; x < 255; x++) {
analogWrite(PWMpin, x);
sens = analogRead(sensorPin);
if (sens > threshold) { // bail out on sensor detect
x = 0;
break;
}
delay(50);
}

how to make spi connection between arduino uno and dspic33ep512mc502?

i just want to test spi comunication between arduino uno and dspic33ep512mc502, i use serial port to see receiving data from microcontroller;
-arduino uno is master
-dspic33ep512mc502 is slave
here is my code for Arduino Uno :
#include<SPI.h>
byte y=1;
void setup() {
Serial.begin(9600);
SPI.begin();
SPI.setDataMode(SPI_MODE1);
digitalWrite(SS,HIGH);
// SPI.setBitOrder( LSBFIRST);
SPI.setBitOrder( MSBFIRST);
}
int trnasfer_spi(int d)
{
digitalWrite(SS,LOW);
byte r=SPI.transfer(7);
digitalWrite(SS,HIGH);
return r;
}
void loop() {
if (Serial.available() > 0) {
// read the incoming byte:
int incomingByte = Serial.read();
y=trnasfer_spi(incomingByte);
}
Serial.print(y, DEC);
delay(1000);
}
here is dspic33ep512mc502 code(just for spic comunication):
initialization :
ANSELBbits.ANSB0 = 0;
TRISBbits.TRISB0 = 1;
TRISBbits.TRISB7 = 1;
TRISBbits.TRISB8 = 0;
TRISBbits.TRISB9 = 1;
SPI1CON1bits.DISSCK = 0;
SPI1CON1bits.DISSDO = 0;
SPI1CON1bits.MODE16 = 0;
SPI1CON1bits.SMP = 0;
SPI1CON1bits.CKP = 0;
SPI1CON1bits.CKE = 1;
SPI1CON1bits.MSTEN = 0;
SPI1CON1bits.SSEN = 1;
//Setari registru SPI1STAT
SPI1STATbits.SPIROV = 0;
SPI1STATbits.SPIEN = 1;
IFS0bits.SPI1IF = 0;
IEC0bits.SPI1IE = 1;
IPC2bits.SPI1IP = 6;
SPI1BUF =3;
SPI1Interrupt:
void __attribute__((__interrupt__)) _SPI1Interrupt(void)
{
IFS0bits.SPI1IF = 0;
SPI1STATbits.SPIROV = 0;
SPI1BUF=3;
};
i expect to see value 3 on serial monitor, but i see only value 7 or 255.
SPI reads and writes at the same time, so a write to the register must be followed by a read, otherwise the next read won't work.
So try to read spi1buf after writing it.

MFRC 522 with ATmega8. Mifare Classic 1K won't authenticate

I have a problem with an ATmega8 and Mifare RC-522 based NFC/RFID controller.
I'm using this library and I've managed to read the UID of a card.
However, I'd like to also read and write other parts of the card but whenever I try to use the MFRC522_Auth function I don't get the idle interrupt which I should, instead it gives me LoAlertIrq saying that FIFObuffer is almost empty.
Here are the docs for the reader and the card, and below are relevant parts of my code.
main.c :
byte = mfrc522_request(PICC_REQALL,str);
if(byte == CARD_FOUND)
{
byte = mfrc522_get_card_serial(str);
if(byte == CARD_FOUND)
{
byte = mfrc522_auth(PICC_AUTHENT1A, 7, sectorKeyA, str);
if( (byte == CARD_FOUND) )
{
byte = MFRC522_Read1(4, str);
if(byte == CARD_FOUND)
{
//write content of that block
}
}
}
Relevant functions from the library :
void mfrc522_write(uint8_t reg, uint8_t data)
{
ENABLE_CHIP();
spi_transmit((reg<<1)&0x7E);
spi_transmit(data);
DISABLE_CHIP();
}
uint8_t mfrc522_read(uint8_t reg)
{
uint8_t data;
ENABLE_CHIP();
spi_transmit(((reg<<1)&0x7E)|0x80);
data = spi_transmit(0x00);
DISABLE_CHIP();
return data;
}
uint8_t mfrc522_to_card(uint8_t cmd, uint8_t *send_data, uint8_t send_data_len, uint8_t *back_data, uint32_t *back_data_len)
{
uint8_t status = 0;
uint8_t irqEn = 0x00;
uint8_t waitIRq = 0x00;
uint8_t lastBits;
uint8_t n;
uint8_t tmp;
uint32_t i;
switch (cmd)
{
case MFAuthent_CMD: //Certification cards close
{
irqEn = 0x12;
waitIRq = 0x10;
break;
}
case Transceive_CMD: //Transmit FIFO data
{
irqEn = 0x77;
waitIRq = 0x30;
break;
}
default:
break;
}
mfrc522_write(ComIEnReg, irqEn|0x80); //Interrupt request
n=mfrc522_read(ComIrqReg);
mfrc522_write(ComIrqReg,n&(~0x80));//clear all interrupt bits
n=mfrc522_read(FIFOLevelReg);
mfrc522_write(FIFOLevelReg,n|0x80);//flush FIFO data
// mfrc522_write(CommandReg, Idle_CMD); //NO action; Cancel the current cmd???
n=mfrc522_read(CommandReg);
mfrc522_write(CommandReg,n|0x00);
//Writing data to the FIFO
for (i=0; i<send_data_len; i++)
{
mfrc522_write(FIFODataReg, send_data[i]);
}
//Execute the cmd
mfrc522_write(CommandReg, cmd);
if (cmd == Transceive_CMD)
{
n=mfrc522_read(BitFramingReg);
mfrc522_write(BitFramingReg,n|0x80);
}
//Waiting to receive data to complete
i = 2000; //i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms???
while (1) {
n = mfrc522_read(ComIrqReg); // ComIrqReg[7..0] bits are: Set1 TxIRq RxIRq IdleIRq HiAlertIRq LoAlertIRq ErrIRq TimerIRq
if (n & waitIRq) { // One of the interrupts that signal success has been set.
break;
}
if (n & 0x01) { // Timer interrupt - nothing received in 25ms
// return 6; //debug purpose
if (cmd == MFAuthent_CMD) {
LCD_Clear();
LCD_WriteTextXY(1, 3, LCD_itoa( mfrc522_read(ComIrqReg) ) );
_delay_ms(2500);
}
break;
}
if (--i == 0) { // The emergency break. If all other condions fail we will eventually terminate on this one after 35.7ms. Communication with the MFRC522 might be down.
if (cmd == MFAuthent_CMD) {
LCD_Clear();
LCD_WriteTextXY(1, 3, LCD_itoa( mfrc522_read(ComIrqReg) ) );
_delay_ms(2500);
}
break;
}
}
tmp=mfrc522_read(BitFramingReg);
mfrc522_write(BitFramingReg,tmp&(~0x80));
if (i != 0)
{
if(!(mfrc522_read(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
{
status = CARD_FOUND;
if (n & irqEn & 0x01)
{
status = CARD_NOT_FOUND; //??
}
if (cmd == Transceive_CMD)
{
n = mfrc522_read(FIFOLevelReg);
lastBits = mfrc522_read(ControlReg) & 0x07;
if (lastBits)
{
*back_data_len = (n-1)*8 + lastBits;
}
else
{
*back_data_len = n*8;
}
if (n == 0)
{
n = 1;
}
if (n > MAX_LEN)
{
n = MAX_LEN;
}
//Reading the received data in FIFO
for (i=0; i<n; i++)
{
back_data[i] = mfrc522_read(FIFODataReg);
}
}
}
if (cmd == MFAuthent_CMD) {
LCD_WriteTextXY(1, 10, LCD_itoa16( mfrc522_read(Status2Reg) ) );
_delay_ms(2500);
}
} else status = 9;
return status;
}
uint8_t mfrc522_get_card_serial(uint8_t * serial_out)
{
uint8_t status;
uint8_t i;
uint8_t serNumCheck=0;
uint32_t unLen;
mfrc522_write(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0]
serial_out[0] = PICC_ANTICOLL;
serial_out[1] = 0x20;
status = mfrc522_to_card(Transceive_CMD, serial_out, 2, serial_out, &unLen);
if (status == CARD_FOUND)
{
//Check card serial number
for (i=0; i<4; i++)
{
serNumCheck ^= serial_out[i];
}
if (serNumCheck != serial_out[i])
{
status = ERROR;
}
}
return status;
}
uint8_t mfrc522_auth(uint8_t authMode, uint8_t BlockAddr, uint8_t *Sectorkey, uint8_t *serNum)
{
uint8_t status;
uint32_t recvBits;
uint8_t i;
uint8_t buff[12];
// Validate instruction block address + sector + password + card serial number
buff[0] = authMode;
buff[1] = BlockAddr;
for (i=0; i<6; i++)
{
buff[i+2] = 0xFF /**(Sectorkey+i)*/;
}
for (i=0; i<4; i++)
{
buff[i+8] = *(serNum+i);
}
status = mfrc522_to_card(MFAuthent_CMD, buff, 12, buff, &recvBits);
return status;
}
uint8_t MFRC522_Read1(uint8_t blockAddr, uint8_t *recvData)
{
uint8_t status = 0;
uint8_t unLen, efa;
recvData[0] = PICC_READ;
recvData[1] = blockAddr;
CalculateCRC(recvData, 2, &recvData);
status = mfrc522_to_card(Transceive_CMD, recvData, 4, recvData, &unLen);
if ((status != CARD_FOUND)|| (unLen != 0x90))
{
status = ERROR;
}
return status;
}
uint8_t CalculateCRC(uint8_t *pIndata, uint8_t len, uint8_t *pOutData)
{
uint8_t i, n;
uint8_t status = 0;
n = mfrc522_read(DivIrqReg);
mfrc522_write(DivIrqReg,n&(~0x04)); //CRCIrq = 0
n = mfrc522_read(FIFOLevelReg); //FIFO
mfrc522_write(FIFOLevelReg, n|0x80);
//Write_MFRC522(CommandReg, PCD_IDLE);
// Write data to the FIFO
for (i=0; i<len; i++)
{
mfrc522_write(FIFODataReg, *(pIndata+i));
}
mfrc522_write(CommandReg, CalcCRC_CMD);
// Read the CRC calculation result
i = 0xFF;
while(1){
n = mfrc522_read(DivIrqReg);
if (n & 0x04) {
break;
}
if (--i != 0) {
return 7;
}
}
// Read the CRC calculation result
pOutData[3] = mfrc522_read(CRCResultReg_2);
pOutData[4] = mfrc522_read(CRCResultReg_1);
return status = 0;
}

Is the cuda kernel limited by memory usage per thread/block

I have a kernel code that executes properly
runnable code
__global__ static void CalcSTLDistance_Kernel(Integer ComputeParticleNumber)
{
//const Integer TID = CudaGetTargetID();
const Integer ID =CudaGetTargetID();
/*if(ID >= ComputeParticleNumber)
{
return ;
}*/
CDistance NearestDistance;
Integer NearestID = -1;
NearestDistance.Magnitude = 1e8;
NearestDistance.Direction.x = 0;
NearestDistance.Direction.y = 0;
NearestDistance.Direction.z = 0;//make_Scalar3(0,0,0);
//if(c_daOutputParticleID[ID] < -1)
//{
// c_daSTLDistance[ID] = NearestDistance;
// c_daSTLID[ID] = NearestID;
// return;
//}
//Scalar3 TargetPosition = c_daParticlePosition[ID];
Integer TriangleID;
Integer CIDX, CIDY, CIDZ;
Integer CID = GetCellID(&CONSTANT_BOUNDINGBOX,&c_daParticlePosition[ID],CIDX, CIDY, CIDZ);
if(CID >=0 && CID < c_CellNum)
{
//Integer Range = 1;
for(Integer k = -1; k <= 1; ++k)
{
for(Integer j = -1; j <= 1; ++j)
{
for(Integer i = -1; i <= 1; ++i)
{
Integer MCID = GetCellID(&CONSTANT_BOUNDINGBOX,CIDX +i, CIDY + j,CIDZ + k);
if(MCID < 0 || MCID >= c_CellNum)
{
continue;
}
unsigned int TriangleNum = c_daCell[MCID].m_TriangleNum;
for(unsigned int l = 0; l < TriangleNum; ++l)
{
TriangleID = c_daCell[MCID].m_TriangleID[l];
/*if(c_daTrianglesParameters[c_daTriangles[TriangleID].ModelIDNumber].isDrag)
{
continue;
}*/
if( TriangleID >= 0 && TriangleID < c_TriangleNum && TriangleID != NearestID)// No need to calculate again for the same triangle
{
CDistance Distance ;
Distance.Magnitude = CalcDistance(&c_daTriangles[TriangleID], &c_daParticlePosition[ID], &Distance.Direction);
if(Distance.Magnitude < NearestDistance.Magnitude)
{
NearestDistance = Distance;
NearestID = TriangleID;
}
}
}
}
}
}
}
c_daSTLDistance[ID] = NearestDistance;
c_daSTLID[ID] = NearestID;
}
and when I add any basic variables or perform any checking operation, it gives unknown error and while checking wih cuda-memcheck, it suggests memory read error.
here in the changed code, i tried to check the previously calculated part and tried to skip the redundant calculation. for this I tried to perform basic check operation in array but it throws memory error.
error raising code
__global__ static void CalcSTLDistance_Kernel(Integer ComputeParticleNumber)
{
//const Integer TID = CudaGetTargetID();
const Integer ID =CudaGetTargetID();
/*if(ID >= ComputeParticleNumber)
{
return ;
}*/
CDistance NearestDistance;
Integer NearestID = -1;
NearestDistance.Magnitude = 1e8;
NearestDistance.Direction.x = 0;
NearestDistance.Direction.y = 0;
NearestDistance.Direction.z = 0;//make_Scalar3(0,0,0);
//if(c_daOutputParticleID[ID] < -1)
//{
// c_daSTLDistance[ID] = NearestDistance;
// c_daSTLID[ID] = NearestID;
// return;
//}
//Scalar3 TargetPosition = c_daParticlePosition[ID];
Integer TriangleID;
Integer CIDX, CIDY, CIDZ;
Integer CID = GetCellID(&CONSTANT_BOUNDINGBOX,&c_daParticlePosition[ID],CIDX, CIDY, CIDZ);
int len=0;
int td[100];
for(int m=0;m<100;m++)
{
td[m]=-1;
}
if(CID >=0 && CID < c_CellNum)
{
//Integer Range = 1;
for(Integer k = -1; k <= 1; ++k)
{
for(Integer j = -1; j <= 1; ++j)
{
for(Integer i = -1; i <= 1; ++i)
{
Integer MCID = GetCellID(&CONSTANT_BOUNDINGBOX,CIDX +i, CIDY + j,CIDZ + k);
if(MCID < 0 || MCID >= c_CellNum)
{
continue;
}
unsigned int TriangleNum = c_daCell[MCID].m_TriangleNum;
bool flag = false;
//len=len+TriangleNum ;
for(unsigned int l = 0; l < TriangleNum; ++l)
{
TriangleID = c_daCell[MCID].m_TriangleID[l];
//tem[l] = c_daCell[MCID].m_TriangleID[l];
for(int m=0;m<100;m++)
{
if(TriangleID ==td[m])
{
flag= true;
}
if(flag == true)
break;
}
if(flag == true)
continue;
else
{
td[len] = TriangleID;
len= len+1;
if( TriangleID >= 0 && TriangleID < c_TriangleNum && TriangleID != NearestID)// No need to calculate again for the same triangle
{
CDistance Distance ;
Distance.Magnitude = CalcDistance(&c_daTriangles[TriangleID], &c_daParticlePosition[ID], &Distance.Direction);
if(Distance.Magnitude < NearestDistance.Magnitude)
{
NearestDistance = Distance;
NearestID = TriangleID;
}
}
}
}
}
}
}
}
c_daSTLDistance[ID] = NearestDistance;
c_daSTLID[ID] = NearestID;
}
this problem arises whenever I tried to add any piece of code,thus I suspects that this block of kernel is not allowing me to add any further code due to memory over use.
is there any memory violation rule per block or thread??
how to find the total memory usuage per kernel ?? is there any way??

Resources