I'm trying to read the on board temp sensor of the msp430fr5739 micro controller and display the results in a terminal.
using C the task should be accomplished!!!
All the code and custom libraries can be found on GitHub
My operating system is ubuntu and the IDE I'm using is code composer studio
here is the main.c
#include <msp430fr5739.h>
#include "system.h"
#include "temp.h"
#include "uart.h"
/*
main.c
1. Switches and LEDs
2.
3. Temp sens
*/
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
unsigned int tempVal = 0; // temp readings
LEDs_INIT(); // Init leds
SWITCHEs_INIT(); // Init Switches
serialBegin(); // Begin Serial communication at 9600 buad
while (1)
{
__bis_SR_register(LPM4_bits + GIE); // Enter LPM4 with interrupts enabled
tempVal = getThermisterVal();
}
return 0;
}
I've tried to follow the demo code that TI had shipped with the board and the resulting libs are published on GitHub (I didn't post all the lib and code, simply because it's too long)
Now I'm really struggling with the serial communication part, i know that the bytes sent from the micro-controller has to be read by some sort of serial monitor application on PC.
Any help is appreciated.
Related
I am doing a major embedded project of making a GM counter. As a main microcontroller I am using a PIC32MK1024MCM064. I wont bore you with details, but I need to implement following algorithm:
When MCU turns on, 13 seconds delay has to pass
MCU waits for a button press, which triggers an interrupt
Button interrupt starts 60 seconds timer
During that 60 seconds, MCU input pin counts the impulses (Idle voltage state is high (3.3V) and low voltage state counts as an impulse (50-130 us duration))
After the timer has expired, MCU outputs the impulse number via 16x2 LCD screen
Project has many files included in it, but I have already verified all the peripheral code is written right:
I have already made sure, that my button interrupt and the timer interrupt work absolutely fine (used the oscilloscope, real timer and all the other stuff.)
I also verified that my I2C driver for the LCD screen works great as well.
I made sure I am indeed getting the low state impulses as defined (50-130 us duration.)
#include <xc.h>
#include "configurations_bits.h"
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "stdio.h"
#include <sys/attribs.h>
#include "delay.h"
#include "inter_integrated_circuit_protocol.h"
#include "liquid_crystal_display.h"
#include "pulse_width_modulation.h"
#include "timer.h"
#include "state_change_interrupts.h"
static int Particle_count = 0; //Variable for counting events
char Value[10]={0}; //Particle value string
int main(void) {
__builtin_disable_interrupts(); //Global interrupt disable
ANSELA = 0x00000000; //Enable PORT A digital inputs
ANSELG = 0x00000000; //Enable PORT G digital inputs
TRISEbits.TRISE12 = 0; //Output gpio of a led
TRISDbits.TRISD8 = 0; //Output gpio of a led
TRISGbits.TRISG9 = 0; //Output GPIO of GM ENABLE
LATGbits.LATG9 = 1; //Enable GM right away
TRISAbits.TRISA1 = 1; //Input for counting particles
TRISCbits.TRISC7 = 1; //Input for control button
Inter_Integrated_Circuit_Setup (); //I2C configuration
Inter_Integrated_Circuit_Enable (); //I2C enable
Liquid_Crystal_Display_initialization(); //LCD configuration
Liquid_Crystal_Display_Set_Cursor(1, 1);
Liquid_Crystal_Display_Write_String("Preparing for");
Liquid_Crystal_Display_Set_Cursor(2, 1);
Liquid_Crystal_Display_Write_String("Measurement");
Pulse_Width_Modulation_Setup(); //PWM setup
Pulse_Width_Modulation_Enable(); //Turn on high voltage generation
for(int i=0; i<13; i++){
delay_ms(1000);} //Waiting until the high voltage rail rises up to 400V (starting GM tube voltage)
Liquid_Crystal_Display_Clear(); //Clearing LCD
Liquid_Crystal_Display_Set_Cursor(1, 1);
Liquid_Crystal_Display_Write_String("Ready for");
Liquid_Crystal_Display_Set_Cursor(2, 1);
Liquid_Crystal_Display_Write_String("Measurement");
State_Change_Interrupts_Setup (); //Button interrupt setup
Timer2_Setup (); //Timer interrupt setup
__builtin_enable_interrupts(); //Global interrupt enable
while (1){
if(T2CONbits.ON){ //Condition, that the timer is on
Liquid_Crystal_Display_Clear(); //Clearing LCD
Liquid_Crystal_Display_Set_Cursor(1, 1);
Liquid_Crystal_Display_Write_String(" Measurement Is ");
Liquid_Crystal_Display_Set_Cursor(2, 1);
Liquid_Crystal_Display_Write_String(" In Progress ");
while(T2CONbits.ON){ //Execute this while cycle until the timer shuts off
if(PORTAbits.RA1==0){
Particle_count = Particle_count+1;
delay_us(100);} //GM tube dead time compensation
}
Liquid_Crystal_Display_Clear(); //Clearing LCD
sprintf(Value,"%05d CPM",Particle_count);
Particle_count=0; //Resetting the CPM value
Liquid_Crystal_Display_Set_Cursor(1, 1);
Liquid_Crystal_Display_Write_String(Value);//Printing radiation level in CPM notation
delay_ms(5000);
Liquid_Crystal_Display_Clear(); //Clearing LCD
}
}
return (EXIT_FAILURE);
}
When I press the button, my LCD outputs "Measurement Is In Progress" for a fraction of a second, then it immediately outputs "00000 CPM" which means it had counted zero impulses (In my application, I know for sure that I must capture at least 5 impulses per minute.) Looks like the while cycle has only one or few iterations (it should last for a minute). So my code problem is not a missing semicolon somewhere, but I feel like the whole architecture is not right. Have you got any observations or suggestions, how could I implement the mentioned algorithm? Want to thank you in advance.
(P.S I am running a 8 MHz internal FRC as the main clock)
I have an Adafruit Sharp Memory display connected via SPI to Arduino Nano Connect RP2040. I don't use Arduino IDE nor libraries. I write the code in C++ like I would write for RP2040 on Pi Pico, so I'm using Pico/RP2040 libraries. I'm building it and then just copying the .uf2 file to Arduino.
I'm trying to control the display but without success and I have no idea what I'm doing wrong. Here is my code, where I'm sending a command which should clear the display but it does not:
#include <stdio.h>
#include <stdlib.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"
#include "hardware/gpio.h"
// ---SPI
// Pins for Arduino
#define SCK_PIN 13 // SCLK / SCK
#define MOSI_PIN 11 // MOSI / COPI
#define SS_PIN 10 // SS / CS
// ---Sharp display
#define WIDTH 144
#define HEIGHT 168
int main() {
stdio_init_all();
printf("START \n");
bool vcom_bool_{false};
spi_init(spi0, 2000000);
spi_set_format( spi0, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
gpio_set_function(MOSI_PIN, GPIO_FUNC_SPI);
gpio_set_function(SCK_PIN, GPIO_FUNC_SPI);
gpio_init(SS_PIN);
gpio_set_dir(SS_PIN, GPIO_OUT);
gpio_put(SS_PIN, 0); // this display is low on inactive
while(true)
{
printf("VCOM = %b \n", vcom_bool_);
gpio_put(SS_PIN, 1);
// Clear the display
uint8_t buf[2];
if(vcom_bool_)
{
buf[0] = 0b01100000;
vcom_bool_ = false;
}
else
{
buf[0] = 0b00100000;
vcom_bool_ = true;
}
buf[1] = 0b00000000;
spi_write_blocking(spi0, buf, 2);
gpio_put(SS_PIN, 0);
sleep_ms(10);
sleep_ms(500);
}
}
Display and wiring are ok, because when I run example code from Adafruit (it is using Arduino's libraries) it works.
I follow this documentation from Sharp: https://www.sharpsde.com/fileadmin/products/Displays/2016_SDE_App_Note_for_Memory_LCD_programming_V1.3.pdf
I also reviewed the code from Adafruit and the SPI communication seems to be done in the same way.
What am I doing wrong?
Is there some issue with using Pico libraries for Arduino Nano RP2040? I did I2C communication in the same way (Pico/RP2040 libraries, .uf2 copied to Arduino Nano RP2040) and it worked.
I'm pretty new to programming in C, but getting used to registers and the way communication in C works. Since UART using the official Arduino read() / write() creates a high delay in passing commands through, I tried to translate this Arduino sketch into pure C. (and because I've time to play around, haha)
My ebike's controller and display are communicating using UART. I tried to read the commands and react to speed changes or brake signals, but first of all I need to get rid of this huge delay in updating the display.
I'm using an Robodyn Mega 2560 PRO (Embed), which has 4x hardware serial ports. In the first step I tried to read what's coming in and forward it to the other port. Shouldn't be to hard to implement in C, right?
void setup() {
Serial1.begin(1200); // BBSHD controller #RX18 TX19
Serial2.begin(1200); // Display DP-C18 #TX16 RX17
}
void loop() {
if (Serial2.available()) {
Serial1.write(Serial2.read());
}
if (Serial1.available()) {
Serial2.write(Serial1.read());
}
}
That's what I programmed in Atmel Studio 7 so far. I used the C example from ATmega640/1280/1281/2560/2561 - Complete Datasheet (Search for USART_Receive and USART_Transmit) and this guide Simple Serial Communications With AVR libc
Currently I can compile and flash it the 2560, but the communication is not being forwarded. I don't know what the default settings are, that Arduino with Serial uses. Which mode, number of stop bits, .. Is there anything obvious I'm missing?
#define F_CPU 16000000UL
#define BAUD 1200
#include <avr/io.h>
#include <stdio.h>
#include <util/setbaud.h>
void uart_init(void) {
/* Serial1 controller */
UBRR1H = UBRRH_VALUE;
UBRR1L = UBRRL_VALUE;
/* Serial2 display */
UBRR2H = UBRRH_VALUE;
UBRR2L = UBRRL_VALUE;
/* 8-bit data, 1stop bit*/
UCSR1C = (1<<UCSZ11) | (1<<UCSZ10);
UCSR2C = (1<<UCSZ21) | (1<<UCSZ20);
/* Enable RX and TX */
UCSR1B = (1<<RXEN1) | (1<<TXEN1);
UCSR2B = (1<<RXEN2) | (1<<TXEN2);
}
int main(void) {
uart_init();
while(1) {
if (!(UCSR1A & (1<<RXC1))) { /* Only if data is received */
while (!(UCSR1A & (1<<UDRE1))); /* Wait for empty transmit buffer */
UDR2 = UDR1; /* Put data into buffer, sends the data */
}
if (!(UCSR2A & (1<<RXC2))) { /* Only if data is received */
while (!(UCSR2A & (1<<UDRE2))); /* Wait for empty transmit buffer */
UDR1 = UDR2; /* Put data into buffer, sends the data */
}
}
}
I have ATTiny with 1MHz clock. I'm trying to light up some ws2812b led strip. I conected everything without any resistors and capacitors. I think everything should works but it doesn't :)
I'm useing light_ws2812 library https://github.com/cpldcpu/light_ws2812.
Below is example code. I have hanged only F_CPU frequency, numper of output pin and reset time in config file. Could You help me find the problem and advice how can I fix it?
MAIN
#define F_CPU 1000000
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "ws2812_config.h"
#include "light_ws2812.h"
struct cRGB led[2];
int main(void)
{
uint8_t pos=0;
uint8_t direction=1;
uint8_t i;
#ifdef __AVR_ATtiny10__
CCP=0xD8; // configuration change protection, write signature
CLKPSR=0; // set cpu clock prescaler =1 (8Mhz) (attiny 4/5/9/10)
#endif
led[0].r=255;led[0].g=00;led[0].b=00; // LED 0 is red
led[1].r=255;led[1].g=16;led[1].b=16; // LED 1 is White
while(1)
{
for (i=0; i<pos; i++)
ws2812_sendarray((uint8_t *)&led[0],3); // Repeatedly send "red" to the led string.
// No more than 1-2µs should pass between calls
// to avoid issuing a reset condition.
for (i=0; i<(16-pos); i++)
ws2812_sendarray((uint8_t *)&led[1],3); // white
_delay_ms(50); // Issue reset and wait for 50 ms.
pos+=direction;
if ((pos==16)||(pos==0)) direction=-direction;
}
}
CONFIG
/*
* light_ws2812_config.h
*
* v2.4 - Nov 27, 2016
*
* User Configuration file for the light_ws2812_lib
*
*/
#ifndef WS2812_CONFIG_H_
#define WS2812_CONFIG_H_
///////////////////////////////////////////////////////////////////////
// Define Reset time in µs.
//
// This is the time the library spends waiting after writing the data.
//
// WS2813 needs 300 µs reset time
// WS2812 and clones only need 50 µs
//
///////////////////////////////////////////////////////////////////////
#define ws2812_resettime 50
///////////////////////////////////////////////////////////////////////
// Define I/O pin
///////////////////////////////////////////////////////////////////////
#define ws2812_port B // Data port
#define ws2812_pin 3 // Data out pin
#endif /* WS2812_CONFIG_H_ */
I think 1Mhz is just too slow to be able to generate the signals required by the WS2812B.
The most timing critical WS2812B signal - the TH0 pulse - must be less than 500ns wide, and at 1Mhz, each MCU cycle is 1000ns.
More info on the the WS2812B timing constraints here...
https://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/
Series resistors and parallel capacitors do help decrease noise that causes inexplicable behavior. But you're right, it should not stop the WS2812bs from working completely.
I suggest you try another pin on your attiny. Pin 3 is used for usb communication. If you are powering your attiny through a usb cable connected to your computer this will cause trouble. Try pins 5 and 6 for example.
You can try the Adafruit_NeoPixel library. I tried and it compiled for attiny85 without modification. I did not actually try to run it since I do not have an attiny lying around.
Also, some of the cheaper WS2812b ledstrips that are around on ebay got their Din and Dout labels switched. This means you have to connect the Dout pin to your attiny. This has actually happened to me once.
I don't know about pulse lenghts in WS2812bs but if that is not the issue I'm pretty sure it's one of the three I mentioned above.
Hope that helps.
[Solution]
According to README I've included config file before header in my MAIN source code file. It was a mistake because the two files are part of different compilation units and DEFINEs are not shared between them. It causes that my configuration settings was ignored and program used default (not correct in my case) ones.
To fix this bug You should include Your ws2812_config.h within light_ws2812.h
You should use the library FASTLED,you can download it on arduino ide .It's very easy to light WS2812 with ATTINY85 by using this library.
I'm currently trying to interface my Tiva C Series with a Sparkfun Breakout Board, IMU Digital Combo Board - 6 Degrees of Freedom ITG3200/ADXL345 and I'm having trouble with the I2C interface.
currently this is my code:
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"
uint8_t SLAVE_ADDRESS = 0x68;
uint32_t first_byte, second_byte, temperature, result;
void i2c_setup(void) {
//Enable the I2C Module
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
//Wait at least 5 clock cycles
SysCtlDelay(2);
//Configure SDA and SCL
GPIOPinConfigure(GPIO_PE4_I2C2SCL);
GPIOPinConfigure(GPIO_PE5_I2C2SDA);
//Wait at least 5 clock cycles
SysCtlDelay(2);
//Set PE4 as SCL
GPIOPinTypeI2CSCL(GPIO_PORTE_BASE, GPIO_PIN_4);
//Set PE5 as SDA
GPIOPinTypeI2C(GPIO_PORTE_BASE, GPIO_PIN_5);
//Configure Master,
I2CMasterInitExpClk(I2C2_BASE, SysCtlClockGet(), false);
}
uint32_t i2c_read() {
I2CMasterSlaveAddrSet(I2C2_BASE, SLAVE_ADDRESS, false);
I2CMasterDataPut(I2C2_BASE, 0x1A);
I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_SINGLE_SEND);
while(I2CMasterBusBusy(I2C2_BASE)); //Loop until the bus is no longer busy
I2CMasterSlaveAddrSet(I2C2_BASE, SLAVE_ADDRESS, true );
I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
while(I2CMasterBusBusy(I2C2_BASE)); //Loop until the bus is no longer busy
first_byte = I2CMasterDataGet(I2C2_BASE);
return first_byte;
}
void setup()
{
Serial.begin(9600);
i2c_setup();
}
void loop()
{
int test = i2c_read();
Serial.println(test);
delay(1000);
}
I'm using Energia to test my program, and when I try to read from the specified register, I get the same result, no matter which register I choose, the result is always decimal 229 (this is the Accelerometer's Device Address).
Can somebody point me in the right direction, I've been looking at my code for quite some time and still don't know whats wrong...
Thanks!
I skimmed through your code and everything seems Okay. Clearly something is working right if you get a response. But Like Martin said , figuring the problem without being there is somewhat difficult. Instead of Writing 0x1A can you try using one of the other I2C commands for the accelerametor ? Also if the jumper is connected to VDD your address should be 0x69 (105 decimal) are you sure it's 0x68 ?
I looked up the documentation on sparkfuns website and they provided the following list
of commands.
char WHO_AM_I = 0x00;
char SMPLRT_DIV= 0x15;
char DLPF_FS = 0x16;
char GYRO_XOUT_H = 0x1D;
char GYRO_XOUT_L = 0x1E;
char GYRO_YOUT_H = 0x1F;
char GYRO_YOUT_L = 0x20;
char GYRO_ZOUT_H = 0x21;
char GYRO_ZOUT_L = 0x22;
GL hope everything works out. Been meaning to buy my own to play around with so keep me posted !