<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Simple sample for measuring coin cell battery voltage with Zephyr and nRF52840</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/97489/simple-sample-for-measuring-coin-cell-battery-voltage-with-zephyr-and-nrf52840</link><description>My project uses Zephyr and the nRF52840 with a CR2450 coin cell battery. All is working well, and now I am looking to add in battery level. I&amp;#39;ve downloaded and read the following samples. 
 zephyr/samples/boards/nrf/battery zephyr/samples/drivers/adc</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 22 Mar 2023 21:58:04 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/97489/simple-sample-for-measuring-coin-cell-battery-voltage-with-zephyr-and-nrf52840" /><item><title>RE: Simple sample for measuring coin cell battery voltage with Zephyr and nRF52840</title><link>https://devzone.nordicsemi.com/thread/416935?ContentTypeID=1</link><pubDate>Wed, 22 Mar 2023 21:58:04 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:724cc9fc-abe0-4340-b221-0fe1c9f50e71</guid><dc:creator>Hieu</dc:creator><description>&lt;p&gt;Hi Steve,&lt;/p&gt;
&lt;p&gt;It&amp;#39;s good to know that you have got it to work. Thank you for sharing your working&amp;nbsp;code with the community. We appreciate it.&lt;/p&gt;
&lt;p&gt;It is curious how sample.yaml&amp;nbsp; comes into play. I&amp;nbsp;will try to look into this some time.&lt;/p&gt;
&lt;p&gt;Besides the original question, I don&amp;#39;t think I have helped with your build issue at all. Thank you for the kind words.&lt;/p&gt;
&lt;p&gt;Happy developing!&lt;/p&gt;
&lt;p&gt;Hieu&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simple sample for measuring coin cell battery voltage with Zephyr and nRF52840</title><link>https://devzone.nordicsemi.com/thread/416931?ContentTypeID=1</link><pubDate>Wed, 22 Mar 2023 21:44:36 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c98f2df4-0bcd-41ad-bd37-fa16be20073e</guid><dc:creator>abvio</dc:creator><description>&lt;p&gt;Hi Hieu,&lt;/p&gt;
&lt;p&gt;Thank you for your follow up. &amp;nbsp;I&amp;#39;m happy to report I have it completely solved and am reading the internal VDD using the ADC. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;It still wasn&amp;#39;t clear why my code wasn&amp;#39;t compiling, but after iterating on a lot of possibilities, I did change the sample.yaml in my project to match the sample.yaml in the ADC example, which mentioned &amp;quot;adc&amp;quot;. After that and a few more iterations, the code started to compile. And after some further debugging, it started to work.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In case someone is looking for some simpler sample code, I reduced the devicetree to just one channel that looks like this:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;/ {
	zephyr,user {
		io-channels = &amp;lt;&amp;amp;adc 0&amp;gt;;
	};
};

&amp;amp;adc {
	#address-cells = &amp;lt;1&amp;gt;;
	#size-cells = &amp;lt;0&amp;gt;;
	status=&amp;quot;okay&amp;quot;;

	channel@0 {
		reg = &amp;lt;0&amp;gt;;
		zephyr,gain = &amp;quot;ADC_GAIN_1_6&amp;quot;;
		zephyr,reference = &amp;quot;ADC_REF_INTERNAL&amp;quot;;
		zephyr,acquisition-time = &amp;lt;ADC_ACQ_TIME_DEFAULT&amp;gt;;
		zephyr,input-positive = &amp;lt;NRF_SAADC_VDD&amp;gt;;
		zephyr,resolution = &amp;lt;14&amp;gt;;
		zephyr,oversampling = &amp;lt;8&amp;gt;;
	};
};
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The code I use to access it looks like this:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
	!DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
#error &amp;quot;No suitable devicetree overlay specified&amp;quot;
#endif

#define DT_SPEC_AND_COMMA(node_id, prop, idx) \
	ADC_DT_SPEC_GET_BY_IDX(node_id, idx),

/* Data of ADC io-channels specified in devicetree. */
static const struct adc_dt_spec adc_channels[] = {
	DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels,
			     DT_SPEC_AND_COMMA)
};

K_MSGQ_DEFINE(battery_msgq, sizeof(battery_event_t), 10, 4);

