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;
}
Related
I am working on a project to write to and read from a TP Link / Kaza power strip or smart plug.
The data that is sent is encrypted json that has been "autokey encrypted".
So far I have been able to convert a typescript encrypt function and it works well. I get the expected result. However, I need to add a "header" to my encrypted data. That data is 3 null bytes followed by a byte that is a measure of the length of the encrypted bytes.
The typescript example has this bit of code to "encrypt with headers", however, I've hit a bit of a wall trying to convert it to something usable. Can someone nudge me along the path ?
First are the two typescript functions: (borrowed from https://github.com/plasticrake/tplink-smarthome-crypto/blob/master/src/index.ts)
/**
* Encrypts input where each byte is XOR'd with the previous encrypted byte.
*
* #param input - Data to encrypt
* #param firstKey - Value to XOR first byte of input
* #returns encrypted buffer
*/
export function encrypt(input: Buffer | string, firstKey = 0xab): Buffer {
const buf = Buffer.from(input);
let key = firstKey;
for (let i = 0; i < buf.length; i += 1) {
// eslint-disable-next-line no-bitwise
buf[i] ^= key;
key = buf[i];
}
return buf;
}
/**
* Encrypts input that has a 4 byte big-endian length header;
* each byte is XOR'd with the previous encrypted byte.
*
* #param input - Data to encrypt
* #param firstKey - Value to XOR first byte of input
* #returns encrypted buffer with header
*/
export function encryptWithHeader(
input: Buffer | string,
firstKey = 0xab
): Buffer {
const msgBuf = encrypt(input, firstKey);
const outBuf = Buffer.alloc(msgBuf.length + 4);
outBuf.writeUInt32BE(msgBuf.length, 0);
msgBuf.copy(outBuf, 4);
return outBuf;
}
Second is what I have so far.
// This part works well and produces the expected results
String encrypt(String input)
{
int16_t firstKey = 0xab;
String buf;
int key;
int i;
buf = input;
key = firstKey;
i = 0;
for (;i < buf.length();(i = i + 1))
{
buf[i] ^= key;
key = buf[i];
}
return buf;
}
// This does not function yet, as I'm pretty lost..
// This was orginally converted from typescript with https://andrei-markeev.github.io/ts2c/
// I started work on converting this, but ran into errors I don't know how to solve.
String encryptWithHeader(String input){
String msgBuf;
String outBuf;
int16_t firstKey = 0xab;
char * null = NULL;
msgBuf = encrypt(input);
outBuf = msgBuf.length() +1;
//this is where I got lost...
assert(null != NULL);
null[0] = '\0';
strncat(null, outBuf, msgBuf.length());
str_int16_t_cat(null, 4);
outBuf = msgBuf + 4
return outBuf;
}
Finally, the data:
//this is the unencrypted json
String offMsg = "{\"system\":{\"set_relay_state\":{\"state\":0}}}";
//current encrypt function produces:
d0f281f88bff9af7d5ef94b6c5a0d48bf99cf091e8b7c4b0d1a5c0e2d8a381f286e793f6d4eedea3dea3
//the working "withheaders" should produce:
00002ad0f281f88bff9af7d5ef94b6c5a0d48bf99cf091e8b7c4b0d1a5c0e2d8a381f286e793f6d4eedea3dea3
Admittedly my C/C++ ability is very limited and I can spell typescript, that's about all. I have a very extensive history with PHP. As useful as that is. So, I understand the basics of data structures and whatnot, but I'm venturing off into areas I've never been in. Any help would be greatly appreciated.
It looks like the encryption is fairly simple: write the current character XORed with the key to the buffer and make that newly written character the new key. It also looks like the "withHeaders" version adds the length of the encrypted string as a 4 byte integer to the start of the buffer. I think it might be easier to allocate a character array and pass that array to a function that writes the result to that buffer. For example:
void encryptWithHeader(byte buffer[], int bufferLength, byte key, String message) {
int i;
uint32_t messageLength = message.length();
Serial.println(message);
Serial.println(message.length());
// check that we won't overrun the buffer
if ( messageLength + 5 < bufferLength) {
buffer[0] = messageLength >> 24 & 0xFF;
buffer[1] = messageLength >> 16 & 0xFF;
buffer[2] = messageLength >> 8 & 0xFF;
buffer[3] = messageLength & 0xFF;
for (i = 0; i < messageLength; i++) {
buffer[i + 4] = message[i] ^ key;
key = buffer[i + 4];
}
}
else { // we would have overrun the buffer
Serial.println("not enough room in buffer for message");
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
byte theBuffer[64];
int i;
String offMsg = "{\"system\":{\"set_relay_state\":{\"state\":0}}}";
encryptWithHeader(theBuffer, 64, 0xab, offMsg);
// now print it out to check
for (i = 0; i < offMsg.length() + 4; i++) {
if (theBuffer[i] < 0x10) // adds an extra zero if a byte prints as on1y 1 char
Serial.print("0");
Serial.print(theBuffer[i], HEX);
}
while (true)
;
}
If you want to send the character buffer to a remote device you can send it out one byte at a time:
for (i = 0; i < offMsg.length() + 4; i++)
Serial.write(theBuffer[i]);
I'm trying to create a full HTML result with HTTP headers with the correct size for content-length as simple as possible.
I looked at setbuf() function but it only works with streams, but I want to directly buffer the output to memory without having a disk involved. Is there a simpler function that does what I'm trying to achieve?
I know in php, one can use ob_start() to start buffering data and ob_get_contents() to load the data in memory and determine the size so is there anything like this in C that I can use?
int main(){
char *mybuf=malloc(1048576); //Allocate 1MB memory for buffer
char *mytitle="Webpage title";
char *mydesc="This is a page version";
int myver=2;
//print HTTP header of known data
printf("HTTP/1.1 200 OK\r\n");
printf("Server: Something\r\n");
printf("Content-type: text/html; charset=UTF-8\r\n");
printf("Cache-control: no-cache\r\n");
//Buffer HTML output to get size (we don't print these 4 lines yet)
sprintf(mybuf,"<html><head><title>%s</title></head><body>\r\n",mytitle);
sprintf(mybuf+strlen(mybuf),"<h1>%s</h1>\r\n",mytitle);
sprintf(mybuf+strlen(mybuf),"<p>%s %d</p>\r\n",mydesc,myver);
sprintf(mybuf+strlen(mybuf),"</body></html>\r\n");
//Print content length header with size of buffered data
printf("Content-length: %d\r\n",strlen(mybuf));
//then print the rest of the data
printf("%s",mybuf);
free(mybuf);
return 0;
}
The C language specification does not define any facility for streams backed only by memory, without any underlying file. Your sprintf() based approach is not bad, but it could be improved by capturing and using the return value, which tells you how many characters were printed. You could use this to avoid all the strlen() calls, which could be a considerable savings if the content is large, especially if it is printed in many small pieces:
size_t total_bytes_written = 0;
long rval;
rval = sprintf(mybuf, "<html><head><title>%s</title></head><body>\r\n", mytitle);
if (rval < 0) {
// handle error ...
}
total_bytes_written += rval;
rval = sprintf(mybuf + total_bytes_written, "<h1>%s</h1>\r\n", mytitle);
// ...
Alternatively, if you are on a system that conforms to POSIX.1-2008 or later, and you are willing to limit your program to such systems, then you might find open_memstream() of interest. This gives you a stream backed by a dynamically managed block of memory. You would write to it with fprintf() or other stream IO functions, and when done, read back a pointer to the data and the total size. Something like this:
char *buf_ptr = NULL;
size_t buf_size = 0;
FILE *mem = open_memstream(&buf_ptr, &buf_size);
fprintf(mem, "<html><head><title>%s</title></head><body>\r\n", mytitle);
fprintf(mem, "<h1>%s</h1>\r\n", mytitle);
// ...
fclose(mem); // mandatory
printf("Content-length: %d\r\n", buf_size);
printf("%s", buf_ptr); // the data are guaranteed null-terminated
free(buf); // you are responsible for this
(All error checks omitted for brevity.)
This relieves you of the manual size tracking, and it gains you a dynamically-growing backing buffer so that you can handle both large and small outputs with reasonable memory efficiency.
There are multiple solutions to this problem:
your approach is OK, but you should use snprintf() to avoid potential buffer overflows:
int main() {
char *mybuf = malloc(1048576); //Allocate 1MB memory for buffer
const char *mytitle = "Webpage title";
const char *mydesc = "This is a page version";
int myver = 2;
size_t pos = 0;
//print HTTP header of known data
printf("HTTP/1.1 200 OK\r\n");
printf("Server: Something\r\n");
printf("Content-type: text/html; charset=UTF-8\r\n");
printf("Cache-control: no-cache\r\n");
//Buffer HTML output to get size (we don't print these 4 lines yet)
pos += snprintf(mybuf + pos, pos < sizeof mybuf ? sizeof mybuf - pos : 0,
"<html><head><title>%s</title></head><body>\r\n", mytitle);
pos += snprintf(mybuf + pos, pos < sizeof mybuf ? sizeof mybuf - pos : 0,
"<h1>%s</h1>\r\n", mytitle);
pos += snprintf(mybuf + pos, pos < sizeof mybuf ? sizeof mybuf - pos : 0,
"<p>%s %d</p>\r\n", mydesc, myver);
pos += snprintf(mybuf + pos, pos < sizeof mybuf ? sizeof mybuf - pos : 0,
"</body></html>\r\n");
//Print content length header with size of buffered data
printf("Content-length: %zu\r\n", pos);
printf("\r\n");
//then print the rest of the data
printf("%s", mybuf);
free(mybuf);
return 0;
}
Here is a simpler one, combining the calls and using snprintf to compute the length:
int main() {
const char *mytitle = "Webpage title";
const char *mydesc = "This is a page version";
int myver = 2;
size_t length = 0;
//print HTTP header of known data
printf("HTTP/1.1 200 OK\r\n");
printf("Server: Something\r\n");
printf("Content-type: text/html; charset=UTF-8\r\n");
printf("Cache-control: no-cache\r\n");
//Buffer HTML output to get size (we don't print these 4 lines yet)
length = snprintf(NULL, 0,
"<html><head><title>%s</title></head><body>\r\n"
"<h1>%s</h1>\r\n"
"<p>%s %d</p>\r\n"
"</body></html>\r\n",
mytitle, mytitle, mydesc, myver);
//Print content length header with size of buffered data
printf("Content-length: %zu\r\n", length);
printf("\r\n");
//then print the rest of the data
printf("<html><head><title>%s</title></head><body>\r\n"
"<h1>%s</h1>\r\n"
"<p>%s %d</p>\r\n"
"</body></html>\r\n",
mytitle, mytitle, mydesc, myver);
return 0;
}
you could use open_memstream() as explained by John Bollinger:
int main() {
const char *mytitle = "Webpage title";
const char *mydesc = "This is a page version";
int myver = 2;
size_t length = 0;
char *buf_ptr = NULL;
size_t buf_size = 0; // the buffer size
int length = 0; // the length of the output
FILE *mem = open_memstream(&buf_ptr, &buf_size);
//print HTTP header of known data
printf("HTTP/1.1 200 OK\r\n");
printf("Server: Something\r\n");
printf("Content-type: text/html; charset=UTF-8\r\n");
printf("Cache-control: no-cache\r\n");
//Buffer HTML output to get size (we don't print these 4 lines yet)
if (mem == NULL) {
// Deal with the error
printf("Internal error\r\n");
return 1;
}
length = fprintf(mem,
"<html><head><title>%s</title></head><body>\r\n"
"<h1>%s</h1>\r\n"
"<p>%s %d</p>\r\n"
"</body></html>\r\n",
mytitle, mytitle, mydesc, myver);
//Print content length header with size of buffered data
printf("Content-length: %zu\r\n", length);
printf("\r\n");
//then print the rest of the data
//beware that buf_ptr is not necessarily null terminated
printf("%.*s", length, buf_ptr);
//could also use fwrite(f, buf_ptr, 1, length, stdout);
free(buf_ptr);
return 0;
}
you can implement your own mem_printf() that allocates or reallocates a memory buffer:
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int mem_printf(char **bufp, size_t *lenp, const char *fmt, ...) {
char buf[1024];
va_list ap;
char *newbuf;
int len;
va_start(ap, fmt);
len = vsnprintf(buf, sizeof buf, fmt, ap);
va_end(ap);
if (len < 0)
return -1;
newbuf = realloc(*bufp, *lenp + len + 1);
if (newbuf == NULL)
return -1;
*bufp = newbuf;
if ((size_t)len < sizeof buf) {
memcpy(newbuf + *lenp, buf, len + 1);
} else {
va_start(ap, fmt);
vsnprintf(newbuf + *lenp, len + 1, fmt, ap);
va_end(ap);
}
*lenp += len;
return len;
}
int main() {
const char *mytitle = "Webpage title";
const char *mydesc = "This is a page version";
int myver = 2;
char *buf_ptr = NULL;
size_t buf_len = 0;
//print HTTP header of known data
printf("HTTP/1.1 200 OK\r\n");
printf("Server: Something\r\n");
printf("Content-type: text/html; charset=UTF-8\r\n");
printf("Cache-control: no-cache\r\n");
//Buffer HTML output to get size (we don't print these 4 lines yet)
mem_printf(&buf_ptr, &buf_len,
"<html><head><title>%s</title></head><body>\r\n"
"<h1>%s</h1>\r\n"
"<p>%s %d</p>\r\n"
"</body></html>\r\n",
mytitle, mytitle, mydesc, myver);
//Print content length header with size of buffered data
printf("Content-length: %zu\r\n", buf_len);
printf("\r\n");
//then print the rest of the data
fputs(buf_ptr, stdout);
free(buf_ptr);
return 0;
}
Content-Length, as you probably know, is the size of your body. This means you have to know at least the length of the body before you can generate the header (or use chunked transfer). sprintf returns the number of bytes written, either accumulate those, or squash it into a single call:
int n = snprintf(mybuf,
mybuf_len,
"<html><head><title>%s</title></head><body>\r\n"
...
"</body></html>\r\n",
mytitle, ..., myver
);
Then generate the header(n) with the n you figured out. If you pass in NULL for instead of mybuf, you get a size without writing anything, then you could do another write a pass in header with the count you got from the first call. If you want, wrap this in a function or two:
int response(const char *header, int body_len, const char body[body_len]) {
...
}
Consider picking a template library (I like the mustache format). It's kinda messy and error prune doing this by hand with raw strings. You have a 1 MB buffer allocated there but use like a .5k, and you will shoot yourself in the foot one day anyhow.
When reading a JSON string from the serial port on an ESP8266 it cuts off the beginning of the data.
I have tried reading data from the Serial port and printing each character, however it is cutting off part of the begging of the data.
void setup() {
Serial.begin(115200);
while (!Serial) {
;
}
}
void loop() {
int curSize = 30;
char* buffer = new char[curSize];
std::fill_n(buffer, curSize, 0);
int pos = 0;
Serial.print("Sending: ");
while(Serial.available() == false) delay(500);
while (Serial.available()) {
char c = Serial.read();
Serial.print(c);
if(pos == curSize-1){
char* newBuffer = increaseBuffer(buffer, curSize, curSize + 30);
curSize += 30;
delete[] buffer;
buffer = newBuffer;
}
if(c == '\n'){
buffer[pos] = 0;
pos = 0;
break;
}
buffer[pos++] = c;
}
if(buffer[0] != 0) {
sendBuffer(buffer);
}
delete[] buffer;
}
char* increaseBuffer(char* orig, int oldSize, int newSize){
char* data = new char[newSize];
std::fill_n(data, newSize, 0);
for(int i = 0; i < newSize; i++){
if(i < oldSize) data[i] = orig[i];
else data[i] = '\0';
}
return data;
}
JSON data used (and expected output)
{"type":0,"ver":"0.0.1","T":[28,29,29,29,29,29,29,29,29,29],"H":[59.1608,59.1608,60,59.1608,60,60,60,59.1608,59.1608,59.1608],"DP":[20.36254,20.36254,20.59363,20.36254,20.59363,20.59363,20.59363,20.36254,20.36254],"HI":[30.90588,30.90588,31.0335,30.90588,31.0335,31.0335,31.0335,30.90588,30.90588]}
examples of what is actually output
Example 1: 9,29,29,29,29,29,29,29,29],"H":[59.1608,59.1608,60,59.1608,60,60,60,59.1608,59.1608,59.1608],"DP":[20.36254,20.36254,20.59363,20.36254,20.59363,20.59363,20.59363,20.36254,20.36254],"HI":[30.90588,30.90588,31.0335,30.90588,31.0335,31.0335,31.0335,30.90588,30.90588]}
Example 2: 29,29,29,29,29,29,29,29,29],"H":[59.1608,59.1608,60,59.1608,60,60,60,59.1608,59.1608,59.1608],"DP":[20.36254,20.36254,20.59363,20.36254,20.59363,20.59363,20.59363,20.36254,20.36254],"HI":[30.90588,30.90588,31.0335,30.90588,31.0335,31.0335,31.0335,30.90588,30.90588]}
Try making the delay 1 instead of 500 in the blocking loop that's waiting for data to start coming in. I'm going to guess what happens is that on one iteration of that loop Serial.available() is false and during the delay you start to get data coming in that ends up getting written over by the time your delay ends to check again.
What I'm picturing is the following. If you were to expand out that delay(500) to be delay(1) called 500 times.
while(Serial.available() == false){
delay(1);
delay(1);
// ...
delay(1); // first character comes in
delay(1);
delay(1); // second character comes in
// ...
delay(1); // n character comes in
}
Then after the delay is over you start actually collecting the characters that are coming in.
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
}
}
}
I am trying get an external interrupt and blink an LED, but I get an error like:
pragma vector = accepts numeric arguments or "unused_interrupts" but not PORT_VECTOR
The code is as follows:
int main(){
// Stop Watch Dog Timer
WDTCTL = WDTPW + WDTHOLD;
P1DIR &= ~BIT4; //configure as an input
P1OUT |= BIT4;
P3DIR |= BIT4;
P3OUT |= BIT4;
P1IES = 0x01;
P1IE = 0x01; //1b = Corresponding port interrupt enabled
P1IFG = 0x01; //PxIFG flag is set with a high-to-low transition
P1REN = 0x01; //Pullup or pulldown enabled
}
#pragma vector = PORT_VECTOR
__interrupt void Port_1 (void){
if( (P1IN & BIT4)==0 ){
// read input as GND
P3OUT |= BIT4;
}
else if( (P1IN & BIT4)==1 ){
P3OUT &= ~BIT4;
}
}