I want to save and restore my integer datas with my FLASH memory in STM32F407 using SPI1. I gave instructions to FLASH like this code.
uint8_t txData[10] = {0xAB, 0x04, 0x06, 0xC7, 0x04, 0x90, 0x00, 0x00, 0x00, 0x00};
uint8_t rxData[10] = {0};
HAL_SPI_Init(&hspi1);
HAL_SPI_Transmit(&hspi1, txData+5, 1, 10000);
HAL_SPI_Transmit(&hspi1, txData+6, 1, 10000);
HAL_SPI_Transmit(&hspi1, txData+7, 1, 10000);
HAL_SPI_Transmit(&hspi1, txData+8, 1, 10000);
HAL_SPI_TransmitReceive(&hspi1, txData+9, rxData, 1, 10000);
But, in rxData[0], it has only FF after HAL_SPI_TransmitReceive(). I want to see my Manufacturer ID.
Thanks to help.
You should follow these steps for writing data to W25Q flash modules.
Write enable
Erase chip or address which want to write
Write enable again
Write datas to address
You can use following functions.
void Flash_Erase_Chip(void)
{
uint8_t Write_Enable = 0x06;
uint8_t Erase_Chip = 0xC7;
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,RESET); // CS to low
HAL_SPI_Transmit(&hspi6,&Write_Enable,1,1000); // Write Enable Command
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,SET); // CS to high
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,RESET); // CS to low
HAL_SPI_Transmit(&hspi6,&Erase_Chip,1,1000); // Erase Chip Command
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,SET); // CS to high
}
void Flash_Write_Data()
{
uint8_t Write_Enable = 0x06;
uint8_t Page_Program = 0x02;
uint32_t Address = 0x00000000;
uint8_t txData[10] = {0xAB, 0x04, 0x06, 0xC7, 0x04, 0x90, 0x00, 0x00, 0x00, 0x00};
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,RESET); // CS to low
HAL_SPI_Transmit(&hspi6,&Write_Enable,1,1000); // Write Enable Command
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,SET); // CS to high
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,RESET); // CS to low
HAL_SPI_Transmit(&hspi6,&Page_Program,1,1000);// Page Program Command
HAL_SPI_Transmit(&hspi6,&Address,4,1000); // Write Address ( The first address of flash module is 0x00000000 )
HAL_SPI_Transmit(&hspi6,txData,10,1000); // Write 10 bytes
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,SET); // CS to high
}
void Flash_Read_Data
{
uint8_t Read_Data = 0x03;
uint32_t Address = 0x00000000;
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,RESET); // CS low
HAL_SPI_Transmit(&hspi6,&Read_Data,1,1000); // Read Command
HAL_SPI_Transmit(&hspi6,&Address,4,1000); // Write Address
HAL_SPI_Receive(&hspi6,rxData,10,1000); // Read 10 bytes
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,RESET); // CS high
}
Related
I was looking for questions related to my problem but only found questions regarding CRC32 reversing. My topic is a bit different.
I am a novice programmer and I have such a task to do. I have input (3 strings of 4 bytes). For this data, I know three checksums computed using a hash function similar to CRC32. However, it is not a standard CRC32 because it differs between the default and unknown values of the polynomial and the crcxor parameter.
So for the input data of 4 bytes I calculate the CRC using different values of the polynomial from 0 to 0xFFFFFFFF and using different values of the parameter crcxor with the values between 0 and 0xFFFF. I wrote this program in CUDA C because it runs faster than the CPU. This is my third CUDA C program right after "Hello World" and "VectorAdd" :). To calculate all possible 0xFFFF x 0xFFFFFFFF variants, it takes about 5 hours for my NVIDIA GTX1060 card.
I wanted to ask if it is possible to modify or optimize the following program code in order to do this task faster?
Ultimately, I would like to calculate 0xFFFFFFFF x 0xFFFFFFFF but I don't know yet if it can be done in a short time.
If anyone would like to have a look at my program code and provide valuable feedback, I would be extremely grateful.
#include <stdio.h>
#include <cuda_runtime.h>
#include <cuda_profiler_api.h>
__device__ unsigned long calculate_crc(unsigned long data, unsigned long poly, unsigned long cxor)
// truncated function for constant values crcinit = 0 refin = 0 refout = 0 direct = 0
{
unsigned long i, j, k, c, bit, crc = 0;
for (i=0,k=24; i<4; i++,k-=8)
{
c = (data>>k)&0xFF;
for (j=0x80; j; j>>=1)
{
bit = crc & 0x80000000;
crc<<= 1;
if (c & j) bit^= 0x80000000;
if (bit) crc^= poly;
}
}
crc^= cxor;
crc&= 0xFFFFFFFF;
return crc;
}
__global__ void calculate_crc_parameters(unsigned long n)
{
unsigned long polynom = 0;
unsigned long crcxor = 0;
//Input data:
const unsigned long data1 = 0x928F640C;
const unsigned long data2 = 0x0121B30E;
const unsigned long data3 = 0xCB652607;
// calculated CRC for the above input data and for polynom 0xFF7A1DB7: crcinit: 0, crcxor: 0x00000000, refin: 0, refout: 0, direct: 0:
// for these CRCs, the function should find the polynomial 0xFF7A1DB7 and crcxor = 0
// finds it right away because crcxor = 0
const unsigned long crc1 = 0x7076BCEB;
const unsigned long crc2 = 0x1F719D7A;
const unsigned long crc3 = 0x8369D986;
// other example crc - for crcxor> 0
// computed CRC for polynom 0xFF7A1DB7: crcinit: 0, crcxor: 0x000000FF, refin: 0, refout: 0, direct: 0:
// for these CRCs, the function should find the polynomial 0xFF7A1DB7 and crcxor = 0x000000FF
// Program find it after 1m 12sec.
/*
const unsigned long crc1 = 0x7076BC14;
const unsigned long crc2 = 0x1F719D85;
const unsigned long crc3 = 0x8369D979;
*/
// computed CRC for polynom 0xFF7A1DB7: crcinit: 0, crcxor: 0x0000FFFE, refin: 0, refout: 0, direct: 0:
// for these CRCs, the function should find the polynomial 0xFF7A1DB7 and crcxor = 0x0000FFFE
// searches for 5 hours
/*
const unsigned long crc1 = 0x70764315;
const unsigned long crc2 = 0x1F716284;
const unsigned long crc3 = 0x83692678;
*/
// CRCs - polynom 0xFF7A1DB7: crcinit: 0, crcxor: 0xFF7A1DB7, refin: 0, refout: 0, direct: 0:
// no implementation for 8-byte crcxor yet - and it would count for a long time
/*
const unsigned long crc1 = 0x8F0CA15C;
const unsigned long crc2 = 0xE00B80CD;
const unsigned long crc3 = 0x7C13C431;
*/
unsigned int index_x = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int stride_x = blockDim.x * gridDim.x;
unsigned int index_y = blockIdx.y * blockDim.y + threadIdx.y;
unsigned int stride_y = blockDim.y * gridDim.y;
unsigned int index_z = blockIdx.z * blockDim.z + threadIdx.z;
unsigned int stride_z = blockDim.z * gridDim.z;
if((index_x<n)&&(index_y<n)&&(index_z<n))
{
polynom = (index_x << 16) ^ index_y; // "gluing" the polynomial
// to get polynom e.g. 0xFF7A1DB7 we have to "glue it" with index_x and index_y
// if index_x == 0xFF7A then LSH by 16 places and we get 0xFF7A0000
// then xor from index_y: 0xFF7A0000 xor 0x00001DB7 and is 0xFF7A1DB7
crcxor = index_z; // crcxor will take the values of index_z that is from 0x0000 to 0xFFFF
if(calculate_crc(data1,polynom,crcxor)==crc1)
if(calculate_crc(data2,polynom,crcxor)==crc2)
if(calculate_crc(data3,polynom,crcxor)==crc3) // compute three checksums and compare them
printf("\nCRC parameters found ---> polynom: 0x%08X, crcxor: 0x%08X\n", polynom,crcxor);
// if the calculated 3 crc sums agree with the known 3 crcs, then display the parameters for which they were calculated
if ((crcxor%0xFF==0)&&(polynom==0xFFFFFFFF)) printf("#"); // 1m 12s from displaying # to the next #
// if the # sign is displayed 256 times, this will be the end of the program
index_x+=stride_x;
index_y+=stride_y;
index_z+=stride_z;
}
}
int main(void)
{
unsigned long N = 0x10000; // 0xFFFF + 0x01 = 65536dec
////////////////////////////////////////////////
// for computing only in X and Y axes - for crcxor = zero all the time
dim3 dimBlock( 4, 4, 1);
dim3 dimGrid(16384, 16384, 1);
////////////////////////////////////////////////
// for computing on the X, Y and Z axes, i.e. for crcxor taking values from the Z axis from 0 to 65535
//dim3 dimBlock( 4, 4, 64); // 4 * 4 * 64 = 1024 --- maximum block size
//dim3 dimGrid(16384, 16384, 1024); //uncomment this 2 lines for crcxor > 0
// 4 4 64
// * * *
// 16384 16384 1024
// = = =
// 0x10000 0x10000 0x10000
// x, y, and z will trigger 65,536 times each
cudaProfilerStart();
calculate_crc_parameters<<<dimGrid, dimBlock>>>(N);
cudaDeviceSynchronize();
cudaDeviceReset();
cudaProfilerStop();
return 0;
}
I compile it in cmd by: nvcc name.cu -o name
I work on win10 with Cuda Toolkit 11.5
Card is NVIDIA GTX 1060.
Could the use of pointers or memory allocations somehow speed up this program?
I computing test crc values here
Optimization should begin with the algorithm, as opposed to optimizing a painfully pointless brute-force approach.
You can factor the search for a polynomial and a final exclusive-or, doing the polynomial first, and then (trivially) finding the exclusive-or value. All you need to do is take the exclusive-or of two of your data values, and the find the polynomial that produces the exclusive-or of the two CRCs of those values, assuming a zero final exclusive or. You will need to try at least two pairs in order to narrow it down to one choice for the polynomial.
Once you have the polynomial, now compute the CRC on one of your data values, exclusive-or that with the desired CRC, and now you have your final exclusive-or value. No search needed for the second step.
The polynomial search is fast enough that you can just use your CPU. No GPU or CUDA or whatever is needed. It took 40 seconds on my three-year old laptop. You only need to try odd polynomials. Even polynomials are not valid.
Exclusive-oring the data and the CRCs also cancels the initial value. So you can find the polynomial this way for CRCs that have both a non-zero initial value and a non-zero final exclusive or. However in order to then solve for both the initial value and final exclusive-or, you will need examples with different length messages, i.e. other than all four-byte messages. There are 232 possible combinations of initial value and final exclusive-or that will match any and all CRCs of four-byte messages.
As an aside, your CRC routine is needlessly complicated. See equivalent below. This prints poly = ff7a1db7, xor = 0000fffe:
#include <stdio.h>
#include <stdint.h>
uint32_t calculate_crc(uint32_t data, uint32_t poly, uint32_t xor) {
for (int i = 0; i < 32; i++)
data = data & 0x80000000 ? (data << 1) ^ poly : data << 1;
return data ^ xor;
}
void findp(uint32_t data1, uint32_t data2, uint32_t data3,
uint32_t crc1, uint32_t crc2, uint32_t crc3) {
uint32_t d = data2, c = crc2;
data1 ^= data3; crc1 ^= crc3;
data2 ^= data3; crc2 ^= crc3;
data3 ^= d; crc3 ^= c;
uint32_t poly = 1;
do {
if (calculate_crc(data1, poly, 0) == crc1 &&
calculate_crc(data2, poly, 0) == crc2 &&
calculate_crc(data3, poly, 0) == crc3)
printf("poly = %08x, xor = %08x\n",
poly, calculate_crc(d, poly, 0) ^ c);
poly += 2;
} while (poly != 1);
}
int main(void) {
findp(0x928F640C, 0x0121B30E, 0xCB652607,
0x70764315, 0x1F716284, 0x83692678);
return 0;
}
There is an even faster, in fact massively faster, approach by solving a set of linear equations over GF(2). However it would take me longer than 40 seconds to write that code, so this is where I would stop. Unless I had many, many of these CRCs to find. Or unless I was trying to find, for example, a 64-bit CRC polynomial.
I have some code for texture object allocation and Host to Device copy. It is just a modification of the answer here. I do not explicitly use streams, just cudaSetDevice()
This code works fine, however, when I run the Visual Profiler, I can see that the memory copies from Host to Array are not asynchronous. They are allocated each to their own device stream, but the second one does not start until the first one finishes (running on 2 GPUs). I have tried it with large images, so I make certain that its not overhead from CPU.
My guess is that there is something in the code that requires to be synchronous thus halts the CPU, but I don't know what. What can I do to make this loop asynchronous?
An MCVE:
void CreateTexture(int num_devices,float* imagedata, int nVoxelX, int nVoxelY, int nVoxelZ ,cudaArray** d_cuArrTex, cudaTextureObject_t *texImage);
int main(void)
{
int deviceCount =0 ;
cudaGetDeviceCount(&deviceCount);
int nVoxelX=512;
int nVoxelY=512;
int nVoxelZ=512;
float* image=(float*)malloc(nVoxelX*nVoxelY*nVoxelZ*sizeof(float));
cudaTextureObject_t *texImg =new cudaTextureObject_t[deviceCount];
cudaArray **d_cuArrTex = new cudaArray*[deviceCount];
CreateTexture(deviceCount,image, nVoxelX,nVoxelY, nVoxelZ,d_cuArrTex,texImg);
}
Actual function:
void CreateTexture(int num_devices, float* imagedata, int nVoxelX, int nVoxelY, int nVoxelZ ,cudaArray** d_cuArrTex, cudaTextureObject_t *texImage)
{
//size_t size_image=nVoxelX*nVoxelY*nVoxelZ;
for (unsigned int i = 0; i < num_devices; i++){
cudaSetDevice(i);
//cudaArray Descriptor
const cudaExtent extent = make_cudaExtent(nVoxelX, nVoxelY, nVoxelZ);
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<float>();
//cuda Array
cudaMalloc3DArray(&d_cuArrTex[i], &channelDesc, extent);
//cudaCheckErrors("Texture memory allocation fail");
cudaMemcpy3DParms copyParams = {0};
//Array creation
copyParams.srcPtr = make_cudaPitchedPtr((void *)imagedata, extent.width*sizeof(float), extent.width, extent.height);
copyParams.dstArray = d_cuArrTex[i];
copyParams.extent = extent;
copyParams.kind = cudaMemcpyHostToDevice;
cudaMemcpy3DAsync(©Params);
//cudaCheckErrors("Texture memory data copy fail");
//Array creation End
cudaResourceDesc texRes;
memset(&texRes, 0, sizeof(cudaResourceDesc));
texRes.resType = cudaResourceTypeArray;
texRes.res.array.array = d_cuArrTex[i];
cudaTextureDesc texDescr;
memset(&texDescr, 0, sizeof(cudaTextureDesc));
texDescr.normalizedCoords = false;
texDescr.filterMode = cudaFilterModePoint;
texDescr.addressMode[0] = cudaAddressModeBorder;
texDescr.addressMode[1] = cudaAddressModeBorder;
texDescr.addressMode[2] = cudaAddressModeBorder;
texDescr.readMode = cudaReadModeElementType;
cudaCreateTextureObject(&texImage[i], &texRes, &texDescr, NULL);
//cudaCheckErrors("Texture object creation fail");
}
}
The two main problems I can see with the code are:
Your host allocation is a pageable allocation. Asynchrony of copy operations in CUDA where one of the targets is host memory requires a pinned alloction for host memory.
You have other synchronizing operations in your create textures loop. Device allocation operations (cudaMalloc3DArray in this case) are synchronizing, in my experience. I haven't run tests to determine if cudaCreateTextureObject is synchronizing, but I wouldn't be surprised if it was. Therefore my recommendation for asynchrony in general is to get synchronizing operations out of the loop.
In your case, we can refactor your code as follows, which seems to allow overlap of operations from the perspective of nvprof:
$ cat t399.cu
void CreateTexture(int num_devices, float* imagedata, int nVoxelX, int nVoxelY, int nVoxelZ ,cudaArray** d_cuArrTex, cudaTextureObject_t *texImage)
{
//size_t size_image=nVoxelX*nVoxelY*nVoxelZ;
const cudaExtent extent = make_cudaExtent(nVoxelX, nVoxelY, nVoxelZ);
for (unsigned int i = 0; i < num_devices; i++){
cudaSetDevice(i);
//cudaArray Descriptor
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<float>();
//cuda Array
cudaMalloc3DArray(&d_cuArrTex[i], &channelDesc, extent);
//cudaCheckErrors("Texture memory allocation fail");
}
for (unsigned int i = 0; i < num_devices; i++){
cudaSetDevice(i);
cudaMemcpy3DParms copyParams = {0};
//Array creation
copyParams.srcPtr = make_cudaPitchedPtr((void *)imagedata, extent.width*sizeof(float), extent.width, extent.height);
copyParams.dstArray = d_cuArrTex[i];
copyParams.extent = extent;
copyParams.kind = cudaMemcpyHostToDevice;
cudaMemcpy3DAsync(©Params);
//cudaCheckErrors("Texture memory data copy fail");
}
for (unsigned int i = 0; i < num_devices; i++){
cudaSetDevice(i);
//Array creation End
cudaResourceDesc texRes;
memset(&texRes, 0, sizeof(cudaResourceDesc));
texRes.resType = cudaResourceTypeArray;
texRes.res.array.array = d_cuArrTex[i];
cudaTextureDesc texDescr;
memset(&texDescr, 0, sizeof(cudaTextureDesc));
texDescr.normalizedCoords = false;
texDescr.filterMode = cudaFilterModePoint;
texDescr.addressMode[0] = cudaAddressModeBorder;
texDescr.addressMode[1] = cudaAddressModeBorder;
texDescr.addressMode[2] = cudaAddressModeBorder;
texDescr.readMode = cudaReadModeElementType;
cudaCreateTextureObject(&texImage[i], &texRes, &texDescr, NULL);
//cudaCheckErrors("Texture object creation fail");
}
for (unsigned int i = 0; i < num_devices; i++){
cudaSetDevice(i);
cudaDeviceSynchronize();
}
}
int main(void)
{
int deviceCount =0 ;
cudaGetDeviceCount(&deviceCount);
int nVoxelX=512;
int nVoxelY=512;
int nVoxelZ=512;
float* image;
cudaHostAlloc(&image, nVoxelX*nVoxelY*nVoxelZ*sizeof(float), cudaHostAllocDefault);
cudaTextureObject_t *texImg =new cudaTextureObject_t[deviceCount];
cudaArray **d_cuArrTex = new cudaArray*[deviceCount];
CreateTexture(deviceCount,image, nVoxelX,nVoxelY, nVoxelZ,d_cuArrTex,texImg);
}
$ nvcc -o t399 t399.cu
$ cuda-memcheck ./t399
========= CUDA-MEMCHECK
========= ERROR SUMMARY: 0 errors
$ nvprof --print-gpu-trace ./t399
==19953== NVPROF is profiling process 19953, command: ./t399
==19953== Profiling application: ./t399
==19953== Profiling result:
Start Duration Grid Size Block Size Regs* SSMem* DSMem* Size Throughput SrcMemType DstMemType Device Context Stream Name
1.55311s 90.735ms - - - - - 512.00MB 5.5106GB/s Pinned Array Tesla P100-PCIE 1 7 [CUDA memcpy HtoA]
1.55316s 90.640ms - - - - - 512.00MB 5.5163GB/s Pinned Array Tesla K40m (1) 2 18 [CUDA memcpy HtoA]
1.55318s 85.962ms - - - - - 512.00MB 5.8165GB/s Pinned Array Tesla K20Xm (2) 3 29 [CUDA memcpy HtoA]
1.55320s 89.908ms - - - - - 512.00MB 5.5612GB/s Pinned Array Tesla K20Xm (3) 4 40 [CUDA memcpy HtoA]
Regs: Number of registers used per CUDA thread. This number includes registers used internally by the CUDA driver and/or tools and can be more than what the compiler shows.
SSMem: Static shared memory allocated per CUDA block.
DSMem: Dynamic shared memory allocated per CUDA block.
SrcMemType: The type of source memory accessed by memory operation/copy
DstMemType: The type of destination memory accessed by memory operation/copy
$
my system here is a 4-GPU system with two GPUs hanging on each of 2 root ports. Therefore the Host->Device pinned transfer bandwidth on PCIE Gen3 of about 10GB/s is getting split from the profiler's perspective between the 2 GPUs on each port, but careful study of the profiler start and duration times for the transfers indicate all 4 are overlapped from the profiler's perspective.
My question is one.
1. I want to FFT the unstable input voltage through the Arduino.
How do I transform from an existing Arduino FFT source?
I'm an Arduino starter.
Please give me a detailed answer.
/*
fft_adc_serial.pde
guest openmusiclabs.com 7.7.14
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb.
*/
#define LOG_OUT 1 // use the log output function
#define FFT_N 256 // set to 256 point fft
#include <FFT.h> // include the library
void setup() {
Serial.begin(115200); // use the serial port
TIMSK0 = 0; // turn off timer0 for lower jitter
ADCSRA = 0xe5; // set the adc to free running mode
ADMUX = 0x40; // use adc0
DIDR0 = 0x01; // turn off the digital input for adc0
}
void loop() {
while(1) { // reduces jitter
cli(); // UDRE interrupt slows this way down on arduino1.0
while(!(ADCSRA & 0x10)); // wait for adc to be ready
ADCSRA = 0xf5; // restart adc
byte m = ADCL; // fetch adc data
byte j = ADCH;
int k = (j << 8) | m; // form into an int
k -= 0x0200; // form into a signed int
k <<= 6; // form into a 16b signed int
fft_window(); // window the data for better frequency respons
fft_reorder(); // reorder the data before doing the fft
fft_run(); // process the data in the fft
fft_mag_log(); // take the output of the fft
sei();
Serial.println("start"); // header send
for (byte i = 0 ; i < FFT_N ; i+=2) {
Serial.write(fft_input[i]); // send out the real part
Serial.write(fft_input[i+1]); // send out the imaginary part
}
}
}
Can anyone help me figure out how to piece these two pieces of code together so I get the result I need? My eyes are crossing from looking at this. I know this is a breeze for probably everyone other than myself, but I am not a programmer and this is just for one small personal project.
So far, after hours and hours of reading and watching any videos I could find relating to Arduino, Pubnub and sensors, I have sensor reading publishing to Pubnub. I created a Freeboard account for visualization and that's all working. The problem is, the data being published is wrong.
Basically, I'm wanting to read a battery voltage and publish it to PubNub. I can get the Arduino (Uno R3) to read the voltage and I can adjust the values in the code to match the actual voltage. The problem I run into is taking that bit of code that works and stuffing it into the JSON array that gets published to PubNub.
If anyone would be willing to help me and maybe explain a little (or not - I'm okay if I just get it working), I would SO appreciate the time, help and effort.
Thanks!
//Each sketch works indepently. I need to merge them to get the correct reading published.
//VoltagePubNub.ino
(This is the one that publishes, which is what I want. I just want the published value to be the value of the second sketch.)
#include <SPI.h>
#include <Ethernet.h>
#include <PubNub.h>
#include <aJSON.h>
// Some Ethernet shields have a MAC address printed on a sticker on the shield;
// fill in that address here, or choose your own at random:
const static byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// Memory saving tip: remove myI and dnsI from your sketch if you
// are content to rely on DHCP autoconfiguration.
IPAddress myI(192, 168, 2, 114);
IPAddress dnsI(8, 8, 8, 8);
const static char pubkey[] = "publish_key";
const static char subkey[] = "subscribe_key";
const static char channel[] = "channel_name";
char uuid[] = "UUID";
#define NUM_CHANNELS 1 // How many analog channels do you want to read?
const static uint8_t analog_pins[] = {A0}; // which pins are you reading?
void setup()
{
Serial.begin(9600);
Serial.println("Serial set up");
Ethernet.begin((byte*) mac, myI, dnsI);
Serial.println("Ethernet set up");
delay(1000);
Serial.println("Ethernet set up");
PubNub.begin(pubkey, subkey);
Serial.println("PubNub set up");
delay(5000);
}
void loop()
{
Ethernet.maintain();
EthernetClient *client;
// create JSON objects
aJsonObject *msg, *analogReadings;
msg = aJson.createObject();
aJson.addItemToObject(msg, "analogReadings", analogReadings = aJson.createObject());
// get latest sensor values then add to JSON message
for (int i = 0; i < NUM_CHANNELS; i++) {
String analogChannel = String(analog_pins[i]);
char charBuf[analogChannel.length()+1];
analogChannel.toCharArray(charBuf, analogChannel.length()+1);
int analogValues = analogRead(analog_pins[i]);
aJson.addNumberToObject(analogReadings, charBuf, analogValues);
}
// convert JSON object into char array, then delete JSON object
char *json_String = aJson.print(msg);
aJson.deleteItem(msg);
// publish JSON formatted char array to PubNub
Serial.print("publishing a message: ");
Serial.println(json_String);
client = PubNub.publish(channel, json_String);
if (!client) {
Serial.println("publishing error");
} else
free(json_String);
client->stop();
delay(5000);
}
//VoltageSensor.ino
(This is the one with the correct value, but no publish feature.)
int analogInput = A0;
float vout = 0.0;
float vin = 0.0;
float R1 = 31000.0; //
float R2 = 8700.0; //
int value = 0;
int volt = 0;
void setup(){
pinMode(analogInput, INPUT);
Serial.begin(9600);
Serial.print("DC VOLTMETER");
Serial.println("");
}
void loop(){
// read the value at analog input
value = analogRead(analogInput);
vout = (value * 4.092) / 1024.0;
vin = vout / (R2/(R1+R2));
Serial.print("INPUT V= ");
Serial.println(vin,2);
delay(2000);
}
It may not be the most glamorous or the proper way of doing it, but I got this to do what I need. I edited the first sketch with the following code:
// create JSON objects
aJsonObject *msg, *analogReadings;
msg = aJson.createObject();
aJson.addItemToObject(msg, "analogReadings", analogReadings = aJson.createObject());
// get latest sensor values then add to JSON message
for (int i = 0; i < NUM_CHANNELS; i++) {
float vout = 0.0;
float vin = 0.0;
float R1 = 33060.0; //
float R2 = 7600.0; //
int value = 0;
int volt = 0;
//Serial.print("INPUT V= ");
//Serial.println(vin,2);
String analogChannel = String(analog_pins[i]);
value = analogRead(analog_pins[i]);
vout = (value * 4.092) / 1024.0;
vin = vout / (R2/(R1+R2));
char charBuf[analogChannel.length()+1];
analogChannel.toCharArray(charBuf, analogChannel.length()+1);
float theVoltage = (vin);
int analogValues = analogRead(analog_pins[i]);
aJson.addNumberToObject(analogReadings, charBuf, theVoltage);
}
// convert JSON object into char array, then delete JSON object
char *json_String = aJson.print(msg);
aJson.deleteItem(msg);
Now the value is published to PubNub and is graphed on Freeboard.io at this link .
i need help!
i have a TI msp-exp430g2 launchpad and a RFM22B and i need them to communicate with each other and i have no idea how to. after along time i came up with the code below to send data to the RFM22. i have an oscilloscope connected to the ANT pin of the RFM22 and i can see only noise and no output!
can anyone tell me what im doing wrong (alot abusively) and maybe someone has an example codes or a project that can help.
#include <msp430.h>
/*
* main.c
*
// MSP430G2xx3
// -----------------
// /|\| XIN|-
// | | |
// --|RST XOUT|-
// | |
// | P1.2|-> Data Out (UCA0SIMO)
// | |
// LED <-|P1.0 P1.3|-> nSel
// | |
// | P1.4|-> Serial Clock Out (UCA0CLK)
*
*/
//unsigned int address;
//unsigned char data;
void init(void);
void initRFM(void);
void write(int address, char data);
void txRFM(void);
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
int t;
for (t=0;t<150;t++){ // 150 ms now
__delay_cycles(1000); // 1000 usec
}
init();
initRFM();
while(1){
txRFM();
}
return 0;
}
void txRFM(void){
unsigned char i;
write(0x07, 0x01); // To ready mode
__delay_cycles(50);
write(0x08, 0x03); // FIFO reset
write(0x08, 0x00); // Clear FIFO
write(0x34, 64); // preamble = 64nibble
write(0x3E, 17); // packet length = 17bytes
for (i=0; i<17; i++)
{
write(0x7F, 0xAA); // send payload to the FIFO
}
write(0x05, 0x04); // enable packet sent interrupt
write(0x07, 9); // Start TX
}
void write(int address, char data){
P1OUT &= ~BIT3; // start write
address |= 0x80;
UCA0TXBUF = address;
while ( ! ( IFG2 & UCA0TXIFG ) ) ;
UCA0TXBUF = data;
__delay_cycles(20);
P1OUT |= BIT3; // end write
}
void init(void) {
P1DIR |= BIT3; // P1.3 nSEL for writing to RFM22
P1OUT |= BIT3; // no write
P1SEL |= BIT2 + BIT4; // P1.4 clock out, P1.2 data out (UCA0SIMO)
P1SEL2 |= BIT2 + BIT4;
UCA0CTL0 |= UCCKPL + UCMSB + UCMST + UCSYNC; // UCCKPL- inactive high, UCMSB- MSB first, UCMST- Master mode, UCSYNC- sync mode
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 |= 0x02; // /2
UCA0BR1 = 0; //
UCA0MCTL = 0; // No modulation
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
IE2 |= UCA0RXIE; // Enable USCI0 RX interrupt
}
void initRFM(void){
//write(0x03, 0x00); // Disable all interrupts
write(0x07, 0x01); // Set READY mode
write(0x09, 0x7F); // Cap = 12.5pF
write(0x0A, 0x05); // Clk output is 2MHz
write(0x0B, 0xF4); // GPIO0 is for RX data output
write(0x0C, 0xEF); // GPIO1 is TX/RX data CLK output
write(0x0D, 0x00); // GPIO2 for MCLK output
write(0x0E, 0x00); // GPIO port use default value
write(0x0F, 0x70); // NO ADC used
write(0x10, 0x00); // no ADC used
write(0x12, 0x00); // No temp sensor used
write(0x13, 0x00); // no temp sensor used
write(0x70, 0x20); // No manchester code, no data whiting, data rate < 30Kbps
write(0x1C, 0x1D); // IF filter bandwidth
write(0x1D, 0x40); // AFC Loop
//write(0x1E, 0x0A); // AFC timing
write(0x20, 0xA1); // clock recovery
write(0x21, 0x20); // clock recovery
write(0x22, 0x4E); // clock recovery
write(0x23, 0xA5); // clock recovery
write(0x24, 0x00); // clock recovery timing
write(0x25, 0x0A); // clock recovery timing
//write(0x2A, 0x18);
write(0x2C, 0x00);
write(0x2D, 0x00);
write(0x2E, 0x00);
write(0x6E, 0x27); // TX data rate 1
write(0x6F, 0x52); // TX data rate 0
write(0x30, 0x8C); // Data access control
write(0x32, 0xFF); // Header control
write(0x33, 0x42); // Header 3, 2, 1, 0 used for head length, fixed packet length, synchronize word length 3, 2,
write(0x34, 64); // 64 nibble = 32 byte preamble
write(0x35, 0x20); // 0x35 need to detect 20bit preamble
write(0x36, 0x2D); // synchronize word
write(0x37, 0xD4);
write(0x38, 0x00);
write(0x39, 0x00);
write(0x3A, 's'); // set tx header 3
write(0x3B, 'o'); // set tx header 2
write(0x3C, 'n'); // set tx header 1
write(0x3D, 'g'); // set tx header 0
write(0x3E, 17); // set packet length to 17 bytes
write(0x3F, 's'); // set rx header
write(0x40, 'o');
write(0x41, 'n');
write(0x42, 'g');
write(0x43, 0xFF); // check all bits
write(0x44, 0xFF); // Check all bits
write(0x45, 0xFF); // check all bits
write(0x46, 0xFF); // Check all bits
write(0x56, 0x01);
write(0x6D, 0x07); // Tx power to max
write(0x79, 0x00); // no frequency hopping
write(0x7A, 0x00); // no frequency hopping
write(0x71, 0x22); // GFSK, fd[8]=0, no invert for TX/RX data, FIFO mode, txclk-->gpio
write(0x72, 0x48); // Frequency deviation setting to 45K=72*625
write(0x73, 0x00); // No frequency offset
write(0x74, 0x00); // No frequency offset
write(0x75, 0x53); // frequency set to 434MHz
write(0x76, 0x64); // frequency set to 434MHz
write(0x77, 0x00); // frequency set to 434Mhz
write(0x5A, 0x7F);
write(0x59, 0x40);
write(0x58, 0x80);
write(0x6A, 0x0B);
write(0x68, 0x04);
write(0x1F, 0x03);
}
I haven't worked with your specific radio, but I have worked extensively with TI CCxxxx radios connected with various TI dev kits (launchpad included).
I would begin by ensuring that your hardwareInit() routine sets up the SPI peripheral correctly. When I was developing with TI radios, I would do the following:
// Setup CSn line.
P2DIR |= BIT7;
P2OUT |= BIT7;
P2SEL &= ~BIT7;
P2SEL2 &= ~BIT7;
// Setup the USCIB0 peripheral for SPI operation.
UCB0CTL1 |= UCSWRST;
UCB0CTL0 |= (UCMODE_0 | UCCKPH | UCMSB | UCMST | UCSYNC);
UCB0CTL1 |= UCSSEL_2;
UCB0BR1 = 0;
UCB0BR0 = 2;
// Setup SCLK, MISO, and MOSI lines.
P1SEL |= BIT5 | BIT6 | BIT7;
P1SEL2 |= BIT5 | BIT6 | BIT7;
UCB0CTL1 &= ~UCSWRST;
Then I would test a write() function to ensure that I was writing using the peripheral correctly:
void write(unsigned char address, const unsigned char *buffer, unsigned char count)
{
register volatile unsigned char i; // Buffer iterator
// Change MISO pin to SPI.
P1SEL |= BIT6;
P1SEL2 |= BIT6;
P2DIR &= ~BIT7;
// Look for CHIP_RDYn from radio.
while (P1IN & BIT6);
// Write the address/command byte.
UCB0TXBUF = address;
// Write data byte(s).
for (i = 0; i < count; i++)
{
while (!(IFG2 & UCB0TXIFG));
UCB0TXBUF = *(buffer+i);
}
// Wait for operation to complete.
while(UCB0STAT & UCBUSY);
P2OUT |= BIT7;
// Change MISO pin to general purpose output (LED use if available).
P1SEL &= ~BIT6;
P1SEL2 &= ~BIT6;
}