int32_t battery_level(void) {
	int err;
	int32_t val_mv;
	int16_t buf = 0;
	uint8_t level = 0; 

	struct adc_sequence sequence = {
		.buffer = &amp;amp;buf,
		/* buffer size in bytes, not number of samples */
		.buffer_size = sizeof(buf),
	};

	if (!device_is_ready(adc_channels[0].dev)) {
		printk(&amp;quot;ADC controller device not ready\n&amp;quot;);
		return level;
	}
	err = adc_channel_setup_dt(&amp;amp;adc_channels[0]);
	if (err &amp;lt; 0) {
		printk(&amp;quot;Could not setup channel #%d (%d)\n&amp;quot;, 0, err);
		return level;
	}
	(void)adc_sequence_init_dt(&amp;amp;adc_channels[0], &amp;amp;sequence);

	err = adc_read(adc_channels[0].dev, &amp;amp;sequence);
	if (err &amp;lt; 0) {
		printk(&amp;quot;Could not read (%d)\n&amp;quot;, err);
		return level; 
	}

	val_mv = buf;
	err = adc_raw_to_millivolts_dt(&amp;amp;adc_channels[0], &amp;amp;val_mv);
	if (err &amp;lt; 0) {
		printk(&amp;quot; (value in mV not available)\n&amp;quot;);
		return level; 
	}

// Voltage to level curve for a coin cell 3V battery. 
#define BATTERY_FULL_MV 2950
#define BATTERY_HALF_MV 2900
#define BATTERY_QUARTER_MV 2800
#define BATTERY_DEAD_MV 2300

	if (val_mv &amp;gt;= BATTERY_FULL_MV) {
		level = 100; 
	} else if (val_mv &amp;lt;= BATTERY_DEAD_MV) {
		level = 0; 
	} else if (val_mv &amp;gt;= BATTERY_HALF_MV) {
		level = (val_mv - BATTERY_HALF_MV) * 50 / (BATTERY_FULL_MV - BATTERY_HALF_MV) + 50;
	} else if (val_mv &amp;gt;= BATTERY_QUARTER_MV) {
		level = (val_mv - BATTERY_QUARTER_MV) * 25 / (BATTERY_HALF_MV - BATTERY_QUARTER_MV) + 25;
	} else {
		level = (val_mv - BATTERY_DEAD_MV) * 25 / (BATTERY_QUARTER_MV - BATTERY_DEAD_MV) + 0;
	}

	return level; 
	// return val_mv / 100; 
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Thanks again for your help,&lt;/p&gt;
&lt;p&gt;Steve&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simple sample for measuring coin cell battery voltage with Zephyr and nRF52840</title><link>https://devzone.nordicsemi.com/thread/416919?ContentTypeID=1</link><pubDate>Wed, 22 Mar 2023 20:32:42 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9ce2a37e-3a82-4285-90d5-7b00819e03ba</guid><dc:creator>Hieu</dc:creator><description>&lt;p&gt;Hi Steve,&lt;/p&gt;
&lt;p&gt;Have you&amp;nbsp;found out where the problem is?&amp;nbsp;I am still&amp;nbsp;slowly getting through my backlog.&amp;nbsp;If you still need help, I should be able to get to this tomorrow.&lt;/p&gt;
&lt;p&gt;Hieu&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simple sample for measuring coin cell battery voltage with Zephyr and nRF52840</title><link>https://devzone.nordicsemi.com/thread/416126?ContentTypeID=1</link><pubDate>Fri, 17 Mar 2023 22:38:16 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1d1c6e97-ffb9-400f-9495-6e120edf143c</guid><dc:creator>Hieu</dc:creator><description>&lt;p&gt;Hi Steve,&lt;/p&gt;
[quote user="abvio"]Maybe something to do with DT_DRV_COMPAT?&amp;nbsp;[/quote]
&lt;p&gt;It seems so. DT_DRV_COMPAT is supposed to be&amp;nbsp;a defined macro. However, in your case, it is expended into literal DT_DRV_COMPAT, so&amp;nbsp;it looks like the driver was not loaded correctly.&lt;/p&gt;
&lt;p&gt;See:&amp;nbsp;&lt;a href="https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.3.0/zephyr/build/dts/howtos.html#option-1-create-devices-using-instance-numbers"&gt;https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.3.0/zephyr/build/dts/howtos.html#option-1-create-devices-using-instance-numbers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hieu&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simple sample for measuring coin cell battery voltage with Zephyr and nRF52840</title><link>https://devzone.nordicsemi.com/thread/415795?ContentTypeID=1</link><pubDate>Thu, 16 Mar 2023 16:22:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4b62a19c-58ff-485f-af5c-4ce74c984ece</guid><dc:creator>abvio</dc:creator><description>&lt;p&gt;Hi Hieu,&lt;/p&gt;
&lt;p&gt;Thanks for letting me know you&amp;#39;re busy.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In the meantime, if you have any canned advice on debugging devicetree compile errors, that would be helpful. The crucial issue is why is the following not defined using&amp;nbsp;my device tree, which copies the sample program. &amp;nbsp;Maybe something to do with DT_DRV_COMPAT?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;__device_dts_ord_DT_N_INST_DT_N_S_zephyr_user_DT_DRV_COMPAT_P_io_channels_IDX_0_PH_ORD&lt;/p&gt;
&lt;p&gt;Thanks again for your help,&lt;/p&gt;
&lt;p&gt;Steve&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simple sample for measuring coin cell battery voltage with Zephyr and nRF52840</title><link>https://devzone.nordicsemi.com/thread/415735?ContentTypeID=1</link><pubDate>Thu, 16 Mar 2023 13:48:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:086bf520-48d5-4d2b-94aa-262fe3e6ff07</guid><dc:creator>Hieu</dc:creator><description>&lt;p&gt;Hi Steve,&lt;/p&gt;
&lt;p&gt;I am a bit tied up&amp;nbsp;for the rest of the week. I will try to start looking into this around Monday and Tuesday and get back to you.&lt;/p&gt;
&lt;p&gt;If that&amp;#39;s not OK please let me know.&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Hieu&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simple sample for measuring coin cell battery voltage with Zephyr and nRF52840</title><link>https://devzone.nordicsemi.com/thread/415588?ContentTypeID=1</link><pubDate>Thu, 16 Mar 2023 04:49:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0166f918-c803-4501-bc0c-f592da6fb185</guid><dc:creator>abvio</dc:creator><description>&lt;p&gt;Thanks Hieu,&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve decided to use the &amp;quot;ADC&amp;quot; sample. I&amp;#39;ve been able to compile it and have it work on my board, showing the 2970 millivolts of the battery using channel 1, which seems to be the internal measure. So now I just need to integrated it into my project. My app currently successfully uses GPIO, SPI and Bluetooth, as well as does DFU, and I would think something like ADC would be simple. &lt;/p&gt;
&lt;p&gt;Here&amp;#39;s a snippet of the code I&amp;#39;ve added.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
    !DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
#error &amp;quot;No suitable device tree overlay specified&amp;quot;
#endif

#define DT_SPEC_AND_COMMA(node_id, prop, idx) \
    ADC_DT_SPEC_INST_GET_BY_IDX(node_id, idx),

static const struct adc_dt_spec adc_channels[] = {
	DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels,
			     DT_SPEC_AND_COMMA)
};&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#39;m integrating the code in pieces. I added the following to my device tree.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;/ {
	zephyr,user {
		io-channels = &amp;lt;&amp;amp;adc 1&amp;gt;;
	};
};

&amp;amp;adc {
	#address-cells = &amp;lt;1&amp;gt;;
	#size-cells = &amp;lt;0&amp;gt;;
	status = &amp;quot;okay&amp;quot;;

	channel@1 {
		reg = &amp;lt;1&amp;gt;;
		zephyr,gain = &amp;quot;ADC_GAIN_1_6&amp;quot;;
		zephyr,reference = &amp;quot;ADC_REF_INTERNAL&amp;quot;;
		zephyr,acquisition-time = &amp;lt;ADC_ACQ_TIME_DEFAULT&amp;gt;;
		zephyr,input-positive = &amp;lt;NRF_SAADC_VDD&amp;gt;;
		zephyr,resolution = &amp;lt;14&amp;gt;;
		zephyr,oversampling = &amp;lt;8&amp;gt;;
	};
};&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve added CONFIG_ADC=y to the prj.conf.&lt;/p&gt;
&lt;p&gt;However, I spent today trying to get it to compile without success. Here is the beginning of a long list of errors. &amp;nbsp;Something seems to be wrong with my device tree. In particular, the errors are triggered by the&amp;nbsp;DT_FOREACH_PROP_ELEM macro.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;In file included from C:\Users\steve\ncs\v2.2.0\zephyr\include\zephyr\toolchain\gcc.h:88,
                 from C:\Users\steve\ncs\v2.2.0\zephyr\include\zephyr\toolchain.h:50,
                 from C:\Users\steve\ncs\v2.2.0\zephyr\include\zephyr\kernel_includes.h:19,
                 from C:\Users\steve\ncs\v2.2.0\zephyr\include\zephyr\kernel.h:17,
                 from c:\Users\steve\Documents\Projects\display-firmware\src\battery.h:5,
                 from c:\Users\steve\Documents\Projects\display-firmware\src\battery.c:5:
C:\Users\steve\ncs\v2.2.0\zephyr\include\zephyr\device.h:83:41: error: &amp;#39;__device_dts_ord_DT_N_INST_DT_N_S_zephyr_user_DT_DRV_COMPAT_P_io_channels_IDX_0_PH_ORD&amp;#39; undeclared here (not in a function)
   83 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
      |                                         ^~~~~~~~~
C:\Users\steve\ncs\v2.2.0\zephyr\include\zephyr\toolchain\common.h:132:26: note: in definition of macro &amp;#39;_DO_CONCAT&amp;#39;
  132 | #define _DO_CONCAT(x, y) x ## y
      |                          ^
C:\Users\steve\ncs\v2.2.0\zephyr\include\zephyr\device.h:83:33: note: in expansion of macro &amp;#39;_CONCAT&amp;#39;
   83 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Devicetree macro debugging seems quite challenging. Any thoughts at what steps I should take to solve this?&lt;/p&gt;
&lt;p&gt;Best,&lt;/p&gt;
&lt;p&gt;Steve&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simple sample for measuring coin cell battery voltage with Zephyr and nRF52840</title><link>https://devzone.nordicsemi.com/thread/414742?ContentTypeID=1</link><pubDate>Fri, 10 Mar 2023 23:18:41 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:172b1529-5f04-4f74-9bd7-0d4efc3c8dcc</guid><dc:creator>Hieu</dc:creator><description>&lt;p&gt;Hi Steve,&lt;/p&gt;
[quote user=""]- From parts of the samples, I&amp;#39;m guessing that the nRF52840 has an internal way to measure VDD. (See &amp;quot;zephyr,input-positive = &amp;lt;NRF_SAADC_VDD&amp;gt;;&amp;quot; in the nRF52840DK devicetree overlay in the &amp;quot;add&amp;quot; sample.) Is this true? If so, how do I access it?[/quote]
&lt;p&gt;Yes. You can find out the details in &lt;a href="https://infocenter.nordicsemi.com/topic/ps_nrf52840/saadc.html?cp=5_0_0_5_22"&gt;the SAADC section&lt;/a&gt;&amp;nbsp;of &lt;a href="https://infocenter.nordicsemi.com/topic/ps_nrf52840/keyfeatures_html5.html?cp=5_0_0"&gt;the nRF52840 Product Specification&lt;/a&gt;.&lt;br /&gt;In particular,&amp;nbsp;&lt;a href="https://infocenter.nordicsemi.com/topic/ps_nrf52840/saadc.html?cp=5_0_0_5_22_0#concept_using"&gt;the first subsection, Input Configuration&lt;/a&gt;,&amp;nbsp;is what you are looking for.&lt;/p&gt;
&lt;p&gt;(But since you are going to work with ADC, I recommend readding the entire SAADC section to have a full understanding of how it works anyhow).&lt;/p&gt;
[quote user=""]- If the above is not true, could my connection between P0.02/AIN0 and the coin cell be used to measure its voltage?[/quote]
&lt;p&gt;Using AIN0 also works, and the same documentations I recommended above would explain it.&lt;/p&gt;
&lt;p&gt;This&amp;nbsp;option must be used if you have a regulator between your coin cell and the SoC. In such a setup, VDD is not the coin cell voltage.&lt;/p&gt;
[quote user=""]- Is there a sample, or some guidance within an existing sample, that you can give me to make this clearer?[/quote]
&lt;p&gt;The samples you found are exactly the samples for this topic.&lt;/p&gt;
&lt;p&gt;I looked into them and agree that more than a few parts of them don&amp;#39;t&amp;nbsp;look very easy to understand.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Besides those, in &lt;a href="https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.3.0/nrf/applications/nrf_desktop/README.html"&gt;the nRF Desktop sample application&lt;/a&gt;, there is a &lt;a href="https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.3.0/nrf/applications/nrf_desktop/doc/battery_meas.html"&gt;battery measurement module&lt;/a&gt;. It may or may not just make you more confused though, since it&amp;nbsp;does more things than what you are looking for.&lt;/p&gt;
&lt;p&gt;If you have some specific points you want to ask about, I can help you&amp;nbsp;with them.&lt;/p&gt;
&lt;p&gt;Hieu&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simple sample for measuring coin cell battery voltage with Zephyr and nRF52840</title><link>https://devzone.nordicsemi.com/thread/414503?ContentTypeID=1</link><pubDate>Thu, 09 Mar 2023 22:59:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6b84ea57-9917-4a9d-9197-d49461b2411a</guid><dc:creator>Hieu</dc:creator><description>&lt;p&gt;Hi Steve,&lt;/p&gt;
&lt;p&gt;I just want you to know that I have received your question; however, because we are a little understaffed due to&amp;nbsp;some&amp;nbsp;events, and I could not start with your question yet. I will try to get back to you with an answer within Friday (tomorrow).&lt;/p&gt;
&lt;p&gt;Hieu&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>